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