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