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