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