tv: Remove mul_table[][][] and simply use * and <<.
[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 => 31 },
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         has_delay_slot    => "(arch_irn_flags_t)sparc_arch_irn_flag_has_delay_slot",
130 );
131
132 my %cmp_operand_constructors = (
133         imm => {
134                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
135                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
136                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
137                 ins        => [ "left" ],
138         },
139         reg => {
140                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
141                 ins        => [ "left", "right" ],
142         },
143 );
144
145 my %binop_operand_constructors = (
146         imm => {
147                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
148                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
149                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
150                 ins        => [ "left" ],
151         },
152         reg => {
153                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
154                 ins        => [ "left", "right" ],
155         },
156 );
157
158 my %binopcc_operand_constructors = (
159         imm => {
160                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
161                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
162                 reg_req    => { in => [ "gp" ], out => [ "gp", "flags" ] },
163                 ins        => [ "left" ],
164         },
165         reg => {
166                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
167                 ins        => [ "left", "right" ],
168         },
169 );
170
171 my %binopx_operand_constructors = (
172         imm => {
173                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
174                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
175                 reg_req    => { in => [ "gp", "flags" ], out => [ "gp" ] },
176                 ins        => [ "left", "carry" ],
177         },
178         reg => {
179                 reg_req    => { in => [ "gp", "gp", "flags" ], out => [ "gp" ] },
180                 ins        => [ "left", "right", "carry" ],
181         },
182 );
183
184
185 my %binopcczero_operand_constructors = (
186         imm => {
187                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
188                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
189                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
190                 ins        => [ "left" ],
191         },
192         reg => {
193                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
194                 ins        => [ "left", "right" ],
195         },
196 );
197
198 my %div_operand_constructors = (
199         imm => {
200                 attr       => "ir_entity *immediate_entity, int32_t immediate_value",
201                 custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
202                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
203         },
204         reg => {
205                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "gp" ] },
206         },
207 );
208
209 my %float_binop_constructors = (
210         s => {
211                 reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
212                 mode    => $mode_fp,
213         },
214         d => {
215                 reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2" ] },
216                 mode    => $mode_fp2,
217         },
218         q => {
219                 reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4" ] },
220                 mode    => $mode_fp4,
221         }
222 );
223
224 my %float_unop_constructors = (
225         s => {
226                 reg_req => { in => [ "fp" ], out => [ "fp" ] },
227                 mode    => $mode_fp,
228         },
229         d => {
230                 reg_req => { in => [ "fp:a|2" ], out => [ "fp:a|2" ] },
231                 mode    => $mode_fp2,
232         },
233         q => {
234                 reg_req => { in => [ "fp:a|4" ], out => [ "fp:a|4" ] },
235                 mode    => $mode_fp4,
236         }
237 );
238
239 %nodes = (
240
241 Add => {
242         irn_flags    => [ "rematerializable" ],
243         mode         => $mode_gp,
244         emit         => 'add %S0, %SI1, %D0',
245         constructors => \%binop_operand_constructors,
246 },
247
248 AddCC => {
249         irn_flags    => [ "rematerializable" ],
250         emit         => 'addcc %S0, %SI1, %D0',
251         outs         => [ "res", "flags" ],
252         constructors => \%binopcc_operand_constructors,
253 },
254
255 AddCCZero => {
256         irn_flags    => [ "rematerializable" ],
257         emit         => 'addcc %S0, %SI1, %%g0',
258         mode         => $mode_flags,
259         constructors => \%binopcczero_operand_constructors,
260 },
261
262 AddX => {
263         # At the moment not rematerializable because of assert in beflags.c/
264         # (it claims that spiller can't rematerialize flag stuff correctly)
265         #irn_flags    => [ "rematerializable" ],
266         emit         => 'addx %S0, %SI1, %D0',
267         constructors => \%binopx_operand_constructors,
268         mode         => $mode_gp,
269 },
270
271 AddCC_t => {
272         ins       => [ "left", "right" ],
273         outs      => [ "res", "flags" ],
274         attr_type => "",
275         dump_func => "NULL",
276 },
277
278 AddX_t => {
279         ins       => [ "left", "right", "flags_input" ],
280         attr_type => "",
281         dump_func => "NULL",
282 },
283
284 Sub => {
285         irn_flags    => [ "rematerializable" ],
286         mode         => $mode_gp,
287         emit         => 'sub %S0, %SI1, %D0',
288         constructors => \%binop_operand_constructors,
289 },
290
291 SubCC => {
292         irn_flags    => [ "rematerializable" ],
293         emit         => 'subcc %S0, %SI1, %D0',
294         outs         => [ "res", "flags" ],
295         constructors => \%binopcc_operand_constructors,
296 },
297
298 SubCCZero => {
299         irn_flags    => [ "rematerializable" ],
300         emit         => 'subcc %S0, %SI1, %%g0',
301         mode         => $mode_flags,
302         constructors => \%binopcczero_operand_constructors,
303 },
304
305 SubX => {
306         # Not rematerializable (see AddX)
307         emit         => 'subx %S0, %SI1, %D0',
308         constructors => \%binopx_operand_constructors,
309         mode         => $mode_gp,
310 },
311
312 SubCC_t => {
313         ins       => [ "left", "right" ],
314         outs      => [ "res", "flags" ],
315         attr_type => "",
316         dump_func => "NULL",
317 },
318
319 SubX_t => {
320         ins       => [ "left", "right", "flags_input" ],
321         attr_type => "",
322         dump_func => "NULL",
323 },
324
325 # Load / Store
326 Ld => {
327         op_flags  => [ "uses_memory" ],
328         state     => "exc_pinned",
329         constructors => {
330                 imm => {
331                         reg_req    => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
332                         ins        => [ "ptr", "mem" ],
333                         attr       => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
334                         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
335                 },
336                 reg => {
337                         reg_req    => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
338                         ins        => [ "ptr", "ptr2", "mem" ],
339                         attr       => "ir_mode *ls_mode",
340                         custominit => "init_sparc_load_store_attributes(res, ls_mode, NULL, 0, false, true);",
341                 },
342         },
343         ins       => [ "ptr", "mem" ],
344         outs      => [ "res", "M" ],
345         attr_type => "sparc_load_store_attr_t",
346         emit      => 'ld%ML [%S0%O1], %D0'
347 },
348
349 SetHi => {
350         irn_flags  => [ "rematerializable" ],
351         outs       => [ "res" ],
352         mode       => $mode_gp,
353         reg_req    => { in => [], out => [ "gp" ] },
354         attr       => "ir_entity *entity, int32_t immediate_value",
355         custominit => "sparc_set_attr_imm(res, entity, immediate_value);",
356         emit       => 'sethi %H, %D0'
357 },
358
359 St => {
360         op_flags  => [ "uses_memory" ],
361         mode      => "mode_M",
362         state     => "exc_pinned",
363         constructors => {
364                 imm => {
365                         reg_req    => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
366                         ins        => [ "val", "ptr", "mem" ],
367                         attr       => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
368                         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
369                 },
370                 reg => {
371                         reg_req    => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
372                         ins        => [ "val", "ptr", "ptr2", "mem" ],
373                         attr       => "ir_mode *ls_mode",
374                         custominit => "init_sparc_load_store_attributes(res, ls_mode, NULL, 0, false, true);",
375                 },
376         },
377         ins       => [ "val", "ptr", "mem" ],
378         outs      => [ "M" ],
379         attr_type => "sparc_load_store_attr_t",
380         emit      => 'st%MS %S0, [%S1%O2]'
381 },
382
383 Save => {
384         emit      => 'save %S0, %SI1, %D0',
385         outs      => [ "stack" ],
386         ins       => [ "stack" ],
387         constructors => {
388                 imm => {
389                         attr       => "ir_entity *immediate_entity, int32_t immediate_value",
390                         custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
391                         reg_req    => { in => [ "sp" ], out => [ "sp:I|S" ] },
392                         ins        => [ "stack" ],
393                 },
394                 reg => {
395                         reg_req    => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
396                         ins        => [ "stack", "increment" ],
397                 }
398         },
399         mode => $mode_gp,
400 },
401
402 Restore => {
403         outs => [ "stack", "res" ],
404         constructors => {
405                 imm => {
406                         attr       => "ir_entity *immediate_entity, int32_t immediate_value",
407                         custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
408                         reg_req    => { in => [ "sp", "frame_pointer", "gp" ], out => [ "sp:I|S", "gp" ] },
409                         ins        => [ "stack", "frame_pointer", "left" ],
410                 },
411                 reg => {
412                         reg_req    => { in => [ "sp", "frame_pointer", "gp", "gp" ], out => [ "sp:I|S", "gp" ] },
413                         ins        => [ "stack", "frame_pointer", "left", "right" ],
414                 }
415         },
416 },
417
418 RestoreZero => {
419         reg_req => { in => [ "sp", "frame_pointer" ], out => [ "sp:I|S" ] },
420         ins     => [ "stack", "frame_pointer" ],
421         outs    => [ "stack" ],
422         emit    => 'restore',
423         mode    => $mode_gp,
424 },
425
426 SubSP => {
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 => [ "sp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
432                         ins        => [ "stack", "mem" ],
433                 },
434                 reg => {
435                         reg_req    => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
436                         ins        => [ "stack", "size", "mem" ],
437                 }
438         },
439         outs    => [ "stack", "addr", "M" ],
440 },
441
442 AddSP => {
443         reg_req => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
444         ins     => [ "stack", "size" ],
445         outs    => [ "stack" ],
446         emit    => "add %S0, %S1, %D0\n",
447         mode    => $mode_gp,
448 },
449
450 FrameAddr => {
451         op_flags   => [ "constlike" ],
452         irn_flags  => [ "rematerializable" ],
453         attr       => "ir_entity *entity, int32_t offset",
454         reg_req    => { in => [ "gp" ], out => [ "gp" ] },
455         ins        => [ "base" ],
456         attr_type  => "sparc_attr_t",
457         custominit => "sparc_set_attr_imm(res, entity, offset);",
458         mode       => $mode_gp,
459 },
460
461 Bicc => {
462         op_flags  => [ "cfopcode", "forking" ],
463         irn_flags => [ "has_delay_slot" ],
464         state     => "pinned",
465         mode      => "mode_T",
466         attr_type => "sparc_jmp_cond_attr_t",
467         attr      => "ir_relation relation, bool is_unsigned",
468         init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, is_unsigned);",
469         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
470         ins       => [ "flags" ],
471         outs      => [ "false", "true" ],
472 },
473
474 fbfcc => {
475         op_flags  => [ "cfopcode", "forking" ],
476         irn_flags => [ "has_delay_slot" ],
477         state     => "pinned",
478         mode      => "mode_T",
479         attr_type => "sparc_jmp_cond_attr_t",
480         attr      => "ir_relation relation",
481         init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, false);",
482         reg_req   => { in => [ "fpflags" ], out => [ "none", "none" ] },
483         ins       => [ "flags" ],
484         outs      => [ "false", "true" ],
485 },
486
487 Ba => {
488         # Note: has_delay_slot depends on whether it is a fallthrough or not, so we
489         # have special code for this in sparc_emitter
490         state     => "pinned",
491         op_flags  => [ "cfopcode" ],
492         irn_flags => [ "simple_jump" ],
493         reg_req   => { out => [ "none" ] },
494         mode      => "mode_X",
495 },
496
497 Start => {
498         state     => "pinned",
499         out_arity => "variable",
500         ins       => [],
501 },
502
503 # This is a Jump instruction, but with the addition that you can add custom
504 # register constraints to model your calling conventions
505 Return => {
506         state     => "pinned",
507         op_flags  => [ "cfopcode" ],
508         irn_flags => [ "has_delay_slot" ],
509         arity     => "variable",
510         mode      => "mode_X",
511         constructors => {
512                 imm => {
513                         attr       => "ir_entity *entity, int32_t offset",
514                         custominit => "\tsparc_set_attr_imm(res, entity, offset);",
515                         arity     => "variable",
516                         reg_req   => { out => [ "none" ] },
517                 },
518                 reg => {
519                         arity     => "variable",
520                         reg_req   => { out => [ "none" ] },
521                 }
522         },
523 },
524
525 # This is a JumpLink instruction, but with the addition that you can add custom
526 # register constraints to model your calling conventions
527 Call => {
528         irn_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, (arch_irn_flags_t)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, (arch_irn_flags_t)sparc_arch_irn_flag_aggregate_return);",
545                 }
546         },
547 },
548
549 Cmp => {  # aka SubccZero
550         irn_flags    => [ "rematerializable" ],
551         emit         => 'cmp %S0, %SI1',
552         mode         => $mode_flags,
553         constructors => \%binopcczero_operand_constructors,
554 },
555
556 SwitchJmp => {
557         op_flags     => [ "cfopcode", "forking" ],
558         irn_flags    => [ "has_delay_slot" ],
559         state        => "pinned",
560         mode         => "mode_T",
561         reg_req      => { in => [ "gp" ], out => [ ] },
562         out_arity    => "variable",
563         attr_type    => "sparc_switch_jmp_attr_t",
564         attr         => "const ir_switch_table *table, ir_entity *jump_table",
565 },
566
567 Sll => {
568         irn_flags    => [ "rematerializable" ],
569         mode         => $mode_gp,
570         emit         => 'sll %S0, %SI1, %D0',
571         constructors => \%binop_operand_constructors,
572 },
573
574 Srl => {
575         irn_flags    => [ "rematerializable" ],
576         mode         => $mode_gp,
577         emit         => 'srl %S0, %SI1, %D0',
578         constructors => \%binop_operand_constructors,
579 },
580
581 Sra => {
582         irn_flags    => [ "rematerializable" ],
583         mode         => $mode_gp,
584         emit         => 'sra %S0, %SI1, %D0',
585         constructors => \%binop_operand_constructors,
586 },
587
588 And => {
589         irn_flags    => [ "rematerializable" ],
590         mode         => $mode_gp,
591         emit         => 'and %S0, %SI1, %D0',
592         constructors => \%binop_operand_constructors,
593 },
594
595 AndCCZero => {
596         irn_flags    => [ "rematerializable" ],
597         emit         => 'andcc %S0, %SI1, %%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, %SI1, %D0',
606         constructors => \%binop_operand_constructors,
607 },
608
609 AndNCCZero => {
610         irn_flags    => [ "rematerializable" ],
611         emit         => 'andncc %S0, %SI1, %%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, %SI1, %D0',
620         constructors => \%binop_operand_constructors,
621 },
622
623 OrCCZero => {
624         irn_flags    => [ "rematerializable" ],
625         emit         => 'orcc %S0, %SI1, %%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, %SI1, %D0',
634         constructors => \%binop_operand_constructors,
635 },
636
637 OrNCCZero => {
638         irn_flags    => [ "rematerializable" ],
639         emit         => 'orncc %S0, %SI1, %%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, %SI1, %D0',
648         constructors => \%binop_operand_constructors,
649 },
650
651 XorCCZero => {
652         irn_flags    => [ "rematerializable" ],
653         emit         => 'xorcc %S0, %SI1, %%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, %SI1, %D0',
662         constructors => \%binop_operand_constructors,
663 },
664
665 XNorCCZero => {
666         irn_flags    => [ "rematerializable" ],
667         emit         => 'xnorcc %S0, %SI1, %%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, %SI1, %D0',
676         constructors => \%binop_operand_constructors,
677 },
678
679 MulCCZero => {
680         irn_flags    => [ "rematerializable" ],
681         emit         => 'smulcc %S0, %SI1, %%g0',
682         mode         => $mode_flags,
683         constructors => \%binopcczero_operand_constructors,
684 },
685
686 SMulh => {
687         irn_flags    => [ "rematerializable" ],
688         outs         => [ "low", "high" ],
689         emit         => 'smul %S0, %SI1, %D0\n'.
690                         'mov %%y, %D0',
691         constructors => \%binop_operand_constructors,
692 },
693
694 UMulh => {
695         irn_flags    => [ "rematerializable" ],
696         outs         => [ "low", "high" ],
697         emit         => 'umul %S0, %SI1, %D0\n'.
698                         'mov %%y, %D0',
699         constructors => \%binop_operand_constructors,
700 },
701
702 SDiv => {
703         irn_flags    => [ "rematerializable", "has_delay_slot" ],
704         state        => "exc_pinned",
705         ins          => [ "dividend_high", "dividend_low", "divisor" ],
706         outs         => [ "res", "M" ],
707         constructors => \%div_operand_constructors,
708 },
709
710 UDiv => {
711         irn_flags    => [ "rematerializable", "has_delay_slot" ],
712         state        => "exc_pinned",
713         ins          => [ "dividend_high", "dividend_low", "divisor" ],
714         outs         => [ "res", "M" ],
715         constructors => \%div_operand_constructors,
716 },
717
718 fcmp => {
719         irn_flags => [ "rematerializable" ],
720         emit      => 'fcmp%FM %S0, %S1',
721         attr_type => "sparc_fp_attr_t",
722         attr      => "ir_mode *fp_mode",
723         mode      => $mode_fpflags,
724         constructors => {
725                 s => {
726                         reg_req => { in => [ "fp", "fp" ], out => [ "fpflags" ] },
727                 },
728                 d => {
729                         reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fpflags" ] },
730                 },
731                 q => {
732                         reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fpflags" ] },
733                 },
734         },
735 },
736
737 fadd => {
738         op_flags     => [ "commutative" ],
739         irn_flags    => [ "rematerializable" ],
740         emit         => 'fadd%FM %S0, %S1, %D0',
741         attr_type    => "sparc_fp_attr_t",
742         attr         => "ir_mode *fp_mode",
743         ins          => [ "left", "right" ],
744         constructors => \%float_binop_constructors,
745 },
746
747 fsub => {
748         irn_flags    => [ "rematerializable" ],
749         emit         => 'fsub%FM %S0, %S1, %D0',
750         attr_type    => "sparc_fp_attr_t",
751         attr         => "ir_mode *fp_mode",
752         ins          => [ "left", "right" ],
753         constructors => \%float_binop_constructors,
754 },
755
756 fmul => {
757         irn_flags    => [ "rematerializable" ],
758         op_flags     => [ "commutative" ],
759         emit         =>'fmul%FM %S0, %S1, %D0',
760         attr_type    => "sparc_fp_attr_t",
761         attr         => "ir_mode *fp_mode",
762         ins          => [ "left", "right" ],
763         constructors => \%float_binop_constructors,
764 },
765
766 fdiv => {
767         irn_flags    => [ "rematerializable" ],
768         emit         => 'fdiv%FM %S0, %S1, %D0',
769         attr_type    => "sparc_fp_attr_t",
770         attr         => "ir_mode *fp_mode",
771         ins          => [ "left", "right" ],
772         outs         => [ "res", "M" ],
773         constructors => {
774                 s => {
775                         reg_req => { in => [ "fp", "fp" ], out => [ "fp", "none" ] },
776                 },
777                 d => {
778                         reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2", "none" ] },
779                 },
780                 q => {
781                         reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4", "none" ] },
782                 }
783         },
784 },
785
786 fneg => {
787         irn_flags => [ "rematerializable" ],
788         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
789         # note that we only need the first register even for wide-values
790         emit      => 'fnegs %S0, %D0',
791         attr_type => "sparc_fp_attr_t",
792         attr      => "ir_mode *fp_mode",
793         ins          => [ "val" ],
794         constructors => \%float_unop_constructors,
795 },
796
797 "fabs" => {
798         irn_flags    => [ "rematerializable" ],
799         # note that we only need the first register even for wide-values
800         emit         => 'fabs %S0, %D0',
801         attr_type    => "sparc_fp_attr_t",
802         attr         => "ir_mode *fp_mode",
803         ins          => [ "val" ],
804         constructors => \%float_unop_constructors,
805 },
806
807 fftof => {
808         irn_flags => [ "rematerializable" ],
809         emit      => 'f%FSto%FD %S0, %D0',
810         attr_type => "sparc_fp_conv_attr_t",
811         attr      => "ir_mode *src_mode, ir_mode *dest_mode",
812         constructors => {
813                 s_d => {
814                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
815                         mode    => $mode_fp2,
816                 },
817                 s_q => {
818                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
819                         mode    => $mode_fp4,
820                 },
821                 d_s => {
822                         reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
823                         mode    => $mode_fp,
824                 },
825                 d_q => {
826                         reg_req => { in => [ "fp:a|2" ], out => [ "fp:a|4" ] },
827                         mode    => $mode_fp4,
828                 },
829                 q_s => {
830                         reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
831                         mode    => $mode_fp,
832                 },
833                 q_d => {
834                         reg_req => { in => [ "fp:a|4" ], out => [ "fp:a|2" ] },
835                         mode    => $mode_fp2,
836                 },
837         },
838 },
839
840 fitof => {
841         irn_flags => [ "rematerializable" ],
842         emit      => 'fito%FM %S0, %D0',
843         attr_type => "sparc_fp_attr_t",
844         attr      => "ir_mode *fp_mode",
845         constructors => {
846                 s => {
847                         reg_req => { in => [ "fp" ], out => [ "fp" ] },
848                         mode    => $mode_fp,
849                 },
850                 d => {
851                         reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
852                         mode    => $mode_fp2,
853                 },
854                 q => {
855                         reg_req => { in => [ "fp" ], out => [ "fp:a|4" ] },
856                         mode    => $mode_fp4,
857                 },
858         },
859 },
860
861 fftoi => {
862         irn_flags => [ "rematerializable" ],
863         emit      => 'f%FMtoi %S0, %D0',
864         attr_type => "sparc_fp_attr_t",
865         attr      => "ir_mode *fp_mode",
866         mode      => $mode_gp,
867         constructors => {
868                 s => {
869                         reg_req => { in => [ "fp" ], out => [ "fp" ] },
870                 },
871                 d => {
872                         reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
873                 },
874                 q => {
875                         reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
876                 },
877         },
878 },
879
880 Ldf => {
881         op_flags  => [ "uses_memory" ],
882         state     => "exc_pinned",
883         constructors => {
884                 s => {
885                         reg_req => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
886                 },
887                 d => {
888                         reg_req => { in => [ "gp", "none" ], out => [ "fp:a|2", "none" ] },
889                 },
890                 q => {
891                         reg_req => { in => [ "gp", "none" ], out => [ "fp:a|4", "none" ] },
892                 },
893         },
894         ins       => [ "ptr", "mem" ],
895         outs      => [ "res", "M" ],
896         attr_type => "sparc_load_store_attr_t",
897         attr      => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
898         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
899         emit      => 'ld%ML [%S0%O1], %D0'
900 },
901
902 Stf => {
903         op_flags  => [ "uses_memory" ],
904         state     => "exc_pinned",
905         constructors => {
906                 s => {
907                         reg_req => { in => [ "fp",     "gp", "none" ], out => [ "none" ] },
908                 },
909                 d => {
910                         reg_req => { in => [ "fp:a|2", "gp", "none" ], out => [ "none" ] },
911                 },
912                 q => {
913                         reg_req => { in => [ "fp:a|4", "gp", "none" ], out => [ "none" ] },
914                 },
915         },
916         ins       => [ "val", "ptr", "mem" ],
917         outs      => [ "M" ],
918         attr_type => "sparc_load_store_attr_t",
919         attr      => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
920         custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
921         emit      => 'st%MS %S0, [%S1%O2]',
922         mode      => 'mode_M',
923 },
924
925 ); # end of %nodes