Fixed name mangling for private entities
[libfirm] / ir / be / ppc32 / ppc32_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3
4 # the cpu architecture (ia32, ia64, mips, sparc, ppc32, ...)
5
6 $arch = "ppc32";
7
8 # register types:
9 #   0 - no special type
10 #   1 - caller save (register must be saved by the caller of a function)
11 #   2 - callee save (register must be saved by the called function)
12 #   4 - ignore (do not assign this register)
13 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
14 %reg_classes = (
15         gp => [
16                 { name => "r0", type => 1 },
17                 { name => "r2", type => 1 },
18                 { name => "r3", type => 1 },
19                 { name => "r4", type => 1 },
20                 { name => "r5", type => 1 },
21                 { name => "r6", type => 1 },
22                 { name => "r7", type => 1 },
23                 { name => "r8", type => 1 },
24                 { name => "r9", type => 1 },
25                 { name => "r10", type => 1 },
26 #               { name => "r11", type => 1 },
27 #               { name => "r12", type => 1 },
28                 { name => "r13", type => 2 },
29                 { name => "r14", type => 2 },
30                 { name => "r15", type => 2 },
31 #               { name => "r16", type => 2 },
32 #               { name => "r17", type => 2 },
33 #               { name => "r18", type => 2 },
34 #               { name => "r19", type => 2 },
35 #               { name => "r20", type => 2 },
36 #               { name => "r21", type => 2 },
37 #               { name => "r22", type => 2 },
38 #               { name => "r23", type => 2 },
39 #               { name => "r24", type => 2 },
40 #               { name => "r25", type => 2 },
41 #               { name => "r26", type => 2 },
42 #               { name => "r27", type => 2 },
43 #               { name => "r28", type => 2 },
44 #               { name => "r29", type => 2 },
45 #               { name => "r30", type => 2 },
46                 { name => "r31", type => 2 },
47                 { name => "r1", type => 6 }, # this is our stackpointer
48                 { "mode" => "mode_P" }
49         ],
50         fp => [
51 #               { name => "f0", type => 1 }, # => reserved for FP Perm
52                 { name => "f1", type => 1 },
53                 { name => "f2", type => 1 },
54                 { name => "f3", type => 1 },
55                 { name => "f4", type => 1 },
56                 { name => "f5", type => 1 },
57                 { name => "f6", type => 1 },
58                 { name => "f7", type => 1 },
59                 { name => "f8", type => 1 },
60                 { name => "f9", type => 1 },
61                 { name => "f10", type => 1 },
62                 { name => "f11", type => 1 },
63                 { name => "f12", type => 1 },
64                 { name => "f13", type => 1 },
65                 { name => "f14", type => 2 },
66                 { name => "f15", type => 2 },
67                 { name => "f16", type => 2 },
68 #               { name => "f17", type => 2 },
69 #               { name => "f18", type => 2 },
70 #               { name => "f19", type => 2 },
71 #               { name => "f20", type => 2 },
72 #               { name => "f21", type => 2 },
73 #               { name => "f22", type => 2 },
74 #               { name => "f23", type => 2 },
75 #               { name => "f24", type => 2 },
76 #               { name => "f25", type => 2 },
77 #               { name => "f26", type => 2 },
78 #               { name => "f27", type => 2 },
79 #               { name => "f28", type => 2 },
80 #               { name => "f29", type => 2 },
81 #               { name => "f30", type => 2 },
82 #               { name => "f31", type => 2 },
83                 { mode => "mode_D" }
84         ],
85         condition => [
86                 { name => "cr0", type => 1 },
87                 { name => "cr1", type => 1 },
88                 { name => "cr2", type => 2 },
89                 { name => "cr3", type => 2 },
90                 { name => "cr4", type => 2 },
91                 { name => "cr5", type => 1 },
92                 { name => "cr6", type => 1 },
93 #               { name => "cr7", type => 1 }, # => reserved for Condition Perm
94                 { mode => "mode_P" } # real mode is 4 bit, but doesn't matter ...
95         ],
96         link => [
97                 { name => "lr", type => 4 }, # 3
98                 { mode => "mode_P" }
99         ],
100         count => [
101                 { name => "ctr", type => 1 },
102                 { mode => "mode_P" }
103         ]
104 ); # %reg_classes
105
106 %emit_templates = (
107         S0 => "${arch}_emit_source_register(node, 0);",
108         S1 => "${arch}_emit_source_register(node, 1);",
109         S2 => "${arch}_emit_source_register(node, 2);",
110         D0 => "${arch}_emit_dest_register(node, 0);",
111         D1 => "${arch}_emit_dest_register(node, 1);",
112         D2 => "${arch}_emit_dest_register(node, 2);",
113         O  => "${arch}_emit_offset(node);",
114         C  => "${arch}_emit_immediate(node);",
115         RLWIMI => "${arch}_emit_rlwimi_helper(node);",
116 );
117
118 $default_cmp_attr = "NULL";
119
120 #--------------------------------------------------#
121 #                        _                         #
122 #                       (_)                        #
123 #  _ __   _____      __  _ _ __    ___  _ __  ___  #
124 # | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
125 # | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
126 # |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
127 #                                      | |         #
128 #                                      |_|         #
129 #--------------------------------------------------#
130
131 %nodes = (
132
133 #-----------------------------------------------------------------#
134 #  _       _                                         _            #
135 # (_)     | |                                       | |           #
136 #  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
137 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
138 # | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
139 # |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
140 #                   __/ |                                         #
141 #                  |___/                                          #
142 #-----------------------------------------------------------------#
143
144 # commutative operations
145
146 Add => {
147         op_flags  => "C",
148         irn_flags => "R",
149         comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
150         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
151         emit      => '. add     %D0, %S0, %S1',
152 },
153
154 Addi => {
155         irn_flags => "R",
156         comment   => "construct Add: Addi(a, const) = Addi(const, a) = a + const",
157         reg_req   => { in => [ "!r0" ], out => [ "gp" ] },
158 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
159         emit      => '. addi    %D0, %S0, %C',
160         cmp_attr  =>
161 '
162         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
163 ',
164 },
165
166 Mullw => {
167         op_flags  => "C",
168         irn_flags => "R",
169         comment   => "construct Mul: Mullw(a, b) = Mullw(b, a) = lo32(a * b)",
170         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
171         emit      => '. mullw   %D0, %S0, %S1',
172 },
173
174 Mulhw => {
175         op_flags  => "C",
176         irn_flags => "R",
177         comment   => "construct Mul: Mulhw(a, b) = Mulhw(b, a) = hi32(a * b)",
178         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
179         emit      => '. mulhw   %D0, %S0, %S1',
180 },
181
182 Mulhwu => {
183         op_flags  => "C",
184         irn_flags => "R",
185         comment   => "construct Mul: Mulhwu(a, b) = Mulhwu(b, a) = hi32(a * b)",
186         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
187         emit      => '. mulhwu  %D0, %S0, %S1',
188 },
189
190 #Mul_i => {
191 #  irn_flags => "R",
192 #  comment   => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
193 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
194 #  emit      => '. mul %S0, %C, %D0',
195 #},
196
197 And => {
198         op_flags  => "C",
199         irn_flags => "R",
200         comment   => "construct And: And(a, b) = And(b, a) = a AND b",
201         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
202         emit      => '. and     %D0, %S0, %S1',
203 },
204
205 #And_i => {
206 #  irn_flags => "R",
207 #  comment   => "construct And: And(a, const) = And(const, a) = a AND const",
208 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
209 #  emit      => '. and %S0, %C, %D0',
210 #},
211
212 Or => {
213         op_flags  => "C",
214         irn_flags => "R",
215         comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
216         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
217         emit      => '. or      %D0, %S0, %S1',
218 },
219
220 #Or_i => {
221 #  op_flags  => "C",
222 #  irn_flags => "R",
223 #  comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
224 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
225 #  emit      => '. or %S0, %C, %D0',
226 #},
227
228 Xor => {
229         op_flags  => "C",
230         irn_flags => "R",
231         comment   => "construct Xor: Xor(a, b) = Xor(b, a) = a XOR b",
232         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
233         emit      => '. xor     %D0, %S0, %S1',
234 },
235
236 #Xor_i => {
237 #  irn_flags => "R",
238 #  comment   => "construct Xor: Xor(a, const) = Xor(const, a) = a EOR const",
239 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
240 #  emit      => '. xor %S0, %C, %D0',
241 #},
242
243 # not commutative operations
244
245 Sub => {
246         irn_flags => "R",
247         comment   => "construct Sub: Sub(a, b) = a - b",
248         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
249         emit      => '. sub %D0, %S0, %S1',
250 },
251
252 #Sub_i => {
253 #  irn_flags => "R",
254 #  comment   => "construct Sub: Sub(a, const) = a - const",
255 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
256 #  emit      => '. subl %S0, %C, %D0',
257 #},
258
259 Slw => {
260         irn_flags => "R",
261         comment   => "construct Shl: Shl(a, b) = a << b",
262         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
263         emit      => '. slw %D0, %S0, %S1',
264 },
265
266 #Shl_i => {
267 #  irn_flags => "R",
268 #  comment   => "construct Shl: Shl(a, const) = a << const",
269 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
270 #  emit      => '. shl %S0, %C, %D0',
271 #},
272
273 Srw => {
274         irn_flags => "R",
275         comment   => "construct Shr: Srw(a, b): c = a >> b",
276         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
277         emit      => '. srw     %D0, %S0, %S1',
278 },
279
280 #Shr_i => {
281 #  irn_flags => "R",
282 #  comment   => "construct Shr: Shr(a, const) = a >> const",
283 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
284 #  emit      => '. shr %S0, %C, %D0',
285 #},
286
287 Sraw => {
288         irn_flags => "R",
289         comment   => "construct Shrs: Sraw(a, b): c = a >> b",
290         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
291         emit      => '. sraw %D0, %S0, %S1',
292 },
293
294 Srawi => {
295         irn_flags => "R",
296         comment   => "construct Shrs: Srawi(a, const): c = a >> const",
297         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
298         emit      => '. sraw %D0, %S0, %C',
299         cmp_attr  =>
300 '
301         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
302 ',
303
304 },
305
306 Rlwnm => {
307         irn_flags => "R",
308         comment   => "construct ???: Rlwnm(a, b): c = a ROTL b",
309         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
310         emit      => '. rlwnm %D0, %S0, %S1',
311 },
312
313 Rlwinm => {
314         irn_flags => "R",
315         comment   => "construct ???: Rlwinm(a, b_const, c_const, d_const): (m = MASK(c, d)) e = (a ROTL b) & m",
316         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
317         emit      => '. rlwinm %D0, %S0, %RLWIMI',
318         cmp_attr  =>
319 '
320         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
321 ',
322 },
323
324 Neg => {
325         irn_flags => "R",
326         comment   => "construct Minus: Neg(a) = -a",
327         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
328         emit      => '. neg %D0, %S0',
329 },
330
331 Not => {
332         irn_flags => "R",
333         comment   => "construct Not: Not(a) = !a",
334         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
335         emit      => '. nor %D0, %S0, %S0',
336 },
337
338 Extsb => {
339         irn_flags => "R",
340         comment   => "construct Sign extension of byte: Extsb(char a) = (int) a",
341         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
342         emit      => '. extsb %D0, %S0',
343 },
344
345 Extsh => {
346         irn_flags => "R",
347         comment   => "construct Sign extension of halfword: Extsh(char a) = (short) a",
348         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
349         emit      => '. extsh %D0, %S0',
350 },
351
352 Divw => {
353         irn_flags => "R",
354         comment   => "construct Div (signed): Div(a, b) = a div b",
355         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
356         emit      => '. divw %D0, %S0, %S1',
357 },
358
359 Divwu => {
360         irn_flags => "R",
361         comment   => "construct Div (unsigned): Div(a, b) = a div b",
362         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
363         emit      => '. divwu %D0, %S0, %S1',
364 },
365
366 Mtctr => {
367         irn_flags => "R",
368         comment   => "construct Mtctr: Ctr = a",
369         reg_req   => { in => [ "gp" ], out => [ "count" ] },
370         emit      => '. mtctr %S0',
371 },
372
373
374 # other operations
375
376 Const => {
377         op_flags  => "c",
378         irn_flags => "R",
379         comment   => "Const (high-level node)",
380         reg_req   => { out => [ "gp" ] },
381         cmp_attr  =>
382 '
383         return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
384 ',
385 },
386
387 fConst => {
388         op_flags  => "c",
389         irn_flags => "R",
390         comment   => "float Const (high-level node)",
391         reg_req   => { out => [ "fp" ] },
392         cmp_attr  =>
393 '
394         return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
395 ',
396 },
397
398 SymConst => {
399         op_flags  => "c",
400         irn_flags => "R",
401         comment   => "SymConst (high-level node)",
402         reg_req   => { out => [ "gp" ] },
403         cmp_attr  =>
404 '
405         return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
406 ',
407 },
408
409 Unknown => {
410         op_flags  => "c",
411         irn_flags => "R",
412         comment   => "construct unknown register",
413         reg_req   => { out => [ "gp" ] },
414         emit      => '. \t\t /* use %D0 as uninitialized value */',
415         cmp_attr  =>
416 '
417         return 1;
418 ',
419 },
420
421 fUnknown => {
422         op_flags  => "c",
423         irn_flags => "R",
424         comment   => "construct unknown float register",
425         reg_req   => { out => [ "fp" ] },
426         emit      => '. \t\t /* use %D0 as uninitialized value */',
427         cmp_attr  =>
428 '
429         return 1;
430 ',
431 },
432
433 cUnknown => {
434         op_flags  => "c",
435         irn_flags => "R",
436         comment   => "construct unknown condition register",
437         reg_req   => { out => [ "condition" ] },
438         emit      => '. \t\t /* use %D0 as uninitialized value */',
439         cmp_attr  =>
440 '
441         return 1;
442 ',
443 },
444
445 Addi_zero => {
446         op_flags  => "c",
447         irn_flags => "R",
448         comment   => "load constant (16bit with sign extension)",
449         reg_req   => { out => [ "gp" ] },
450         emit      => '. addi    %D0, 0, %C',
451         cmp_attr  =>
452 '
453         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
454 ',
455 },
456
457 Branch => {
458         op_flags  => "L|X|Y",
459         comment   => "branch somewhere",
460         reg_req   => { in => [ "condition" ], out => [ "none", "none" ] },
461         cmp_attr  =>
462 '
463         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
464 ',
465 },
466
467 LoopCopy => {
468         irn_flags => "R",
469         comment   => "construct LoopCopy(src, dest, count, mem): Copy count words from src to dest",
470         reg_req   => { in => [ "gp", "gp", "count", "none" ], out => [ "none", "in_r1", "in_r2", "in_r3", "gp" ] },
471 },
472
473 Switch => {
474         op_flags => "L|X|Y",
475         comment   => "construct Switch(selector): Jump to whatever",
476         reg_req   => { in => [ "gp", "gp", "condition" ], out => [ "none" ] },
477         cmp_attr  =>
478 '
479         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
480 ',
481 },
482
483 Addis_zero => {
484         op_flags  => "c",
485         irn_flags => "R",
486         comment   => "load the constant to higher 16 bit of register",
487         reg_req   => { out => [ "gp" ] },
488         emit      => '. addis %D0, 0, %C',
489         "attr"      => "ppc32_attr_offset_mode om, tarval *tv, ident *id",
490         "init_attr" =>
491 '
492         attr->offset_mode = om;
493         if (tv) {
494                 attr->content_type = ppc32_ac_Const;
495                 attr->data.constant_tarval = tv;
496         }
497         else if (id) {
498                 attr->content_type = ppc32_ac_SymConst;
499                 attr->data.symconst_ident = id;
500         }
501 ',
502         cmp_attr  =>
503 '
504         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
505 ',
506 },
507
508 Ori => {
509         irn_flags => "R",
510         comment   => "ors constant with register",
511         reg_req   => { in => [ "gp"], out => [ "gp" ] },
512         emit      => '. ori %D0, %S0, %C',
513         cmp_attr  =>
514 '
515         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
516 ',
517 },
518
519 Andi_dot => {
520         irn_flags => "R",
521         comment   => "ands constant with register with cr0 update",
522         reg_req   => { in => [ "gp"], out => [ "gp", "cr0" ] },
523         emit      => '. andi. %D0, %S0,%C',
524         cmp_attr  =>
525 '
526         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
527 ',
528 },
529
530 Cmp => {
531         irn_flags => "R",
532         comment   => "construct Cmp: Cmp(a, b) = Flags in crX",
533         reg_req   => { in => [ "gp", "gp" ], out => [ "condition" ] },
534         emit      => '. cmp %D0, 0, %S0, %S1',
535 },
536
537 Cmpi => {
538         irn_flags => "R",
539         comment   => "construct Cmp immediate: Cmpi(a, const) = Flags in crX",
540         reg_req   => { in => [ "gp" ], out => [ "condition" ] },
541         emit      => '. cmpi %D0, 0, %S0, %C',
542         cmp_attr  =>
543 '
544         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
545 ',
546 },
547
548 Cmpl => {
549         irn_flags => "R",
550         comment   => "construct Cmp logical: Cmpl(a, b) = Flags in crX",
551         reg_req   => { in => [ "gp", "gp" ], out => [ "condition" ] },
552         emit      => '. cmpl %D0, 0, %S0, %S1',
553 },
554
555 Cmpli => {
556         irn_flags => "R",
557         comment   => "construct Cmp logical immediate: Cmpli(a, const) = Flags in crX",
558         reg_req   => { in => [ "gp" ], out => [ "condition" ] },
559         emit      => '. cmpli %D0, 0, %S0, %C',
560         cmp_attr  =>
561 '
562         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
563 ',
564 },
565
566
567 # Load / Store
568
569 Lbz => {
570         op_flags  => "L|F",
571         irn_flags => "R",
572         state     => "exc_pinned",
573         comment   => "construct Load (byte unsigned): Load(ptr, mem) = LD ptr -> reg",
574         reg_req   => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
575         emit      => '. lbz %D0, %O(%S0)',
576         cmp_attr  =>
577 '
578         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
579 ',
580         outs      => [ "res", "M" ],
581 },
582
583 Lhz => {
584         op_flags  => "L|F",
585         irn_flags => "R",
586         state     => "exc_pinned",
587         comment   => "construct Load (halfword unsigned): Load(ptr, mem) = LD ptr -> reg",
588         reg_req   => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
589         emit      => '. lhz %D0, %O(%S0)',
590         cmp_attr  =>
591 '
592         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
593 ',
594         outs      => [ "res", "M" ],
595 },
596
597 Lha => {
598         op_flags  => "L|F",
599         irn_flags => "R",
600         state     => "exc_pinned",
601         comment   => "construct Load (halfword signed): Load(ptr, mem) = LD ptr -> reg",
602         reg_req   => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
603         emit      => '. lha %D0, %O(%S0)',
604         cmp_attr  =>
605 '
606         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
607 ',
608         outs      => [ "res", "M" ],
609 },
610
611 Lwz => {
612         op_flags  => "L|F",
613         irn_flags => "R",
614         state     => "exc_pinned",
615         comment   => "construct Load (word): Load(ptr, mem) = LD ptr -> reg",
616         reg_req   => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
617         emit      => '. lwz %D0, %O(%S0)',
618         cmp_attr  =>
619 '
620         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
621 ',
622         outs      => [ "res", "M" ],
623 },
624
625 Lwzu => {
626         op_flags  => "L|F",
627         irn_flags => "R",
628         state     => "exc_pinned",
629         comment   => "construct Load with update (word): Load(ptr, mem) = LD ptr -> reg",
630         reg_req   => { in => [ "!r0", "none" ], out => [ "gp", "in_r1", "none"] },
631         emit      => '. lwzu %D0, %O(%S0)',
632         cmp_attr  =>
633 '
634         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
635 ',
636         outs      => [ "res", "ptr", "M" ],
637 },
638
639 Stb => {
640         op_flags  => "L|F",
641         state     => "exc_pinned",
642         comment   => "construct Store: Store (byte) (ptr, val, mem) = ST ptr,val",
643         reg_req   => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
644         emit      => '. stb %S1, %O(%S0)',
645         cmp_attr  =>
646 '
647         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
648 ',
649         outs      => [ "M" ],
650 },
651
652 Sth => {
653         op_flags  => "L|F",
654         state     => "exc_pinned",
655         comment   => "construct Store: Store (halfword) (ptr, val, mem) = ST ptr,val",
656         reg_req   => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
657         emit      => '. sth %S1, %O(%S0)',
658         cmp_attr  =>
659 '
660         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
661 ',
662         outs      => [ "M" ],
663 },
664
665 Stw => {
666         op_flags  => "L|F",
667         state     => "exc_pinned",
668         comment   => "construct Store: Store (word) (ptr, val, mem) = ST ptr,val",
669         reg_req   => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
670         emit      => '. stw %S1, %O(%S0)',
671         cmp_attr  =>
672 '
673         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
674 ',
675         outs      => [ "M" ],
676 },
677
678 #--------------------------------------------------------#
679 #    __ _             _                     _            #
680 #   / _| |           | |                   | |           #
681 #  | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
682 #  |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
683 #  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
684 #  |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
685 #--------------------------------------------------------#
686
687 # commutative operations
688
689 fAdd => {
690         op_flags  => "C",
691         irn_flags => "R",
692         comment   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
693         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
694         emit      => '. fadd %D0, %S0, %S1',
695 },
696
697 fAdds => {
698         op_flags  => "C",
699         irn_flags => "R",
700         comment   => "construct FP Add (single): Add(a, b) = Add(b, a) = a + b",
701         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
702         emit      => '. fadds %D0, %S0, %S1',
703 },
704
705 fMul => {
706         op_flags  => "C",
707         comment   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
708         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
709         emit      => '. fmul %D0, %S0, %S1',
710 },
711
712 fMuls => {
713         op_flags  => "C",
714         comment   => "construct FP Mul (single): Mul(a, b) = Mul(b, a) = a * b",
715         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
716         emit      => '. fmuls %D0, %S0, %S1',
717 },
718
719 fNeg => {
720         comment   => "construct FP Negation: fNeg(a) = -a",
721         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
722         emit      => '. fneg %D0, %S0',
723 },
724
725 fMax => {
726         op_flags  => "C",
727         irn_flags => "R",
728         comment   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
729         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
730         emit      => '. fmax %S0, %S1, %D0',
731 },
732
733 fMin => {
734         op_flags  => "C",
735         irn_flags => "R",
736         comment   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
737         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
738         emit      => '. fmin %S0, %S1, %D0',
739 },
740
741 # not commutative operations
742
743 fSub => {
744         irn_flags => "R",
745         comment   => "construct FP Sub: Sub(a, b) = a - b",
746         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
747         emit      => '. fsub %D0, %S0, %S1',
748 },
749
750 fSubs => {
751         irn_flags => "R",
752         comment   => "construct FP Sub (single): Sub(a, b) = a - b",
753         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
754         emit      => '. fsubs %D0, %S0, %S1',
755 },
756
757 fDiv => {
758         comment   => "construct FP Div: Div(a, b) = a / b",
759         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
760         emit      => '. fdiv %D0, %S0, %S1',
761 },
762
763 fDivs => {
764         comment   => "construct FP Div (single): Div(a, b) = a / b",
765         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
766         emit      => '. fdivs %D0, %S0, %S1',
767 },
768
769 fMinus => {
770         irn_flags => "R",
771         comment   => "construct FP Minus: fMinus(a) = -a",
772         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
773         emit      => '. fneg %D0, %S0',
774 },
775
776 fCtiw => {
777         irn_flags => "R",
778         comment   => "construct FP Convert to integer word: fCtiw(a) = (int) a",
779         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
780         emit      => '. fctiw %D0, %S0',
781 },
782
783 fRsp => {
784         irn_flags => "R",
785         comment   => "construct FP Round to single: fRsp(a) = (float) a",
786         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
787         emit      => '. frsp %D0, %S0',
788 },
789
790 fAbs => {
791         irn_flags => "R",
792         comment   => "construct FP Abs: fAbs(a) = |a|",
793         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
794         emit      => '. fabs %D0, %S0',
795 },
796
797 fCmpu => {
798         irn_flags => "R",
799         comment   => "construct FP Cmp unordered: fCmpu(a, b) = a ? b",
800         reg_req   => { in => [ "fp", "fp" ], out => [ "condition" ] },
801         emit      => '. fcmpu %D0, %S0, %S1',
802 },
803
804 # other operations
805
806 #fConst => {
807 #       op_flags  => "c",
808 #       irn_flags => "R",
809 #       comment   => "represents a FP constant",
810 #       reg_req   => { out => [ "fp" ] },
811 #       emit      => '. fmov %C, %D0',
812 #       cmp_attr  =>
813 #'
814 #       /* TODO: compare fConst attributes */
815 #       return 1;
816 #',
817 #},
818
819 fUnknown => {
820         op_flags  => "c",
821         irn_flags => "R",
822         comment   => "construct unknown floating point register",
823         reg_req   => { out => [ "fp" ] },
824         emit      => '. \t\t /* use %D0 as uninitialized value */',
825         cmp_attr  =>
826 '
827         return 1;
828 ',
829 },
830
831 # Load / Store
832
833 Lfd => {
834         op_flags  => "L|F",
835         irn_flags => "R",
836         state     => "exc_pinned",
837         comment   => "construct FP Load (double): Load(ptr, mem) = LD ptr",
838         reg_req   => { in => [ "!r0", "none" ], out => [ "fp", "none" ] },
839         emit      => '. lfd %D0, %O(%S0)',
840         cmp_attr  =>
841 '
842         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
843 ',
844         outs      => [ "res", "M" ],
845 },
846
847 Lfs => {
848         op_flags  => "L|F",
849         irn_flags => "R",
850         state     => "exc_pinned",
851         comment   => "construct FP Load (single): Load(ptr, mem) = LD ptr",
852         reg_req   => { in => [ "!r0", "none" ], out => [ "fp","none" ] },
853         emit      => '. lfs %D0, %O(%S0)',
854         cmp_attr  =>
855 '
856         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
857 ',
858         outs      => [ "res", "M" ],
859 },
860
861 Stfd => {
862         op_flags  => "L|F",
863         state     => "exc_pinned",
864         comment   => "construct Store (double): Store(ptr, val, mem)  = ST ptr,val",
865         reg_req   => { in => [ "!r0", "fp", "none" ], out => [ "none" ] },
866         emit      => '. stfd %S1, %O(%S0)',
867         cmp_attr  =>
868 '
869         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
870 ',
871         outs      => [ "M" ],
872 },
873
874 Stfs => {
875         op_flags  => "L|F",
876         state     => "exc_pinned",
877         comment   => "construct Store (single): Store(ptr, val, mem)  = ST ptr,val",
878         reg_req   => { in => [ "!r0", "fp", "none" ], out => [ "none" ] },
879         emit      => '. stfs %S1, %O(%S0)',
880         cmp_attr  =>
881 '
882         return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
883 ',
884         outs      => [ "M" ],
885 },
886
887 ); # end of %nodes