Remove redundant reg_req from SPARC nodes with constructors.
[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 $normal      =  0; # no special type
14 $caller_save =  1; # caller save (register must be saved by the caller of a function)
15 $callee_save =  2; # callee save (register must be saved by the called function)
16 $ignore      =  4; # ignore (do not assign this register)
17 $arbitrary   =  8; # emitter can choose an arbitrary register of this class
18 $virtual     = 16; # the register is a virtual one
19 $state       = 32; # register represents a state
20
21 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
22 %reg_classes = (
23         gp => [
24                 { name => "g0", type => $ignore }, # hardwired 0, behaves like /dev/null
25                 { name => "g1", type => $caller_save }, # temp. value
26                 { name => "g2", type => $caller_save },
27                 { name => "g3", type => $caller_save },
28                 { name => "g4", type => $caller_save },
29                 { name => "g5", type => $ignore }, # reserved by SPARC ABI
30                 { name => "g6", type => $ignore }, # reserved by SPARC ABI
31                 { name => "g7", type => $ignore }, # reserved by SPARC ABI
32
33                 # window's out registers
34                 { name => "o0", type => $caller_save }, # param 1 / return value from callee
35                 { name => "o1", type => $caller_save }, # param 2
36                 { name => "o2", type => $caller_save }, # param 3
37                 { name => "o3", type => $caller_save }, # param 4
38                 { name => "o4", type => $caller_save }, # param 5
39                 { name => "o5", type => $caller_save }, # param 6
40                 { name => "sp", type => $ignore }, # our stackpointer
41                 { name => "o7", type => $ignore }, # temp. value / address of CALL instr.
42
43                 # window's local registers
44                 { name => "l0", type => 0 },
45                 { name => "l1", type => 0 },
46                 { name => "l2", type => 0 },
47                 { name => "l3", type => 0 },
48                 { name => "l4", type => 0 },
49                 { name => "l5", type => 0 },
50                 { name => "l6", type => 0 },
51                 { name => "l7", type => 0 },
52
53                 # window's in registers
54                 { name => "i0", type => 0 }, # incoming param1 / return value to caller
55                 { name => "i1", type => 0 }, # param 2
56                 { name => "i2", type => 0 }, # param 3
57                 { name => "i3", type => 0 }, # param 4
58                 { name => "i4", type => 0 }, # param 5
59                 { name => "i5", type => 0 }, # param 6
60                 { name => "frame_pointer", realname => "fp", type => $ignore }, # our framepointer
61                 { name => "i7", type => $ignore }, # return address - 8
62                 { mode => $mode_gp }
63         ],
64         fpflags_class => [
65                 { name => "fpflags", type => $ignore },
66                 { mode => $mode_fpflags, flags => "manual_ra" }
67         ],
68         flags_class => [
69                 { name => "flags", type => $ignore },
70                 { mode => $mode_flags, flags => "manual_ra" }
71         ],
72         mul_div_high_res => [
73                 { name => "y", type => $ignore },
74                 { mode => $mode_gp, flags => "manual_ra" }
75         ],
76         # fp registers can be accessed any time
77         fp => [
78                 { name => "f0",  type => $caller_save },
79                 { name => "f1",  type => $caller_save },
80                 { name => "f2",  type => $caller_save },
81                 { name => "f3",  type => $caller_save },
82                 { name => "f4",  type => $caller_save },
83                 { name => "f5",  type => $caller_save },
84                 { name => "f6",  type => $caller_save },
85                 { name => "f7",  type => $caller_save },
86                 { name => "f8",  type => $caller_save },
87                 { name => "f9",  type => $caller_save },
88                 { name => "f10", type => $caller_save },
89                 { name => "f11", type => $caller_save },
90                 { name => "f12", type => $caller_save },
91                 { name => "f13", type => $caller_save },
92                 { name => "f14", type => $caller_save },
93                 { name => "f15", type => $caller_save },
94                 { name => "f16", type => $caller_save },
95                 { name => "f17", type => $caller_save },
96                 { name => "f18", type => $caller_save },
97                 { name => "f19", type => $caller_save },
98                 { name => "f20", type => $caller_save },
99                 { name => "f21", type => $caller_save },
100                 { name => "f22", type => $caller_save },
101                 { name => "f23", type => $caller_save },
102                 { name => "f24", type => $caller_save },
103                 { name => "f25", type => $caller_save },
104                 { name => "f26", type => $caller_save },
105                 { name => "f27", type => $caller_save },
106                 { name => "f28", type => $caller_save },
107                 { name => "f29", type => $caller_save },
108                 { name => "f30", type => $caller_save },
109                 { name => "f31", type => $caller_save },
110                 { mode => $mode_fp }
111         ]
112 ); # %reg_classes
113
114 %emit_templates = (
115 # emit source reg or imm dep. on node's arity
116         RI  => "${arch}_emit_reg_or_imm(node, -1);",
117         R1I => "${arch}_emit_reg_or_imm(node, 0);",
118         R2I => "${arch}_emit_reg_or_imm(node, 1);",
119         R3I => "${arch}_emit_reg_or_imm(node, 2);",
120         S1  => "${arch}_emit_source_register(node, 0);",
121         S2  => "${arch}_emit_source_register(node, 1);",
122         S3  => "${arch}_emit_source_register(node, 2);",
123         S4  => "${arch}_emit_source_register(node, 3);",
124         S5  => "${arch}_emit_source_register(node, 4);",
125         S6  => "${arch}_emit_source_register(node, 5);",
126         D1  => "${arch}_emit_dest_register(node, 0);",
127         D2  => "${arch}_emit_dest_register(node, 1);",
128         D3  => "${arch}_emit_dest_register(node, 2);",
129         D4  => "${arch}_emit_dest_register(node, 3);",
130         D5  => "${arch}_emit_dest_register(node, 4);",
131         D6  => "${arch}_emit_dest_register(node, 5);",
132         IM  => "${arch}_emit_immediate(node);",
133         LM  => "${arch}_emit_load_mode(node);",
134         SM  => "${arch}_emit_store_mode(node);",
135         FLSM => "${arch}_emit_float_load_store_mode(node);",
136         FPM  => "${arch}_emit_fp_mode_suffix(node);",
137         FCONVS => "${arch}_emit_fp_conv_source(node);",
138         FCONVD => "${arch}_emit_fp_conv_destination(node);",
139         O      => "${arch}_emit_offset(node);",
140 );
141
142 $default_attr_type = "sparc_attr_t";
143 $default_copy_attr = "sparc_copy_attr";
144
145
146 %init_attr = (
147         sparc_attr_t             => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
148         sparc_load_store_attr_t  => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
149                                     "\tinit_sparc_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);",
150         sparc_symconst_attr_t    => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
151                                     "\tinit_sparc_symconst_attributes(res, entity);",
152         sparc_jmp_cond_attr_t    => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
153         sparc_jmp_switch_attr_t  => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
154         sparc_save_attr_t        => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
155         sparc_fp_attr_t          => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
156                                     "\tinit_sparc_fp_attributes(res, fp_mode);\n",
157         sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);".
158                                     "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
159 );
160
161 %compare_attr = (
162         sparc_attr_t            => "cmp_attr_sparc",
163         sparc_load_store_attr_t => "cmp_attr_sparc_load_store",
164         sparc_symconst_attr_t   => "cmp_attr_sparc_symconst",
165         sparc_jmp_cond_attr_t   => "cmp_attr_sparc_jmp_cond",
166         sparc_jmp_switch_attr_t => "cmp_attr_sparc_jmp_switch",
167         sparc_save_attr_t       => "cmp_attr_sparc_save",
168         sparc_fp_attr_t         => "cmp_attr_sparc_fp",
169         sparc_fp_conv_attr_t    => "cmp_attr_sparc_fp_conv",
170 );
171
172 %custom_irn_flags = (
173         modifies_flags    => "sparc_arch_irn_flag_modifies_flags",
174         modifies_fp_flags => "sparc_arch_irn_flag_modifies_fp_flags",
175 );
176
177 # addressing modes: imm, reg, reg +/- imm, reg + reg
178 # max. imm = 13 bits signed (-4096 ... 4096)
179
180 my %cmp_operand_constructors = (
181         imm => {
182                 attr       => "int immediate_value",
183                 custominit => "sparc_set_attr_imm(res, immediate_value);",
184                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
185                 ins        => [ "left" ],
186         },
187         reg => {
188                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
189                 ins        => [ "left", "right" ],
190         },
191 );
192
193 my %unop_operand_constructors = (
194         imm => {
195                 attr       => "int immediate_value",
196                 custominit => "sparc_set_attr_imm(res, immediate_value);",
197                 reg_req    => { in => [], out => [ "gp" ] },
198         },
199         reg => {
200                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
201         },
202 );
203
204 my %binop_operand_constructors = (
205         imm => {
206                 attr       => "int immediate_value",
207                 custominit => "sparc_set_attr_imm(res, immediate_value);",
208                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
209                 ins        => [ "left" ],
210         },
211         reg => {
212                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
213                 ins        => [ "left", "right" ],
214         },
215 );
216
217 my %float_binop_constructors = (
218         s => {
219                 reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
220                 ins     => [ "left", "right" ],
221                 mode    => $mode_fp,
222         },
223         d => {
224                 reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2" ] },
225                 ins     => [ "left", "right" ],
226                 mode    => $mode_fp2,
227         },
228         q => {
229                 reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4" ] },
230                 ins     => [ "left", "right" ],
231                 mode    => $mode_fp4,
232         }
233 );
234
235 %nodes = (
236
237 Add => {
238         irn_flags    => [ "rematerializable" ],
239         mode         => $mode_gp,
240         emit         => '. add %S1, %R2I, %D1',
241         constructors => \%binop_operand_constructors,
242 },
243
244 Sub => {
245         irn_flags    => [ "rematerializable" ],
246         mode         => $mode_gp,
247         emit         => '. sub %S1, %R2I, %D1',
248         constructors => \%binop_operand_constructors,
249 },
250
251
252 # Load / Store
253 Ld => {
254         op_flags  => [ "labeled", "fragile" ],
255         state     => "exc_pinned",
256         constructors => {
257                 "" => {
258                         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
259                 },
260                 d => {
261                         reg_req => { in => [ "gp", "none" ], out => [ "gp:a|2", "none" ] },
262                 },
263         },
264         outs      => [ "res", "M" ],
265         ins       => [ "ptr", "mem" ],
266         attr_type => "sparc_load_store_attr_t",
267         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
268         emit      => '. ld%LM [%S1%O], %D1'
269 },
270
271 HiImm => {
272         irn_flags => [ "rematerializable" ],
273         state     => "exc_pinned",
274         outs      => [ "res" ],
275         mode      => $mode_gp,
276         reg_req   => { in => [], out => [ "gp" ] },
277         attr       => "int immediate_value",
278         custominit => "sparc_set_attr_imm(res, immediate_value);",
279 },
280
281 LoImm => {
282         irn_flags => [ "rematerializable" ],
283         state     => "exc_pinned",
284         ins       => [ "hireg" ],
285         outs      => [ "res" ],
286         mode      => $mode_gp,
287         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
288         attr       => "int immediate_value",
289         custominit => "sparc_set_attr_imm(res, immediate_value);",
290 },
291
292 St => {
293         op_flags  => [ "labeled", "fragile" ],
294         mode      => "mode_M",
295         state     => "exc_pinned",
296         constructors => {
297                 "" => {
298                         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
299                 },
300                 d => {
301                         reg_req   => { in => [ "gp", "gp:a|2", "none" ], out => [ "none" ] },
302                 },
303         },
304         ins       => [ "ptr", "val", "mem" ],
305         outs      => [ "M" ],
306         attr_type => "sparc_load_store_attr_t",
307         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
308         emit      => '. st%SM %S2, [%S1%O]'
309 },
310
311 Mov => {
312         irn_flags => [ "rematerializable" ],
313         arity     => "variable",
314         emit      => '. mov %R1I, %D1',
315         mode      => $mode_gp,
316         constructors => \%unop_operand_constructors,
317 },
318
319 Save => {
320         reg_req   => {
321                 in => [ "sp", "none"],
322                 out => [ "sp:I|S", "frame_pointer:I", "none" ]
323         },
324         ins       => [ "stack", "mem" ],
325         outs      => [ "stack", "frame", "mem" ],
326         attr      => "int initial_stacksize",
327         attr_type => "sparc_save_attr_t",
328         init_attr => "\tinit_sparc_save_attributes(res, initial_stacksize);",
329 },
330
331 SubSP => {
332         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
333         ins       => [ "stack", "size", "mem" ],
334         outs      => [ "stack", "addr", "M" ],
335         emit      => ". sub %S1, %S2, %D1\n",
336 },
337
338 AddSP => {
339         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
340         ins       => [ "stack", "size", "mem" ],
341         outs      => [ "stack", "M" ],
342         emit      => ". add %S1, %S2, %D1\n",
343 },
344
345 SymConst => {
346         op_flags  => [ "constlike" ],
347         irn_flags => [ "rematerializable" ],
348         attr      => "ir_entity *entity",
349         reg_req   => { out => [ "gp" ] },
350         attr_type => "sparc_symconst_attr_t",
351         mode      => $mode_gp,
352 },
353
354 FrameAddr => {
355         op_flags  => [ "constlike" ],
356         irn_flags => [ "rematerializable" ],
357         attr      => "ir_entity *entity",
358         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
359         ins       => [ "base" ],
360         attr_type => "sparc_symconst_attr_t",
361         mode      => $mode_gp,
362 },
363
364 Bicc => {
365         op_flags  => [ "labeled", "cfopcode", "forking" ],
366         state     => "pinned",
367         mode      => "mode_T",
368         attr_type => "sparc_jmp_cond_attr_t",
369         attr      => "pn_Cmp pnc, bool is_unsigned",
370         init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, is_unsigned);",
371         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
372 },
373
374 fbfcc => {
375         op_flags  => [ "labeled", "cfopcode", "forking" ],
376         state     => "pinned",
377         mode      => "mode_T",
378         attr_type => "sparc_jmp_cond_attr_t",
379         attr      => "pn_Cmp pnc",
380         init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, false);",
381         reg_req   => { in => [ "fpflags" ], out => [ "none", "none" ] },
382 },
383
384 Ba => {
385         state     => "pinned",
386         op_flags  => [ "cfopcode" ],
387         irn_flags => [ "simple_jump" ],
388         reg_req   => { out => [ "none" ] },
389         mode      => "mode_X",
390 },
391
392 Call => {
393         irn_flags => [ "modifies_flags", "modifies_fp_flags" ],
394         state     => "exc_pinned",
395         arity     => "variable",
396         out_arity => "variable",
397         constructors => {
398                 imm => {
399                         attr       => "ir_entity *entity, long offset",
400                         custominit => "get_sparc_attr(res)->immediate_value_entity = entity;",
401                         arity     => "variable",
402                         out_arity => "variable",
403                 },
404                 reg => {
405                         arity     => "variable",
406                         out_arity => "variable",
407                 }
408         },
409 },
410
411 Cmp => {
412         irn_flags    => [ "rematerializable", "modifies_flags" ],
413         emit         => '. cmp %S1, %R2I',
414         ins          => [ "left", "right" ],
415         mode         => $mode_flags,
416         constructors => \%cmp_operand_constructors,
417 },
418
419 Tst => {
420         irn_flags    => [ "rematerializable", "modifies_flags" ],
421         emit         => '. tst %S1',
422         mode         => $mode_flags,
423         reg_req      => { in => [ "gp" ], out => [ "flags" ] },
424         ins          => [ "val" ],
425 },
426
427 SwitchJmp => {
428         op_flags  => [ "labeled", "cfopcode", "forking" ],
429         irn_flags => [ "modifies_flags" ],
430         state     => "pinned",
431         mode      => "mode_T",
432         attr      => "int n_projs, long def_proj_num",
433         init_attr => "\tset_sparc_jmp_switch_n_projs(res, n_projs);\n".
434                                         "\tset_sparc_jmp_switch_default_proj_num(res, def_proj_num);",
435         reg_req   => { in => [ "gp" ], out => [ "none" ] },
436         attr_type => "sparc_jmp_switch_attr_t",
437 },
438
439 Sll => {
440         irn_flags    => [ "rematerializable" ],
441         mode         => $mode_gp,
442         emit         => '. sll %S1, %R2I, %D1',
443         constructors => \%binop_operand_constructors,
444 },
445
446 Slr => {
447         irn_flags    => [ "rematerializable" ],
448         mode         => $mode_gp,
449         emit         => '. srl %S1, %R2I, %D1',
450         constructors => \%binop_operand_constructors,
451 },
452
453 Sra => {
454         irn_flags    => [ "rematerializable" ],
455         mode         => $mode_gp,
456         emit         => '. sra %S1, %R2I, %D1',
457         constructors => \%binop_operand_constructors,
458 },
459
460 And => {
461         irn_flags    => [ "rematerializable" ],
462         mode         => $mode_gp,
463         emit         => '. and %S1, %R2I, %D1',
464         constructors => \%binop_operand_constructors,
465 },
466
467 Or => {
468         irn_flags    => [ "rematerializable" ],
469         mode         => $mode_gp,
470         emit         => '. or %S1, %R2I, %D1',
471         constructors => \%binop_operand_constructors,
472 },
473
474 Xor => {
475         irn_flags    => [ "rematerializable" ],
476         mode         => $mode_gp,
477         emit         => '. xor %S1, %R2I, %D1',
478         constructors => \%binop_operand_constructors,
479 },
480
481 Mul => {
482         mode         => $mode_gp,
483         emit         => '. smul %S1, %R2I, %D1',
484         constructors => \%binop_operand_constructors,
485 },
486
487 Mulh => {
488         outs         => [ "low", "high" ],
489         constructors => \%binop_operand_constructors,
490 },
491
492 # The div instructions are kinda hacky. Things to improve:
493 # * Make high-value input explicitely. Either as a gp at first or ideally
494 #   as an explicit y-register
495
496 SDiv => {
497         irn_flags    => [ "rematerializable" ],
498         state        => "exc_pinned",
499         ins          => [ "dividend_low", "divisor" ],
500         outs         => [ "res", "M" ],
501         constructors => \%binop_operand_constructors,
502 },
503
504 UDiv => {
505         irn_flags    => [ "rematerializable" ],
506         state        => "exc_pinned",
507         ins          => [ "dividend_low", "divisor" ],
508         outs         => [ "res", "M" ],
509         constructors => \%binop_operand_constructors,
510 },
511
512 Minus => {
513         irn_flags => [ "rematerializable" ],
514         mode      => $mode_gp,
515         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
516         emit      => ". sub %%g0, %S1, %D1"
517 },
518
519 Not => {
520         irn_flags => [ "rematerializable" ],
521         mode      => $mode_gp,
522         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
523         emit      => '. xnor %S1, %%g0, %D1'
524 },
525
526 Nop => {
527         op_flags => [ "keep" ],
528         reg_req  => { in => [], out => [ "none" ] },
529         emit     => '. nop',
530 },
531
532 fcmp => {
533         irn_flags => [ "rematerializable", "modifies_fp_flags" ],
534         reg_req   => { in => [ "fp", "fp" ], out => [ "fpflags" ] },
535         emit      => '. fcmp%FPM %S1, %S2',
536         attr_type => "sparc_fp_attr_t",
537         attr      => "ir_mode *fp_mode",
538         mode      => $mode_fpflags,
539 },
540
541 fadd => {
542         op_flags     => [ "commutative" ],
543         irn_flags    => [ "rematerializable" ],
544         emit         => '. fadd%FPM %S1, %S2, %D1',
545         attr_type    => "sparc_fp_attr_t",
546         attr         => "ir_mode *fp_mode",
547         constructors => \%float_binop_constructors,
548 },
549
550 fsub => {
551         irn_flags    => [ "rematerializable" ],
552         emit         => '. fsub%FPM %S1, %S2, %D1',
553         attr_type    => "sparc_fp_attr_t",
554         attr         => "ir_mode *fp_mode",
555         constructors => \%float_binop_constructors,
556 },
557
558 fmul => {
559         irn_flags    => [ "rematerializable" ],
560         op_flags     => [ "commutative" ],
561         emit         =>'. fmul%FPM %S1, %S2, %D1',
562         attr_type    => "sparc_fp_attr_t",
563         attr         => "ir_mode *fp_mode",
564         constructors => \%float_binop_constructors,
565 },
566
567 fdiv => {
568         irn_flags    => [ "rematerializable" ],
569         emit         => '. fdiv%FPM %S1, %S2, %D1',
570         attr_type    => "sparc_fp_attr_t",
571         attr         => "ir_mode *fp_mode",
572         outs         => [ "res", "M" ],
573         constructors => \%float_binop_constructors,
574 },
575
576 fneg => {
577         irn_flags => [ "rematerializable" ],
578         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
579         emit      => '. fneg%FPM %S1, %D1',
580         attr_type => "sparc_fp_attr_t",
581         attr      => "ir_mode *fp_mode",
582         mode      => $mode_fp,
583 },
584
585 "fabs" => {
586         irn_flags    => [ "rematerializable" ],
587         emit         => '. fabs%FPM %S1, %D1',
588         attr_type    => "sparc_fp_attr_t",
589         attr         => "ir_mode *fp_mode",
590         constructors => \%float_binop_constructors,
591 },
592
593 fftof => {
594         irn_flags => [ "rematerializable" ],
595         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
596         emit      => '. f%FCONVS%.to%FCONVD %S1, %D1',
597         attr_type => "sparc_fp_conv_attr_t",
598         attr      => "ir_mode *src_mode, ir_mode *dest_mode",
599         mode      => $mode_fp,
600 },
601
602 fitof => {
603         irn_flags => [ "rematerializable" ],
604         reg_req   => { in => [ "gp" ], out => [ "fp" ] },
605         emit      => '. fito%FPM %S1, %D1',
606         attr_type => "sparc_fp_attr_t",
607         attr      => "ir_mode *fp_mode",
608         mode      => $mode_fp,
609 },
610
611 fftoi => {
612         irn_flags => [ "rematerializable" ],
613         reg_req   => { in => [ "fp" ], out => [ "gp" ] },
614         emit      => '. f%FPM.toi %S1, %D1',
615         attr_type => "sparc_fp_attr_t",
616         attr      => "ir_mode *fp_mode",
617         mode      => $mode_gp,
618 },
619
620 Ldf => {
621         op_flags  => [ "labeled", "fragile" ],
622         state     => "exc_pinned",
623         ins       => [ "ptr", "mem" ],
624         outs      => [ "res", "M" ],
625         reg_req   => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
626         attr_type => "sparc_load_store_attr_t",
627         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
628         emit      => '. ld%FLSM [%S1%O], %D1'
629 },
630
631 Stf => {
632         op_flags  => [ "labeled", "fragile" ],
633         state     => "exc_pinned",
634         ins       => [ "ptr", "val", "mem" ],
635         outs      => [ "M" ],
636         reg_req   => { in => [ "gp", "fp", "none" ], out => [ "none" ] },
637         attr_type => "sparc_load_store_attr_t",
638         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
639         emit      => '. st%FLSM %S2, [%S1%O]',
640         mode      => 'mode_M',
641 },
642
643 ); # end of %nodes