sparc: fix delayslot picking order
[libfirm] / ir / be / sparc / sparc_spec.pl
1 # Creation: 2006/02/13
2
3 $arch = "sparc";
4
5 $mode_gp      = "mode_Iu";
6 $mode_flags   = "mode_Bu";
7 $mode_fpflags = "mode_Bu";
8 $mode_fp      = "mode_F";
9 $mode_fp2     = "mode_D";
10 $mode_fp4     = "mode_Q";
11
12 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
13 %reg_classes = (
14         gp => [
15                 # Note: locals come first here since they're usually constrained last
16                 # (by calls and others)
17                 { name => "l0", dwarf => 16 },
18                 { name => "l1", dwarf => 17 },
19                 { name => "l2", dwarf => 18 },
20                 { name => "l3", dwarf => 19 },
21                 { name => "l4", dwarf => 20 },
22                 { name => "l5", dwarf => 21 },
23                 { name => "l6", dwarf => 22 },
24                 { name => "l7", dwarf => 23 },
25
26                 { name => "g0", dwarf => 0 },
27                 { name => "g1", dwarf => 1 },
28                 { name => "g2", dwarf => 2 },
29                 { name => "g3", dwarf => 3 },
30                 { name => "g4", dwarf => 4 },
31                 { name => "g5", dwarf => 5 },
32                 { name => "g6", dwarf => 6 },
33                 { name => "g7", dwarf => 7 },
34
35                 { name => "o0", dwarf => 8 },
36                 { name => "o1", dwarf => 9 },
37                 { name => "o2", dwarf => 10 },
38                 { name => "o3", dwarf => 11 },
39                 { name => "o4", dwarf => 12 },
40                 { name => "o5", dwarf => 13 },
41                 { name => "sp", dwarf => 14 },
42                 { name => "o7", dwarf => 15 },
43
44                 { name => "i0", dwarf => 24 },
45                 { name => "i1", dwarf => 25 },
46                 { name => "i2", dwarf => 26 },
47                 { name => "i3", dwarf => 27 },
48                 { name => "i4", dwarf => 28 },
49                 { name => "i5", dwarf => 29 },
50                 { name => "frame_pointer", dwarf => 30, realname => "fp" },
51                 { name => "i7", dwarf => 30 },
52                 { mode => $mode_gp }
53         ],
54         fpflags_class => [
55                 { name => "fpflags" },
56                 { mode => $mode_fpflags, flags => "manual_ra" }
57         ],
58         flags_class => [
59                 { name => "flags" },
60                 { mode => $mode_flags, flags => "manual_ra" }
61         ],
62         mul_div_high_res => [
63                 { name => "y" },
64                 { mode => $mode_gp, flags => "manual_ra" }
65         ],
66         # fp registers can be accessed any time
67         fp => [
68                 { name => "f0",  dwarf => 32 },
69                 { name => "f1",  dwarf => 33 },
70                 { name => "f2",  dwarf => 34 },
71                 { name => "f3",  dwarf => 35 },
72                 { name => "f4",  dwarf => 36 },
73                 { name => "f5",  dwarf => 37 },
74                 { name => "f6",  dwarf => 38 },
75                 { name => "f7",  dwarf => 39 },
76                 { name => "f8",  dwarf => 40 },
77                 { name => "f9",  dwarf => 41 },
78                 { name => "f10", dwarf => 42 },
79                 { name => "f11", dwarf => 43 },
80                 { name => "f12", dwarf => 44 },
81                 { name => "f13", dwarf => 45 },
82                 { name => "f14", dwarf => 46 },
83                 { name => "f15", dwarf => 47 },
84                 { name => "f16", dwarf => 48 },
85                 { name => "f17", dwarf => 49 },
86                 { name => "f18", dwarf => 50 },
87                 { name => "f19", dwarf => 51 },
88                 { name => "f20", dwarf => 52 },
89                 { name => "f21", dwarf => 53 },
90                 { name => "f22", dwarf => 54 },
91                 { name => "f23", dwarf => 55 },
92                 { name => "f24", dwarf => 56 },
93                 { name => "f25", dwarf => 57 },
94                 { name => "f26", dwarf => 58 },
95                 { name => "f27", dwarf => 59 },
96                 { name => "f28", dwarf => 60 },
97                 { name => "f29", dwarf => 61 },
98                 { name => "f30", dwarf => 62 },
99                 { name => "f31", dwarf => 63 },
100                 { mode => $mode_fp }
101         ]
102 ); # %reg_classes
103
104 $default_attr_type = "sparc_attr_t";
105 $default_copy_attr = "sparc_copy_attr";
106
107 %init_attr = (
108         sparc_attr_t             => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
109         sparc_load_store_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
110         sparc_jmp_cond_attr_t    => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
111         sparc_switch_jmp_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
112                                     "\tinit_sparc_switch_jmp_attributes(res, table, jump_table);\n",
113         sparc_fp_attr_t          => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
114                                     "\tinit_sparc_fp_attributes(res, fp_mode);\n",
115         sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);".
116                                     "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
117 );
118
119 %compare_attr = (
120         sparc_attr_t            => "cmp_attr_sparc",
121         sparc_fp_attr_t         => "cmp_attr_sparc_fp",
122         sparc_fp_conv_attr_t    => "cmp_attr_sparc_fp_conv",
123         sparc_jmp_cond_attr_t   => "cmp_attr_sparc_jmp_cond",
124         sparc_load_store_attr_t => "cmp_attr_sparc_load_store",
125         sparc_switch_jmp_attr_t => "cmp_attr_sparc",
126 );
127
128 %custom_irn_flags = (
129         modifies_flags    => "(arch_irn_flags_t)sparc_arch_irn_flag_modifies_flags",
130         modifies_fp_flags => "(arch_irn_flags_t)sparc_arch_irn_flag_modifies_fp_flags",
131         has_delay_slot    => "(arch_irn_flags_t)sparc_arch_irn_flag_has_delay_slot",
132 );
133
134 my %cmp_operand_constructors = (
135         imm => {
136                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
137                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
138                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
139                 ins        => [ "left" ],
140         },
141         reg => {
142                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
143                 ins        => [ "left", "right" ],
144         },
145 );
146
147 my %binop_operand_constructors = (
148         imm => {
149                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
150                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
151                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
152                 ins        => [ "left" ],
153         },
154         reg => {
155                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
156                 ins        => [ "left", "right" ],
157         },
158 );
159
160 my %binopcc_operand_constructors = (
161         imm => {
162                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
163                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
164                 reg_req    => { in => [ "gp" ], out => [ "gp", "flags" ] },
165                 ins        => [ "left" ],
166         },
167         reg => {
168                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
169                 ins        => [ "left", "right" ],
170         },
171 );
172
173 my %binopx_operand_constructors = (
174         imm => {
175                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
176                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
177                 reg_req    => { in => [ "gp", "flags" ], out => [ "gp" ] },
178                 ins        => [ "left", "carry" ],
179         },
180         reg => {
181                 reg_req    => { in => [ "gp", "gp", "flags" ], out => [ "gp" ] },
182                 ins        => [ "left", "right", "carry" ],
183         },
184 );
185
186
187 my %binopcczero_operand_constructors = (
188         imm => {
189                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
190                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
191                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
192                 ins        => [ "left" ],
193         },
194         reg => {
195                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
196                 ins        => [ "left", "right" ],
197         },
198 );
199
200 my %div_operand_constructors = (
201         imm => {
202                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
203                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
204                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
205         },
206         reg => {
207                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "gp" ] },
208         },
209 );
210
211 my %float_binop_constructors = (
212         s => {
213                 reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
214                 mode    => $mode_fp,
215         },
216         d => {
217                 reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2" ] },
218                 mode    => $mode_fp2,
219         },
220         q => {
221                 reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4" ] },
222                 mode    => $mode_fp4,
223         }
224 );
225
226 my %float_unop_constructors = (
227         s => {
228                 reg_req => { in => [ "fp" ], out => [ "fp" ] },
229                 mode    => $mode_fp,
230         },
231         d => {
232                 reg_req => { in => [ "fp:a|2" ], out => [ "fp:a|2" ] },
233                 mode    => $mode_fp2,
234         },
235         q => {
236                 reg_req => { in => [ "fp:a|4" ], out => [ "fp:a|4" ] },
237                 mode    => $mode_fp4,
238         }
239 );
240
241 %nodes = (
242
243 Add => {
244         irn_flags    => [ "rematerializable" ],
245         mode         => $mode_gp,
246         emit         => 'add %S0, %SI1, %D0',
247         constructors => \%binop_operand_constructors,
248 },
249
250 AddCC => {
251         irn_flags    => [ "rematerializable", "modifies_flags" ],
252         emit         => 'addcc %S0, %SI1, %D0',
253         outs         => [ "res", "flags" ],
254         constructors => \%binopcc_operand_constructors,
255 },
256
257 AddCCZero => {
258         irn_flags    => [ "rematerializable", "modifies_flags" ],
259         emit         => 'addcc %S0, %SI1, %%g0',
260         mode         => $mode_flags,
261         constructors => \%binopcczero_operand_constructors,
262 },
263
264 AddX => {
265         # At the moment not rematerializable because of assert in beflags.c/
266         # (it claims that spiller can't rematerialize flag stuff correctly)
267         #irn_flags    => [ "rematerializable" ],
268         emit         => 'addx %S0, %SI1, %D0',
269         constructors => \%binopx_operand_constructors,
270         mode         => $mode_gp,
271 },
272
273 AddCC_t => {
274         ins       => [ "left", "right" ],
275         outs      => [ "res", "flags" ],
276         attr_type => "",
277         dump_func => "NULL",
278 },
279
280 AddX_t => {
281         ins       => [ "left", "right", "flags_input" ],
282         attr_type => "",
283         dump_func => "NULL",
284 },
285
286 Sub => {
287         irn_flags    => [ "rematerializable" ],
288         mode         => $mode_gp,
289         emit         => 'sub %S0, %SI1, %D0',
290         constructors => \%binop_operand_constructors,
291 },
292
293 SubCC => {
294         irn_flags    => [ "rematerializable", "modifies_flags" ],
295         emit         => 'subcc %S0, %SI1, %D0',
296         outs         => [ "res", "flags" ],
297         constructors => \%binopcc_operand_constructors,
298 },
299
300 SubCCZero => {
301         irn_flags    => [ "rematerializable", "modifies_flags" ],
302         emit         => 'subcc %S0, %SI1, %%g0',
303         mode         => $mode_flags,
304         constructors => \%binopcczero_operand_constructors,
305 },
306
307 SubX => {
308         # Not rematerializable (see AddX)
309         emit         => 'subx %S0, %SI1, %D0',
310         constructors => \%binopx_operand_constructors,
311         mode         => $mode_gp,
312 },
313
314 SubCC_t => {
315         ins       => [ "left", "right" ],
316         outs      => [ "res", "flags" ],
317         attr_type => "",
318         dump_func => "NULL",
319 },
320
321 SubX_t => {
322         ins       => [ "left", "right", "flags_input" ],
323         attr_type => "",
324         dump_func => "NULL",
325 },
326
327 # Load / Store
328 Ld => {
329         op_flags  => [ "uses_memory" ],
330         state     => "exc_pinned",
331         constructors => {
332                 imm => {
333                         reg_req    => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
334                         ins        => [ "ptr", "mem" ],
335                         attr       => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
336                         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
337                 },
338                 reg => {
339                         reg_req    => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
340                         ins        => [ "ptr", "ptr2", "mem" ],
341                         attr       => "ir_mode *ls_mode",
342                         custominit => "init_sparc_load_store_attributes(res, ls_mode, NULL, 0, false, true);",
343                 },
344         },
345         ins       => [ "ptr", "mem" ],
346         outs      => [ "res", "M" ],
347         attr_type => "sparc_load_store_attr_t",
348         emit      => 'ld%ML [%S0%O1], %D0'
349 },
350
351 SetHi => {
352         irn_flags  => [ "rematerializable" ],
353         outs       => [ "res" ],
354         mode       => $mode_gp,
355         reg_req    => { in => [], out => [ "gp" ] },
356         attr       => "ir_entity *entity, int32_t immediate_value",
357         custominit => "sparc_set_attr_imm(res, entity, immediate_value);",
358         emit       => 'sethi %H, %D0'
359 },
360
361 St => {
362         op_flags  => [ "uses_memory" ],
363         mode      => "mode_M",
364         state     => "exc_pinned",
365         constructors => {
366                 imm => {
367                         reg_req    => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
368                         ins        => [ "val", "ptr", "mem" ],
369                         attr       => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
370                         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
371                 },
372                 reg => {
373                         reg_req    => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
374                         ins        => [ "val", "ptr", "ptr2", "mem" ],
375                         attr       => "ir_mode *ls_mode",
376                         custominit => "init_sparc_load_store_attributes(res, ls_mode, NULL, 0, false, true);",
377                 },
378         },
379         ins       => [ "val", "ptr", "mem" ],
380         outs      => [ "M" ],
381         attr_type => "sparc_load_store_attr_t",
382         emit      => 'st%MS %S0, [%S1%O2]'
383 },
384
385 Save => {
386         emit      => 'save %S0, %SI1, %D0',
387         outs      => [ "stack" ],
388         ins       => [ "stack" ],
389         constructors => {
390                 imm => {
391                         attr       => "ir_entity *immediate_entity, int32_t immediate_value",
392                         custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
393                         reg_req    => { in => [ "sp" ], out => [ "sp:I|S" ] },
394                         ins        => [ "stack" ],
395                 },
396                 reg => {
397                         reg_req    => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
398                         ins        => [ "stack", "increment" ],
399                 }
400         },
401         mode => $mode_gp,
402 },
403
404 Restore => {
405         outs => [ "stack", "res" ],
406         constructors => {
407                 imm => {
408                         attr       => "ir_entity *immediate_entity, int32_t immediate_value",
409                         custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
410                         reg_req    => { in => [ "sp", "frame_pointer", "gp" ], out => [ "sp:I|S", "gp" ] },
411                         ins        => [ "stack", "frame_pointer", "left" ],
412                 },
413                 reg => {
414                         reg_req    => { in => [ "sp", "frame_pointer", "gp", "gp" ], out => [ "sp:I|S", "gp" ] },
415                         ins        => [ "stack", "frame_pointer", "left", "right" ],
416                 }
417         },
418 },
419
420 RestoreZero => {
421         reg_req => { in => [ "sp", "frame_pointer" ], out => [ "sp:I|S" ] },
422         ins     => [ "stack", "frame_pointer" ],
423         outs    => [ "stack" ],
424         emit    => 'restore',
425         mode    => $mode_gp,
426 },
427
428 SubSP => {
429         constructors => {
430                 imm => {
431                         attr       => "ir_entity *immediate_entity, int32_t immediate_value",
432                         custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
433                         reg_req    => { in => [ "sp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
434                         ins        => [ "stack", "mem" ],
435                 },
436                 reg => {
437                         reg_req    => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
438                         ins        => [ "stack", "size", "mem" ],
439                 }
440         },
441         outs    => [ "stack", "addr", "M" ],
442 },
443
444 AddSP => {
445         reg_req => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
446         ins     => [ "stack", "size" ],
447         outs    => [ "stack" ],
448         emit    => "add %S0, %S1, %D0\n",
449         mode    => $mode_gp,
450 },
451
452 FrameAddr => {
453         op_flags   => [ "constlike" ],
454         irn_flags  => [ "rematerializable" ],
455         attr       => "ir_entity *entity, int32_t offset",
456         reg_req    => { in => [ "gp" ], out => [ "gp" ] },
457         ins        => [ "base" ],
458         attr_type  => "sparc_attr_t",
459         custominit => "sparc_set_attr_imm(res, entity, offset);",
460         mode       => $mode_gp,
461 },
462
463 Bicc => {
464         op_flags  => [ "cfopcode", "forking" ],
465         irn_flags => [ "has_delay_slot" ],
466         state     => "pinned",
467         mode      => "mode_T",
468         attr_type => "sparc_jmp_cond_attr_t",
469         attr      => "ir_relation relation, bool is_unsigned",
470         init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, is_unsigned);",
471         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
472         ins       => [ "flags" ],
473         outs      => [ "false", "true" ],
474 },
475
476 fbfcc => {
477         op_flags  => [ "cfopcode", "forking" ],
478         irn_flags => [ "has_delay_slot" ],
479         state     => "pinned",
480         mode      => "mode_T",
481         attr_type => "sparc_jmp_cond_attr_t",
482         attr      => "ir_relation relation",
483         init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, false);",
484         reg_req   => { in => [ "fpflags" ], out => [ "none", "none" ] },
485         ins       => [ "flags" ],
486         outs      => [ "false", "true" ],
487 },
488
489 Ba => {
490         # Note: has_delay_slot depends on wether it is a fallthrough or not, so we
491         # have special code for this in sparc_emitter
492         state     => "pinned",
493         op_flags  => [ "cfopcode" ],
494         irn_flags => [ "simple_jump" ],
495         reg_req   => { out => [ "none" ] },
496         mode      => "mode_X",
497 },
498
499 Start => {
500         state     => "pinned",
501         out_arity => "variable",
502         ins       => [],
503 },
504
505 # This is a Jump instruction, but with the addition that you can add custom
506 # register constraints to model your calling conventions
507 Return => {
508         state     => "pinned",
509         op_flags  => [ "cfopcode" ],
510         irn_flags => [ "has_delay_slot" ],
511         arity     => "variable",
512         mode      => "mode_X",
513         constructors => {
514                 imm => {
515                         attr       => "ir_entity *entity, int32_t offset",
516                         custominit => "\tsparc_set_attr_imm(res, entity, offset);",
517                         arity     => "variable",
518                         reg_req   => { out => [ "none" ] },
519                 },
520                 reg => {
521                         arity     => "variable",
522                         reg_req   => { out => [ "none" ] },
523                 }
524         },
525 },
526
527 # This is a JumpLink instruction, but with the addition that you can add custom
528 # register constraints to model your calling conventions
529 Call => {
530         irn_flags => [ "modifies_flags", "modifies_fp_flags", "has_delay_slot" ],
531         state     => "exc_pinned",
532         arity     => "variable",
533         out_arity => "variable",
534         constructors => {
535                 imm => {
536                         attr       => "ir_entity *entity, int32_t offset, bool aggregate_return",
537                         custominit => "\tsparc_set_attr_imm(res, entity, offset);".
538                                       "\tif (aggregate_return) arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_aggregate_return);",
539                         arity     => "variable",
540                         out_arity => "variable",
541                 },
542                 reg => {
543                         attr       => "bool aggregate_return",
544                         arity      => "variable",
545                         out_arity  => "variable",
546                         custominit => "\tif (aggregate_return) arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_aggregate_return);",
547                 }
548         },
549 },
550
551 Cmp => {  # aka SubccZero
552         irn_flags    => [ "rematerializable", "modifies_flags" ],
553         emit         => 'cmp %S0, %SI1',
554         mode         => $mode_flags,
555         constructors => \%binopcczero_operand_constructors,
556 },
557
558 SwitchJmp => {
559         op_flags     => [ "cfopcode", "forking" ],
560         irn_flags    => [ "has_delay_slot" ],
561         state        => "pinned",
562         mode         => "mode_T",
563         reg_req      => { in => [ "gp" ], out => [ ] },
564         out_arity    => "variable",
565         attr_type    => "sparc_switch_jmp_attr_t",
566         attr         => "const ir_switch_table *table, ir_entity *jump_table",
567 },
568
569 Sll => {
570         irn_flags    => [ "rematerializable" ],
571         mode         => $mode_gp,
572         emit         => 'sll %S0, %SI1, %D0',
573         constructors => \%binop_operand_constructors,
574 },
575
576 Srl => {
577         irn_flags    => [ "rematerializable" ],
578         mode         => $mode_gp,
579         emit         => 'srl %S0, %SI1, %D0',
580         constructors => \%binop_operand_constructors,
581 },
582
583 Sra => {
584         irn_flags    => [ "rematerializable" ],
585         mode         => $mode_gp,
586         emit         => 'sra %S0, %SI1, %D0',
587         constructors => \%binop_operand_constructors,
588 },
589
590 And => {
591         irn_flags    => [ "rematerializable" ],
592         mode         => $mode_gp,
593         emit         => 'and %S0, %SI1, %D0',
594         constructors => \%binop_operand_constructors,
595 },
596
597 AndCCZero => {
598         irn_flags    => [ "rematerializable", "modifies_flags" ],
599         emit         => 'andcc %S0, %SI1, %%g0',
600         mode         => $mode_flags,
601         constructors => \%binopcczero_operand_constructors,
602 },
603
604 AndN => {
605         irn_flags => [ "rematerializable" ],
606         mode      => $mode_gp,
607         emit      => 'andn %S0, %SI1, %D0',
608         constructors => \%binop_operand_constructors,
609 },
610
611 AndNCCZero => {
612         irn_flags    => [ "rematerializable", "modifies_flags" ],
613         emit         => 'andncc %S0, %SI1, %%g0',
614         mode         => $mode_flags,
615         constructors => \%binopcczero_operand_constructors,
616 },
617
618 Or => {
619         irn_flags    => [ "rematerializable" ],
620         mode         => $mode_gp,
621         emit         => 'or %S0, %SI1, %D0',
622         constructors => \%binop_operand_constructors,
623 },
624
625 OrCCZero => {
626         irn_flags    => [ "rematerializable", "modifies_flags" ],
627         emit         => 'orcc %S0, %SI1, %%g0',
628         mode         => $mode_flags,
629         constructors => \%binopcczero_operand_constructors,
630 },
631
632 OrN => {
633         irn_flags => [ "rematerializable" ],
634         mode      => $mode_gp,
635         emit      => 'orn %S0, %SI1, %D0',
636         constructors => \%binop_operand_constructors,
637 },
638
639 OrNCCZero => {
640         irn_flags    => [ "rematerializable", "modifies_flags" ],
641         emit         => 'orncc %S0, %SI1, %%g0',
642         mode         => $mode_flags,
643         constructors => \%binopcczero_operand_constructors,
644 },
645
646 Xor => {
647         irn_flags    => [ "rematerializable" ],
648         mode         => $mode_gp,
649         emit         => 'xor %S0, %SI1, %D0',
650         constructors => \%binop_operand_constructors,
651 },
652
653 XorCCZero => {
654         irn_flags    => [ "rematerializable", "modifies_flags" ],
655         emit         => 'xorcc %S0, %SI1, %%g0',
656         mode         => $mode_flags,
657         constructors => \%binopcczero_operand_constructors,
658 },
659
660 XNor => {
661         irn_flags => [ "rematerializable" ],
662         mode      => $mode_gp,
663         emit      => 'xnor %S0, %SI1, %D0',
664         constructors => \%binop_operand_constructors,
665 },
666
667 XNorCCZero => {
668         irn_flags    => [ "rematerializable", "modifies_flags" ],
669         emit         => 'xnorcc %S0, %SI1, %%g0',
670         mode         => $mode_flags,
671         constructors => \%binopcczero_operand_constructors,
672 },
673
674 Mul => {
675         irn_flags    => [ "rematerializable" ],
676         mode         => $mode_gp,
677         emit         => 'smul %S0, %SI1, %D0',
678         constructors => \%binop_operand_constructors,
679 },
680
681 MulCCZero => {
682         irn_flags    => [ "rematerializable", "modifies_flags" ],
683         emit         => 'smulcc %S0, %SI1, %%g0',
684         mode         => $mode_flags,
685         constructors => \%binopcczero_operand_constructors,
686 },
687
688 SMulh => {
689         irn_flags    => [ "rematerializable" ],
690         outs         => [ "low", "high" ],
691         emit         => 'smul %S0, %SI1, %D0\n'.
692                         'mov %%y, %D0',
693         constructors => \%binop_operand_constructors,
694 },
695
696 UMulh => {
697         irn_flags    => [ "rematerializable" ],
698         outs         => [ "low", "high" ],
699         emit         => 'umul %S0, %SI1, %D0\n'.
700                         'mov %%y, %D0',
701         constructors => \%binop_operand_constructors,
702 },
703
704 SDiv => {
705         irn_flags    => [ "rematerializable", "has_delay_slot" ],
706         state        => "exc_pinned",
707         ins          => [ "dividend_high", "dividend_low", "divisor" ],
708         outs         => [ "res", "M" ],
709         constructors => \%div_operand_constructors,
710 },
711
712 UDiv => {
713         irn_flags    => [ "rematerializable", "has_delay_slot" ],
714         state        => "exc_pinned",
715         ins          => [ "dividend_high", "dividend_low", "divisor" ],
716         outs         => [ "res", "M" ],
717         constructors => \%div_operand_constructors,
718 },
719
720 fcmp => {
721         irn_flags => [ "rematerializable", "modifies_fp_flags" ],
722         emit      => 'fcmp%FM %S0, %S1',
723         attr_type => "sparc_fp_attr_t",
724         attr      => "ir_mode *fp_mode",
725         mode      => $mode_fpflags,
726         constructors => {
727                 s => {
728                         reg_req => { in => [ "fp", "fp" ], out => [ "fpflags" ] },
729                 },
730                 d => {
731                         reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fpflags" ] },
732                 },
733                 q => {
734                         reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fpflags" ] },
735                 },
736         },
737 },
738
739 fadd => {
740         op_flags     => [ "commutative" ],
741         irn_flags    => [ "rematerializable" ],
742         emit         => 'fadd%FM %S0, %S1, %D0',
743         attr_type    => "sparc_fp_attr_t",
744         attr         => "ir_mode *fp_mode",
745         ins          => [ "left", "right" ],
746         constructors => \%float_binop_constructors,
747 },
748
749 fsub => {
750         irn_flags    => [ "rematerializable" ],
751         emit         => 'fsub%FM %S0, %S1, %D0',
752         attr_type    => "sparc_fp_attr_t",
753         attr         => "ir_mode *fp_mode",
754         ins          => [ "left", "right" ],
755         constructors => \%float_binop_constructors,
756 },
757
758 fmul => {
759         irn_flags    => [ "rematerializable" ],
760         op_flags     => [ "commutative" ],
761         emit         =>'fmul%FM %S0, %S1, %D0',
762         attr_type    => "sparc_fp_attr_t",
763         attr         => "ir_mode *fp_mode",
764         ins          => [ "left", "right" ],
765         constructors => \%float_binop_constructors,
766 },
767
768 fdiv => {
769         irn_flags    => [ "rematerializable" ],
770         emit         => 'fdiv%FM %S0, %S1, %D0',
771         attr_type    => "sparc_fp_attr_t",
772         attr         => "ir_mode *fp_mode",
773         ins          => [ "left", "right" ],
774         outs         => [ "res", "M" ],
775         constructors => {
776                 s => {
777                         reg_req => { in => [ "fp", "fp" ], out => [ "fp", "none" ] },
778                 },
779                 d => {
780                         reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2", "none" ] },
781                 },
782                 q => {
783                         reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4", "none" ] },
784                 }
785         },
786 },
787
788 fneg => {
789         irn_flags => [ "rematerializable" ],
790         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
791         # note that we only need the first register even for wide-values
792         emit      => 'fnegs %S0, %D0',
793         attr_type => "sparc_fp_attr_t",
794         attr      => "ir_mode *fp_mode",
795         ins          => [ "val" ],
796         constructors => \%float_unop_constructors,
797 },
798
799 "fabs" => {
800         irn_flags    => [ "rematerializable" ],
801         # note that we only need the first register even for wide-values
802         emit         => 'fabs %S0, %D0',
803         attr_type    => "sparc_fp_attr_t",
804         attr         => "ir_mode *fp_mode",
805         ins          => [ "val" ],
806         constructors => \%float_unop_constructors,
807 },
808
809 fftof => {
810         irn_flags => [ "rematerializable" ],
811         emit      => 'f%FSto%FD %S0, %D0',
812         attr_type => "sparc_fp_conv_attr_t",
813         attr      => "ir_mode *src_mode, ir_mode *dest_mode",
814         constructors => {
815                 s_d => {
816                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
817                         mode    => $mode_fp2,
818                 },
819                 s_q => {
820                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
821                         mode    => $mode_fp4,
822                 },
823                 d_s => {
824                         reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
825                         mode    => $mode_fp,
826                 },
827                 d_q => {
828                         reg_req => { in => [ "fp:a|2" ], out => [ "fp:a|4" ] },
829                         mode    => $mode_fp4,
830                 },
831                 q_s => {
832                         reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
833                         mode    => $mode_fp,
834                 },
835                 q_d => {
836                         reg_req => { in => [ "fp:a|4" ], out => [ "fp:a|2" ] },
837                         mode    => $mode_fp2,
838                 },
839         },
840 },
841
842 fitof => {
843         irn_flags => [ "rematerializable" ],
844         emit      => 'fito%FM %S0, %D0',
845         attr_type => "sparc_fp_attr_t",
846         attr      => "ir_mode *fp_mode",
847         constructors => {
848                 s => {
849                         reg_req => { in => [ "fp" ], out => [ "fp" ] },
850                         mode    => $mode_fp,
851                 },
852                 d => {
853                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
854                         mode    => $mode_fp2,
855                 },
856                 q => {
857                         reg_req => { in => [ "fp" ], out => [ "fp:a|4" ] },
858                         mode    => $mode_fp4,
859                 },
860         },
861 },
862
863 fftoi => {
864         irn_flags => [ "rematerializable" ],
865         emit      => 'f%FMtoi %S0, %D0',
866         attr_type => "sparc_fp_attr_t",
867         attr      => "ir_mode *fp_mode",
868         mode      => $mode_gp,
869         constructors => {
870                 s => {
871                         reg_req => { in => [ "fp" ], out => [ "fp" ] },
872                 },
873                 d => {
874                         reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
875                 },
876                 q => {
877                         reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
878                 },
879         },
880 },
881
882 Ldf => {
883         op_flags  => [ "uses_memory" ],
884         state     => "exc_pinned",
885         constructors => {
886                 s => {
887                         reg_req => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
888                 },
889                 d => {
890                         reg_req => { in => [ "gp", "none" ], out => [ "fp:a|2", "none" ] },
891                 },
892                 q => {
893                         reg_req => { in => [ "gp", "none" ], out => [ "fp:a|4", "none" ] },
894                 },
895         },
896         ins       => [ "ptr", "mem" ],
897         outs      => [ "res", "M" ],
898         attr_type => "sparc_load_store_attr_t",
899         attr      => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
900         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
901         emit      => 'ld%ML [%S0%O1], %D0'
902 },
903
904 Stf => {
905         op_flags  => [ "uses_memory" ],
906         state     => "exc_pinned",
907         constructors => {
908                 s => {
909                         reg_req => { in => [ "fp",     "gp", "none" ], out => [ "none" ] },
910                 },
911                 d => {
912                         reg_req => { in => [ "fp:a|2", "gp", "none" ], out => [ "none" ] },
913                 },
914                 q => {
915                         reg_req => { in => [ "fp:a|4", "gp", "none" ], out => [ "none" ] },
916                 },
917         },
918         ins       => [ "val", "ptr", "mem" ],
919         outs      => [ "M" ],
920         attr_type => "sparc_load_store_attr_t",
921         attr      => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
922         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
923         emit      => 'st%MS %S0, [%S1%O2]',
924         mode      => 'mode_M',
925 },
926
927 ); # end of %nodes