removed old unused files
[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                         }
842                         break;
843
844                 case irm_D:
845                         switch(to_mode)
846                         {
847                                 case irm_F:
848                                         return new_rd_ppc32_fRsp(env->dbg, env->irg, env->block, op, env->mode);
849                         }
850                         break;
851
852                 case irm_Is:
853                 case irm_Iu:
854                         switch(to_mode)
855                         {
856                                 case irm_Hs:
857                                         return new_rd_ppc32_Extsh(env->dbg, env->irg, env->block, op, env->mode);
858                                 case irm_Hu:
859                                         return own_gen_Andi_dot_lo16(env, op, 0xffff);
860                                 case irm_Bs:
861                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
862                                 case irm_Bu:
863                                         return own_gen_Andi_dot_lo16(env, op, 0xff);
864                                 case irm_Is:
865                                 case irm_Iu:
866                                         SKIP;
867                         }
868                         break;
869
870                 case irm_Hs:
871                 case irm_Hu:
872                         switch(to_mode)
873                         {
874                                 case irm_Iu:
875                                         if(from_mode==irm_Hu)
876                                 case irm_Hu:
877                                                 return own_gen_Andi_dot_lo16(env, op, 0xffff);
878                                 case irm_Is:
879                                         SKIP;
880                                 case irm_Bs:
881                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
882                                 case irm_Bu:
883                                         return own_gen_Andi_dot_lo16(env, op, 0xff);
884                                 case irm_Hs:
885                                         return new_rd_ppc32_Extsh(env->dbg, env->irg, env->block, op, env->mode);
886                         }
887                         break;
888
889                 case irm_Bs:
890                 case irm_Bu:
891                         switch(to_mode)
892                         {
893                                 case irm_Iu:
894                                 case irm_Hu:
895                                         if(from_mode==irm_Bs)
896                                 case irm_Bu:
897                                                 return own_gen_Andi_dot_lo16(env, op, 0xff);
898                                 case irm_Is:
899                                 case irm_Hs:
900                                         SKIP;
901                                 case irm_Bs:
902                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
903                         }
904                         break;
905                 case irm_P:
906                         if(to_mode==irm_Is || to_mode==irm_Iu) SKIP;
907                         break;
908         }
909
910         fprintf(stderr, "Mode for Conv not supported: %s -> %s\n",
911                 get_mode_name(get_irn_mode(get_irn_n(env->irn,0))),get_mode_name(env->mode));
912         assert(0);
913         return 0;
914 }
915
916 #undef SKIP
917
918
919 /**
920  * Transforms an Abs node.
921  *
922  * @param mod     the debug module
923  * @param block   the block the new node should belong to
924  * @param node    the ir Not node
925  * @param op      operator
926  * @param mode    node mode
927  * @return the ppc node generating the absolute value
928  */
929 static ir_node *gen_Abs(ppc32_transform_env_t *env, ir_node *op) {
930         int shift = 7;
931         switch(get_nice_modecode(env->mode))
932         {
933                 case irm_F:
934                 case irm_D:
935                         return new_rd_ppc32_fAbs(env->dbg, env->irg, env->block, op, env->mode);
936
937                 {
938                         ir_node *n1,*n2;
939                 case irm_Is:
940                         shift += 16;
941                 case irm_Hs:
942                         shift += 8;
943                 case irm_Bs: ;
944                         n1 = new_rd_ppc32_Srawi(env->dbg, env->irg, env->block, op, env->mode);
945                         set_ppc32_constant_tarval(n1, new_tarval_from_long(shift, mode_Is));
946                         set_ppc32_offset_mode(n1, ppc32_ao_None);
947                         n2 = new_rd_ppc32_Add(env->dbg, env->irg, env->block, op, n1, env->mode);
948                         return new_rd_ppc32_Xor(env->dbg, env->irg, env->block, n2, n1, env->mode);
949                 }
950         }
951         fprintf(stderr, "Mode for Abs not supported: %s\n", get_mode_name(env->mode));
952         assert(0);
953         return 0;
954 }
955
956 /**
957  * Transforms an Cond node.
958  *
959  * @param mod     the debug module
960  * @param block   the block the new node should belong to
961  * @param node    the ir Not node
962  * @param op      operator
963  * @param mode    node mode
964  * @return a ppc branch node
965  */
966 static ir_node *gen_Cond(ppc32_transform_env_t *env) {
967         ir_node *selector = get_Cond_selector(env->irn);
968         ir_mode *projmode = get_irn_mode(selector);
969         if(is_Proj(selector) && projmode==get_ppc32_mode_Cond())
970         {
971                 int projnum = get_Proj_proj(selector);
972                 ir_node *branch = new_rd_ppc32_Branch(env->dbg, env->irg, env->block, selector, env->mode);
973                 set_ppc32_proj_nr(branch, projnum);
974                 return branch;
975         }
976         else
977         {
978                 ir_node *unknown_gpr = new_rd_ppc32_Unknown(env->dbg, env->irg, env->block, mode_Is);
979                 ir_node *unknown_cond = new_rd_ppc32_cUnknown(env->dbg, env->irg, env->block, get_ppc32_mode_Cond());
980
981                 ir_node *switch_node = new_rd_ppc32_Switch(env->dbg, env->irg, env->block, selector,
982                         unknown_gpr, unknown_cond, env->mode);
983                 set_ppc32_proj_nr(switch_node, get_Cond_defaultProj(env->irn));
984
985                 return switch_node;
986         }
987
988 }
989
990 /**
991  * Transforms an Unknown node.
992  *
993  * @param mod     the debug module
994  * @param block   the block the new node should belong to
995  * @param node    the ir Not node
996  * @param op      operator
997  * @param mode    node mode
998  * @return a ppc Unknown node
999  */
1000 static ir_node *gen_Unknown(ppc32_transform_env_t *env) {
1001         if(mode_is_float(env->mode))
1002                 return new_rd_ppc32_fUnknown(env->dbg, env->irg, env->block, env->mode);
1003         else if (mode_is_int(env->mode))
1004                 return new_rd_ppc32_Unknown(env->dbg, env->irg, env->block, env->mode);
1005         else
1006         {
1007                 fprintf(stderr, "Mode %s for unknown value not supported.\n", get_mode_name(env->mode));
1008                 assert(0);
1009                 return 0;
1010         }
1011 }
1012
1013 static ir_node *ldst_insert_const(ir_node *ptr, tarval **ptv, ident **pid, ppc32_transform_env_t *env) {
1014         tarval *tv_const = NULL;
1015         ident *id_symconst = NULL;
1016
1017         if(is_ppc32_Const(ptr))
1018         {
1019                 tv_const = get_ppc32_constant_tarval(ptr);
1020                 ptr = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, mode_P, ppc32_ao_Ha16, tv_const, NULL);
1021         }
1022         else if(is_ppc32_SymConst(ptr))
1023         {
1024                 entity *ent = get_ppc32_frame_entity(ptr);
1025                 if(is_direct_entity(ent))
1026                 {
1027                         id_symconst = get_entity_ident(ent);
1028                         ptr = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, mode_P, ppc32_ao_Ha16, NULL, id_symconst);
1029                 }
1030         }
1031         *ptv = tv_const;
1032         *pid = id_symconst;
1033         return ptr;
1034 }
1035
1036 /**
1037  * Transforms a Load.
1038  *
1039  * @param mod     the debug module
1040  * @param block   the block the new node should belong to
1041  * @param node    the ir Load node
1042  * @param mode    node mode
1043  * @return the created ppc Load node
1044  */
1045 static ir_node *gen_Load(ppc32_transform_env_t *env) {
1046         ir_node *node = env->irn;
1047         ir_node *loadptr = get_Load_ptr(node);
1048         ir_node *load;
1049         ir_mode *mode = get_Load_mode(node);
1050         tarval *tv_const = NULL;
1051         ident *id_symconst = NULL;
1052
1053         loadptr = ldst_insert_const(loadptr, &tv_const, &id_symconst, env);
1054         switch(get_nice_modecode(mode)){
1055                 case irm_Bu:
1056                         load = new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1057                         break;
1058
1059                 case irm_Bs:
1060                 {
1061                         ir_node *proj_load, *extsb_node;
1062                         load =  new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1063                         proj_load = new_rd_Proj(env->dbg, env->irg, env->block, load, mode, pn_Load_res);
1064                         extsb_node = new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, proj_load, mode);
1065                         exchange(get_succ_Proj(env->irn, pn_Load_res), extsb_node);
1066                         break;
1067                 }
1068
1069
1070                 case irm_Hu:
1071                         load = new_rd_ppc32_Lhz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1072                         break;
1073                 case irm_Hs:
1074                         load =new_rd_ppc32_Lha(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1075                         break;
1076                 case irm_Is:
1077                 case irm_Iu:
1078                 case irm_P:
1079                         load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1080                         break;
1081
1082                 case irm_D:
1083                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1084                         break;
1085                 case irm_F:
1086                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node), env->mode);
1087                         break;
1088
1089                 default:
1090                         fprintf(stderr, "Mode for Load not supported: %s\n", get_mode_name(env->mode));
1091                         assert(0);
1092                         return 0;
1093         }
1094
1095         if(tv_const)
1096         {
1097                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1098                 set_ppc32_constant_tarval(load, tv_const);
1099         }
1100         else if(id_symconst)
1101         {
1102                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1103                 set_ppc32_symconst_ident(load, id_symconst);
1104         }
1105         return load;
1106 }
1107
1108
1109
1110 /**
1111  * Transforms a Store.
1112  *
1113  * @param mod     the debug module
1114  * @param block   the block the new node should belong to
1115  * @param node    the ir Store node
1116  * @param mode    node mode
1117  * @return the created ppc Store node
1118  */
1119 static ir_node *gen_Store(ppc32_transform_env_t *env) {
1120         ir_node *node = env->irn;
1121         ir_node *storeptr = get_Store_ptr(node);
1122         ir_node *valuenode = get_Store_value(node);
1123         ir_mode *mode = get_irn_mode(valuenode);
1124         ir_node *store;
1125         tarval *tv_const = NULL;
1126         ident *id_symconst = NULL;
1127
1128         storeptr = ldst_insert_const(storeptr, &tv_const, &id_symconst, env);
1129
1130         switch(get_nice_modecode(mode)){
1131                 case irm_Bu:
1132                 case irm_Bs:
1133                         store = new_rd_ppc32_Stb(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node), env->mode);
1134                         break;
1135
1136                 case irm_Hu:
1137                 case irm_Hs:
1138                         store = new_rd_ppc32_Sth(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node), env->mode);
1139                         break;
1140                 case irm_Is:
1141                 case irm_Iu:
1142                 case irm_P:
1143                         store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node), env->mode);
1144                         break;
1145
1146                 case irm_D:
1147                         store = new_rd_ppc32_Stfd(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node), env->mode);
1148                         break;
1149                 case irm_F:
1150                         store = new_rd_ppc32_Stfs(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node), env->mode);
1151                         break;
1152
1153                 default:
1154                         fprintf(stderr, "Mode for Store not supported: %s\n", get_mode_name(env->mode));
1155                         assert(0);
1156                         return 0;
1157         }
1158         if(tv_const)
1159         {
1160                 set_ppc32_offset_mode(store, ppc32_ao_Lo16);
1161                 set_ppc32_constant_tarval(store, tv_const);
1162         }
1163         else if(id_symconst)
1164         {
1165                 set_ppc32_offset_mode(store, ppc32_ao_Lo16);
1166                 set_ppc32_symconst_ident(store, id_symconst);
1167         }
1168         return store;
1169 }
1170
1171 /**
1172  * Transforms a CopyB.
1173  *
1174  * @param mod     the debug module
1175  * @param block   the block the new node should belong to
1176  * @param node    the ir Store node
1177  * @param mode    node mode
1178  * @return the created ppc CopyB node
1179  */
1180 static ir_node *gen_CopyB(ppc32_transform_env_t *env) {
1181         ir_node *mem = get_CopyB_mem(env->irn);
1182         ir_node *src = get_CopyB_src(env->irn);
1183         ir_node *dest = get_CopyB_dst(env->irn);
1184         ir_type *type = get_CopyB_type(env->irn);
1185         int size = get_type_size_bytes(type);
1186         int offset = 0;
1187
1188         ir_node *load, *store;
1189
1190         if(size/4>=1)
1191         {
1192                 ir_node *res;
1193                 tarval *offset0 = new_tarval_from_long(0, mode_Is);
1194                 tarval *offset4 = new_tarval_from_long(4, mode_Is);
1195
1196                 load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, src, mem, mode_T);
1197                 set_ppc32_constant_tarval(load, offset0);
1198                 set_ppc32_offset_mode(load, ppc32_ao_None);
1199                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1200                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1201
1202                 store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, dest, res, mem, mode_T);
1203                 set_ppc32_constant_tarval(store, offset0);
1204                 set_ppc32_offset_mode(store, ppc32_ao_None);
1205                 mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1206
1207                 if(size/4==2)
1208                 {
1209                         load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, src, mem, mode_T);
1210                         set_ppc32_constant_tarval(load, offset4);
1211                         set_ppc32_offset_mode(load, ppc32_ao_None);
1212                         mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1213                         res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1214
1215                         store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, dest, res, mem, mode_T);
1216                         set_ppc32_constant_tarval(store, offset4);
1217                         set_ppc32_offset_mode(store, ppc32_ao_None);
1218                         mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1219
1220                         offset = 8;
1221                 }
1222                 else
1223                 {
1224                         ir_node *ornode, *mtctrnode;
1225                         ir_node* in[3];
1226                         assert(size/4-1<=0xffff);
1227                         if(size/4-1<0x8000)
1228                         {
1229                                 ornode = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1230                                 set_ppc32_offset_mode(ornode, ppc32_ao_None);
1231                         }
1232                         else
1233                         {
1234                                 ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1235                                 set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1236                                 set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1237                                 ornode = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1238                                 set_ppc32_offset_mode(ornode, ppc32_ao_Lo16);
1239                         }
1240
1241                         set_ppc32_constant_tarval(ornode, new_tarval_from_long(size/4-1, mode_Is));
1242                         mtctrnode = new_rd_ppc32_Mtctr(env->dbg, env->irg, env->block, ornode, mode_Is);
1243                         store = new_rd_ppc32_LoopCopy(env->dbg, env->irg, env->block, src, dest, mtctrnode, mem, mode_T);
1244
1245                         in[0] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 1); // src
1246                         in[1] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 2); // dest
1247                         in[2] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 4); // temp
1248                         be_new_Keep(&ppc32_reg_classes[CLASS_ppc32_general_purpose], env->irg, env->block, 3, in);
1249                         in[0] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 3); // ctr
1250                         be_new_Keep(&ppc32_reg_classes[CLASS_ppc32_count], env->irg, env->block, 1, in);
1251
1252                         mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, 0);
1253
1254                         offset = 4;
1255                 }
1256         }
1257
1258         if((size & 2) == 2)
1259         {
1260                 ir_node *res;
1261                 tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
1262                 load = new_rd_ppc32_Lhz(env->dbg, env->irg, env->block, src, mem, mode_T);
1263                 set_ppc32_constant_tarval(load, offset_tarval);
1264                 set_ppc32_offset_mode(load, ppc32_ao_None);
1265                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1266                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1267
1268                 store = new_rd_ppc32_Sth(env->dbg, env->irg, env->block, dest, res, mem, mode_T);
1269                 set_ppc32_constant_tarval(store, offset_tarval);
1270                 set_ppc32_offset_mode(store, ppc32_ao_None);
1271                 mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1272
1273                 offset += 2;
1274         }
1275
1276         if((size & 1) == 1)
1277         {
1278                 ir_node *res;
1279                 tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
1280                 load = new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, src, mem, mode_T);
1281                 set_ppc32_constant_tarval(load, offset_tarval);
1282                 set_ppc32_offset_mode(load, ppc32_ao_None);
1283                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1284                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1285
1286                 store = new_rd_ppc32_Stb(env->dbg, env->irg, env->block, dest, res, mem, mode_T);
1287                 set_ppc32_constant_tarval(store, offset_tarval);
1288                 set_ppc32_offset_mode(store, ppc32_ao_None);
1289                 // mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1290         }
1291
1292         return store;
1293 }
1294
1295 /**
1296  * Transforms a FrameAddr into a ppc Add.
1297  */
1298 static ir_node *gen_FrameAddr(ppc32_transform_env_t *env) {
1299         ir_node *op = get_irn_n(env->irn, 0);
1300         ir_node *add = new_rd_ppc32_Addi(env->dbg, env->irg, env->block, op, mode_P);
1301         set_ppc32_frame_entity(add, be_get_frame_entity(env->irn));
1302         return add;
1303 }
1304
1305 /**
1306  * Transforms a StackParam into a ppc Load
1307  */
1308 static ir_node *gen_StackParam(ppc32_transform_env_t *env) {
1309         ir_node *load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, get_irn_n(env->irn, 0), new_NoMem(), mode_T);
1310         ir_node *proj = new_rd_Proj(env->dbg, env->irg, env->block, load, env->mode, pn_Load_res);
1311         set_ppc32_frame_entity(load, be_get_frame_entity(env->irn));
1312         return proj;
1313 }
1314
1315
1316 /*********************************************************
1317  *                  _             _      _
1318  *                 (_)           | |    (_)
1319  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1320  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1321  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1322  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1323  *
1324  *********************************************************/
1325
1326
1327
1328 /**
1329  * Transforms the given firm node (and maybe some other related nodes)
1330  * into one or more assembler nodes.
1331  *
1332  * @param node    the firm node
1333  * @param env     the debug module
1334  */
1335 void ppc32_transform_node(ir_node *node, void *env) {
1336         ppc32_code_gen_t *cgenv = (ppc32_code_gen_t *)env;
1337         opcode  code               = get_irn_opcode(node);
1338         ir_node *asm_node          = NULL;
1339         ppc32_transform_env_t tenv;
1340
1341         if (is_Block(node))
1342                 return;
1343
1344         tenv.block    = get_nodes_block(node);
1345         tenv.dbg      = get_irn_dbg_info(node);
1346         tenv.irg      = current_ir_graph;
1347         tenv.irn      = node;
1348         tenv.mod      = cgenv->mod;
1349         tenv.mode     = get_irn_mode(node);
1350
1351 #define UNOP(a)        case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
1352 #define BINOP(a)       case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
1353 #define GEN(a)         case iro_##a: asm_node = gen_##a(&tenv); break
1354 #define IGN(a)         case iro_##a: break
1355 #define BAD(a)         case iro_##a: goto bad
1356 #define OTHER_BIN(a)                                                       \
1357         if (get_irn_op(node) == get_op_##a()) {                                \
1358                 asm_node = gen_##a(&tenv, get_irn_n(node, 0), get_irn_n(node, 1)); \
1359                 break;                                                             \
1360         }
1361 #define BE_GEN(a)                  \
1362         if (be_is_##a(node)) {         \
1363                 asm_node = gen_##a(&tenv); \
1364                 break;                     \
1365         }
1366
1367         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1368
1369         switch (code) {
1370                 BINOP(Add);
1371                 BINOP(Mul);
1372                 BINOP(And);
1373                 BINOP(Or);
1374                 BINOP(Eor);
1375
1376                 BINOP(Sub);
1377                 BINOP(Shl);
1378                 BINOP(Shr);
1379                 BINOP(Shrs);
1380                 BINOP(Rot);
1381                 BINOP(Quot);
1382                 BINOP(Div);
1383                 BINOP(DivMod);
1384                 BINOP(Mod);
1385                 BINOP(Cmp);
1386
1387                 UNOP(Minus);
1388                 UNOP(Not);
1389                 UNOP(Conv);
1390                 UNOP(Abs);
1391
1392                 GEN(Load);
1393                 GEN(Store);
1394                 GEN(Cond);
1395                 GEN(Unknown);
1396                 GEN(CopyB);
1397
1398                 /* TODO: implement these nodes */
1399                 IGN(Mux);
1400
1401                 /* You probably don't need to handle the following nodes */
1402
1403                 IGN(Call);
1404                 IGN(Proj);
1405                 IGN(Alloc);
1406
1407                 IGN(Block);
1408                 IGN(Start);
1409                 IGN(End);
1410                 IGN(NoMem);
1411                 IGN(Phi);
1412                 IGN(IJmp);
1413                 IGN(Jmp);
1414                 IGN(Break);
1415                 IGN(Sync);
1416
1417                 BAD(Raise);
1418                 BAD(Sel);
1419                 BAD(InstOf);
1420                 BAD(Cast);
1421                 BAD(Free);
1422                 BAD(Tuple);
1423                 BAD(Id);
1424                 BAD(Bad);
1425                 BAD(Confirm);
1426                 BAD(Filter);
1427                 BAD(CallBegin);
1428                 BAD(EndReg);
1429                 BAD(EndExcept);
1430
1431                 default:
1432                         OTHER_BIN(Mulh);
1433                         BE_GEN(FrameAddr);
1434                         BE_GEN(StackParam);
1435                         if (get_irn_op(node) == get_op_Max() ||
1436                                 get_irn_op(node) == get_op_Min())
1437                         {
1438                                 /* TODO: implement */
1439                                 /* ignore for now  */
1440                         }
1441                         break;
1442 bad:
1443                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
1444                 assert(0);
1445         }
1446
1447         if (asm_node) {
1448                 exchange(node, asm_node);
1449                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1450         }
1451         else {
1452                 DB((tenv.mod, LEVEL_1, "ignored\n"));
1453         }
1454 }
1455
1456 /**
1457  * Constant generating code
1458  */
1459
1460 struct tv_ent {
1461         entity *ent;
1462         tarval *tv;
1463 };
1464
1465 /** Compares two (entity, tarval) combinations */
1466 static int cmp_tv_ent(const void *a, const void *b, size_t len) {
1467         const struct tv_ent *e1 = a;
1468         const struct tv_ent *e2 = b;
1469
1470         return !(e1->tv == e2->tv);
1471 }
1472
1473 /** Generates a SymConst node for a known FP const */
1474 static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_const) {
1475         static set    *const_set = NULL;
1476         static ir_type *tp = NULL;
1477         struct tv_ent  key;
1478         struct tv_ent *entry;
1479         ir_node       *cnst,*symcnst;
1480         ir_graph      *rem;
1481         entity        *ent;
1482
1483         if(!const_set)
1484                 const_set = new_set(cmp_tv_ent, 10);
1485         if(!tp)
1486                 tp = new_type_primitive(new_id_from_str("const_double_t"), env->mode);
1487
1488         key.tv  = known_const;
1489         key.ent = NULL;
1490
1491         entry = set_insert(const_set, &key, sizeof(key), HASH_PTR(key.tv));
1492
1493         if(!entry->ent) {
1494                 char buf[80];
1495                 sprintf(buf, "const_%i", get_irn_node_nr(env->irn));
1496                 ent = new_entity(get_glob_type(), new_id_from_str(buf), tp);
1497
1498                 set_entity_ld_ident(ent, get_entity_ident(ent));
1499                 set_entity_visibility(ent, visibility_local);
1500                 set_entity_variability(ent, variability_constant);
1501                 set_entity_allocation(ent, allocation_static);
1502
1503                 /* we create a new entity here: It's initialization must resist on the
1504                     const code irg */
1505                 rem = current_ir_graph;
1506                 current_ir_graph = get_const_code_irg();
1507                 cnst = new_Const(env->mode, key.tv);
1508                 current_ir_graph = rem;
1509
1510                 set_atomic_ent_value(ent, cnst);
1511
1512                 /* set the entry for hashmap */
1513                 entry->ent = ent;
1514         }                                                                          // TODO: Wird nicht richtig in global type gesteckt, ppc32_gen_decls.c findet ihn nicht
1515
1516         symcnst = new_rd_ppc32_SymConst(env->dbg, env->irg, env->block, env->mode);
1517         set_ppc32_frame_entity(symcnst, ent);
1518         return symcnst;
1519 }
1520
1521 static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env);
1522
1523 /**
1524  * Transforms a Const.
1525  *
1526  * @param mod     the debug module
1527  * @param block   the block the new node should belong to
1528  * @param node    the ir Const node
1529  * @param mode    node mode
1530  * @return the created ppc Load immediate node
1531  */
1532 static ir_node *gen_ppc32_Const(ppc32_transform_env_t *env) {
1533         tarval *tv_const = get_ppc32_constant_tarval(env->irn);
1534         ir_node *node;
1535
1536         switch(get_nice_modecode(env->mode)){
1537                 case irm_Hu:
1538                 {
1539                         unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
1540                         if(val1&0x80)
1541                         {
1542                                 ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1543                                 set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1544                                 set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1545                                 node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1546                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1547                                 break;
1548                         }
1549                 }
1550                 case irm_Bu:
1551                 case irm_Bs:
1552                 case irm_Hs:
1553                         node = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, env->mode);
1554                         set_ppc32_offset_mode(node, ppc32_ao_None);
1555                         break;
1556                 case irm_Is:
1557                 case irm_Iu:
1558                 case irm_P:
1559                 {
1560                         unsigned char val2 = get_tarval_sub_bits(tv_const,2);
1561                         unsigned char val3 = get_tarval_sub_bits(tv_const,3);
1562                         if(!val2 && !val3)
1563                         {
1564                                 unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
1565                                 if(val1&0x80)
1566                                 {
1567                                         ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1568                                         set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1569                                         set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1570                                         node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1571                                         set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1572                                 }
1573                                 else
1574                                 {
1575                                         node = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, env->mode);
1576                                         set_ppc32_offset_mode(node, ppc32_ao_None);
1577                                 }
1578                         }
1579                         else
1580                         {
1581                                 unsigned char val0 = get_tarval_sub_bits(tv_const,0);
1582                                 unsigned char val1 = get_tarval_sub_bits(tv_const,1);
1583                                 node = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Hi16, tv_const, NULL);
1584                                 if(val0 || val1)
1585                                 {
1586                                         set_ppc32_constant_tarval(node, tv_const);
1587                                         node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, node, env->mode);
1588                                         set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1589                                 }
1590                         }
1591                         break;
1592                 }
1593
1594                 default:
1595                         fprintf(stderr, "Mode for Const not supported: %s\n", get_mode_name(env->mode));
1596                         assert(0);
1597                         return 0;
1598         }
1599         set_ppc32_constant_tarval(node, tv_const);
1600         return node;
1601 }
1602
1603 /**
1604  * Transforms a fConst.
1605  *
1606  * @param mod     the debug module
1607  * @param block   the block the new node should belong to
1608  * @param node    the ir Const node
1609  * @param mode    node mode
1610  * @return the created ppc float Load node
1611  */
1612 static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env) {
1613         tarval *tv_const = get_ppc32_constant_tarval(env->irn);
1614
1615         switch(get_nice_modecode(env->mode)){
1616                 case irm_D:
1617                 case irm_F:
1618                 {
1619                         ir_node *addr, *load;
1620                         ir_mode *mode = env->mode;
1621                         entity *ent;
1622                         env->irn = gen_fp_known_symconst(env, tv_const);
1623                         env->mode = mode_P;
1624                         ent = get_ppc32_frame_entity(env->irn);
1625                         if(is_direct_entity(ent))
1626                         {
1627                                 ident *id_symconst = get_entity_ident(ent);
1628                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
1629
1630                                 if(mode==mode_D)
1631                                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, node_addis, new_NoMem(), mode_T);
1632                                 else // mode_F
1633                                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, node_addis, new_NoMem(), mode_T);
1634
1635                                 set_ppc32_symconst_ident(load, id_symconst);
1636                                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1637                         }
1638                         else
1639                         {
1640                                 addr = gen_ppc32_SymConst (env);
1641                                 if(mode==mode_D)
1642                                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, addr, new_NoMem(), mode_T);
1643                                 else // mode_F
1644                                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, addr, new_NoMem(), mode_T);
1645                         }
1646                         return new_rd_Proj(env->dbg, env->irg, env->block, load, mode, pn_Load_res);
1647                 }
1648
1649                 default:
1650                         fprintf(stderr, "Mode for fConst not supported: %s\n", get_mode_name(env->mode));
1651                         assert(0);
1652                         return 0;
1653         }
1654         assert(0 && "Dead end!");
1655 }
1656
1657
1658 /**
1659  * Returns true, if the entity can be accessed directly,
1660  * or false, if the address must be loaded first
1661  */
1662 int is_direct_entity(entity *ent) {
1663         return get_entity_visibility(ent)!=visibility_external_allocated;
1664 /*      visibility vis = get_entity_visibility(ent);
1665         if(is_Method_type(get_entity_type(ent)))
1666         {
1667                 return (vis!=visibility_external_allocated);
1668         }
1669         else
1670         {
1671                 return (vis==visibility_local);
1672         }*/
1673 }
1674
1675 /**
1676  * Transforms a SymConst.
1677  *
1678  * @param mod     the debug module
1679  * @param block   the block the new node should belong to
1680  * @param node    the ir Const node
1681  * @param mode    node mode
1682  * @return the created ppc Load immediate node
1683  */
1684 static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env) {
1685         entity *ent = get_ppc32_frame_entity(env->irn);
1686         ident *id_symconst = get_entity_ident(ent);
1687         ir_node *node;
1688         switch(get_nice_modecode(env->mode)){
1689                 case irm_P:
1690                 {
1691                         if (is_direct_entity(ent))
1692                         {
1693                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Hi16, NULL, id_symconst);
1694                                 node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, node_addis, env->mode);
1695                                 set_ppc32_symconst_ident(node, id_symconst);
1696                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1697                         }
1698                         else
1699                         {
1700                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
1701                                 node = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, node_addis, new_NoMem(), mode_T);
1702                                 set_ppc32_symconst_ident(node, id_symconst);
1703                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1704                                 node = new_rd_Proj(env->dbg, env->irg, env->block, node, env->mode, pn_Load_res);
1705 //                              pset_insert_ptr(symbol_pset, ent);
1706                         }
1707                         break;
1708                 }
1709
1710                 default:
1711                         fprintf(stderr, "Mode for SymConst not supported: %s\n", get_mode_name(env->mode));
1712                         assert(0);
1713                         return 0;
1714         }
1715         return node;
1716 }
1717
1718 /**
1719  * Transforms the given firm node (and maybe some other related nodes)
1720  * into one or more assembler nodes.
1721  *
1722  * @param node    the firm node
1723  * @param env     the debug module
1724  */
1725 void ppc32_transform_const(ir_node *node, void *env) {
1726         ppc32_code_gen_t *cgenv = (ppc32_code_gen_t *)env;
1727         opcode  code               = get_irn_opcode(node);
1728         ir_node *asm_node          = NULL;
1729         ppc32_transform_env_t tenv;
1730
1731         if (is_Block(node))
1732                 return;
1733
1734         tenv.block    = get_nodes_block(node);
1735         tenv.dbg      = get_irn_dbg_info(node);
1736         tenv.irg      = current_ir_graph;
1737         tenv.irn      = node;
1738         tenv.mod      = cgenv->mod;
1739         tenv.mode     = get_irn_mode(node);
1740
1741 #define OTHER_GEN(a)                                                       \
1742         if (get_irn_op(node) == get_op_##a()) {                                \
1743                 asm_node = gen_##a(&tenv);                                         \
1744         }
1745
1746         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1747
1748         OTHER_GEN(ppc32_Const)
1749         else OTHER_GEN(ppc32_fConst)
1750         else OTHER_GEN(ppc32_SymConst)
1751
1752         if (asm_node) {
1753                 exchange(node, asm_node);
1754                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1755         }
1756         else {
1757                 DB((tenv.mod, LEVEL_1, "ignored\n"));
1758         }
1759 }