d24c4bea7e0664f6e6bdeed78f170b24c104fa35
[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_fp      = "mode_D";
9
10 # The node description is done as a perl hash initializer with the
11 # following structure:
12 #
13 # %nodes = (
14 #
15 # <op-name> => {
16 #   arity     => "0|1|2|3 ... |variable|dynamic|any",   # optional
17 #   state     => "floats|pinned|mem_pinned|exc_pinned", # optional
18 #   args      => [
19 #                    { type => "type 1", name => "name 1" },
20 #                    { type => "type 2", name => "name 2" },
21 #                    ...
22 #                  ],
23 #   comment   => "any comment for constructor",  # optional
24 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
25 #   cmp_attr  => "c source code for comparing node attributes", # optional
26 #   outs      => { "out1", "out2" },# optional, creates pn_op_out1, ... consts
27 #   ins       => { "in1", "in2" },  # optional, creates n_op_in1, ... consts
28 #   mode      => "mode_Iu",         # optional, predefines the mode
29 #   emit      => "emit code with templates",   # optional for virtual nodes
30 #   attr      => "additional attribute arguments for constructor", # optional
31 #   init_attr => "emit attribute initialization template",         # optional
32 #   rd_constructor => "c source code which constructs an ir_node", # optional
33 #   hash_func => "name of the hash function for this operation",   # optional, get the default hash function else
34 #   latency   => "latency of this operation (can be float)"        # optional
35 #   attr_type => "name of the attribute struct",                   # optional
36 # },
37 #
38 # ... # (all nodes you need to describe)
39 #
40 # ); # close the %nodes initializer
41
42 # state: state of the operation, OPTIONAL (default is "floats")
43 #
44 # arity: arity of the operation, MUST NOT BE OMITTED
45 #
46 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
47 #        are always the first 3 arguments and are always autmatically
48 #        created)
49 #        If this key is missing the following arguments will be created:
50 #        for i = 1 .. arity: ir_node *op_i
51 #        ir_mode *mode
52 #
53 # outs:  if a node defines more than one output, the names of the projections
54 #        nodes having outs having automatically the mode mode_T
55 #
56 # comment: OPTIONAL comment for the node constructor
57 #
58 # register types:
59 #   0 - no special type
60 #   1 - caller save (register must be saved by the caller of a function)
61 #   2 - callee save (register must be saved by the called function)
62 #   4 - ignore (do not assign this register)
63 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
64
65 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
66 %reg_classes = (
67         gp => [
68                 { name => "g0", realname => "g0", type => 4 }, # hardwired 0, behaves like /dev/null
69                 { name => "g1", realname => "g1", type => 1 }, # temp. value
70                 { name => "g2", realname => "g2", type => 1 },
71                 { name => "g3", realname => "g3", type => 1 },
72                 { name => "g4", realname => "g4", type => 1 },
73                 { name => "g5", realname => "g5", type => 4 }, # reserved by SPARC ABI
74                 { name => "g6", realname => "g6", type => 4 }, # reserved by SPARC ABI
75                 { name => "g7", realname => "g7", type => 4 }, # reserved by SPARC ABI
76
77                 # window's out registers
78                 { name => "o0", realname => "o0", type => 1 }, # param 1 / return value from callee
79                 { name => "o1", realname => "o1", type => 1 }, # param 2
80                 { name => "o2", realname => "o2", type => 1 }, # param 3
81                 { name => "o3", realname => "o3", type => 1 }, # param 4
82                 { name => "o4", realname => "o4", type => 1 }, # param 5
83                 { name => "o5", realname => "o5", type => 1 }, # param 6
84                 { name => "sp", realname => "sp", type => 4 }, # our stackpointer
85                 { name => "o7", realname => "o6", type => 4 }, # temp. value / address of CALL instr.
86
87                 # window's local registers
88                 { name => "l0", realname => "l0", type => 0 },
89                 { name => "l1", realname => "l1", type => 0 },
90                 { name => "l2", realname => "l2", type => 0 },
91                 { name => "l3", realname => "l3", type => 0 },
92                 { name => "l4", realname => "l4", type => 0 },
93                 { name => "l5", realname => "l5", type => 0 },
94                 { name => "l6", realname => "l6", type => 0 },
95                 { name => "l7", realname => "l7", type => 0 },
96
97                 # window's in registers
98                 { name => "i0", realname => "i0", type => 0 }, # incoming param1 / return value to caller
99                 { name => "i1", realname => "i1", type => 0 }, # param 2
100                 { name => "i2", realname => "i2", type => 0 }, # param 3
101                 { name => "i3", realname => "i3", type => 0 }, # param 4
102                 { name => "i4", realname => "i4", type => 0 }, # param 5
103                 { name => "i5", realname => "i5", type => 0 }, # param 6
104                 { name => "fp", realname => "fp", type => 4 }, # our framepointer
105                 { name => "i7", realname => "i7", type => 4 }, # return address - 8
106                 { mode => $mode_gp }
107         ],
108         flags => [
109                 { name => "y", realname => "y", type => 4 },  # the multiply/divide state register
110                 { mode => $mode_flags, flags => "manual_ra" }
111         ],
112 #       cpu => [
113 #               { name => "psr", realname => "psr", type => 4 },  # the processor state register
114 #               { name => "wim", realname => "wim", type => 4 },  # the window invalid mask register
115 #               { name => "tbr", realname => "tbr", type => 4 },  # the trap base register
116 #               { name => "pc", realname => "pc", type => 4 },  # the program counter register
117 #               { name => "npc", realname => "npc", type => 4 },  # the next instruction addr. (PC + 1) register
118 #               { mode => "mode_Iu", flags => "manual_ra" }
119 #       ],
120
121         # fp registers can be accessed any time
122         fp  => [
123                 { name => "f0", type => 1 },
124                 { name => "f1", type => 1 },
125                 { name => "f2", type => 1 },
126                 { name => "f3", type => 1 },
127                 { name => "f4", type => 1 },
128                 { name => "f5", type => 1 },
129                 { name => "f6", type => 1 },
130                 { name => "f7", type => 1 },
131                 { name => "f8", type => 1 },
132                 { name => "f9", type => 1 },
133                 { name => "f10", type => 1 },
134                 { name => "f11", type => 1 },
135                 { name => "f12", type => 1 },
136                 { name => "f13", type => 1 },
137                 { name => "f14", type => 1 },
138                 { name => "f15", type => 1 },
139                 { name => "f16", type => 1 },
140                 { name => "f17", type => 1 },
141                 { name => "f18", type => 1 },
142                 { name => "f19", type => 1 },
143                 { name => "f20", type => 1 },
144                 { name => "f21", type => 1 },
145                 { name => "f22", type => 1 },
146                 { name => "f23", type => 1 },
147                 { name => "f24", type => 1 },
148                 { name => "f25", type => 1 },
149                 { name => "f26", type => 1 },
150                 { name => "f27", type => 1 },
151                 { name => "f28", type => 1 },
152                 { name => "f29", type => 1 },
153                 { name => "f30", type => 1 },
154                 { name => "f31", type => 1 },
155                 { mode => $mode_fp }
156         ]
157 ); # %reg_classes
158
159 %emit_templates = (
160 # emit source reg or imm dep. on node's arity
161     RI => "${arch}_emit_reg_or_imm(node, -1);",
162     R1I => "${arch}_emit_reg_or_imm(node, 0);",
163     R2I => "${arch}_emit_reg_or_imm(node, 1);",
164     R3I => "${arch}_emit_reg_or_imm(node, 2);",
165 # simple reg emitters
166     S1 => "${arch}_emit_source_register(node, 0);",
167     S2 => "${arch}_emit_source_register(node, 1);",
168     S3 => "${arch}_emit_source_register(node, 2);",
169     S4 => "${arch}_emit_source_register(node, 3);",
170     S5 => "${arch}_emit_source_register(node, 4);",
171     S6 => "${arch}_emit_source_register(node, 5);",
172     D1 => "${arch}_emit_dest_register(node, 0);",
173     D2 => "${arch}_emit_dest_register(node, 1);",
174     D3 => "${arch}_emit_dest_register(node, 2);",
175     D4 => "${arch}_emit_dest_register(node, 3);",
176     D5 => "${arch}_emit_dest_register(node, 4);",
177     D6 => "${arch}_emit_dest_register(node, 5);",
178 # more custom emitters
179         C  => "${arch}_emit_immediate(node);",
180         LM  => "${arch}_emit_load_mode(node);",
181         SM  => "${arch}_emit_store_mode(node);",
182         EXTPREF  => "${arch}_emit_mode_sign_prefix(node);",
183         FPM  => "${arch}_emit_fp_mode_suffix(node);",
184         FPLM  => "${arch}_emit_fp_load_mode(node);",
185         FPSM  => "${arch}_emit_fp_store_mode(node);",
186         O  => "${arch}_emit_offset(node);",
187 );
188
189 $default_attr_type = "sparc_attr_t";
190 $default_copy_attr = "sparc_copy_attr";
191
192
193 %init_attr = (
194                 sparc_attr_t                            => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
195                 sparc_load_store_attr_t                 => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
196                                                                                         "\tinit_sparc_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);",
197                 sparc_symconst_attr_t                   => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
198                                                                 "\tinit_sparc_symconst_attributes(res, entity);",
199                 sparc_cmp_attr_t                        => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n",
200                 sparc_jmp_cond_attr_t                   => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
201                 sparc_jmp_switch_attr_t                 => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
202                 sparc_save_attr_t                       => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
203
204 );
205
206 %compare_attr = (
207                 sparc_attr_t            => "cmp_attr_sparc",
208                 sparc_load_store_attr_t => "cmp_attr_sparc_load_store",
209                 sparc_symconst_attr_t   => "cmp_attr_sparc_symconst",
210                 sparc_jmp_cond_attr_t   => "cmp_attr_sparc_jmp_cond",
211                 sparc_jmp_switch_attr_t => "cmp_attr_sparc_jmp_switch",
212                 sparc_cmp_attr_t        => "cmp_attr_sparc_cmp",
213                 sparc_save_attr_t       => "cmp_attr_sparc_save",
214 );
215
216
217 # addressing modes: imm, reg, reg +/- imm, reg + reg
218 # max. imm = 13 bits signed (-4096 ... 4096)
219
220
221 my %cmp_operand_constructors = (
222     imm => {
223         attr       => "int immediate_value, bool ins_permuted, bool is_unsigned",
224         custominit => "sparc_set_attr_imm(res, immediate_value);" .
225                                                 "\tinit_sparc_cmp_attr(res, ins_permuted, is_unsigned);",
226         reg_req    => { in => [ "gp" ], out => [ "flags" ] },
227         ins        => [ "left" ],
228     },
229     reg => {
230         attr       => "bool ins_permuted, bool is_unsigned",
231         custominit => "init_sparc_cmp_attr(res, ins_permuted, is_unsigned);",
232         reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
233         ins        => [ "left", "right" ],
234     },
235 );
236
237 my %unop_operand_constructors = (
238     imm => {
239         attr       => "int immediate_value",
240         custominit => "sparc_set_attr_imm(res, immediate_value);",
241         reg_req    => { in => [], out => [ "gp" ] },
242     },
243     reg => {
244         reg_req    => { in => [ "gp" ], out => [ "gp" ] },
245     },
246 );
247
248 my %binop_operand_constructors = (
249     imm => {
250         attr       => "int immediate_value",
251         custominit => "sparc_set_attr_imm(res, immediate_value);",
252         reg_req    => { in => [ "gp" ], out => [ "gp" ] },
253         ins        => [ "left" ],
254     },
255     reg => {
256         reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
257         ins        => [ "left", "right" ],
258     },
259 );
260
261 %nodes = (
262
263 Add => {
264   irn_flags => [ "rematerializable" ],
265   comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
266   mode          => $mode_gp,
267   emit      => '. add %S1, %R2I, %D1',
268   constructors => \%binop_operand_constructors,
269 },
270
271 Sub => {
272   irn_flags => [ "rematerializable" ],
273   comment   => "construct Sub: Sub(a, b) = a - b",
274   mode          => $mode_gp,
275   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
276   emit      => '. sub %S1, %R2I, %D1',
277   constructors => \%binop_operand_constructors,
278 },
279
280
281 # Load / Store
282 Load => {
283   op_flags  => [ "labeled", "fragile" ],
284   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
285   state     => "exc_pinned",
286   ins       => [ "ptr", "mem" ],
287   outs      => [ "res", "M" ],
288   reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
289   attr_type => "sparc_load_store_attr_t",
290   attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
291   emit      => '. ld%LM [%S1%O], %D1'
292 },
293
294 LoadHi => {
295   op_flags  => [ "labeled", "fragile" ],
296   comment   => "construct LoadHi: Load(ptr, mem) = sethi hi(ptr) -> reg",
297   state     => "exc_pinned",
298   ins       => [ "ptr", "mem" ],
299   outs      => [ "res", "M" ],
300   reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
301   attr_type => "sparc_load_store_attr_t",
302   attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
303   emit      => '. sethi %%hi(%S1), %D1',
304 },
305
306 HiImm => {
307   irn_flags => [ "rematerializable" ],
308   comment   => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
309   state     => "exc_pinned",
310   outs      => [ "res" ],
311   mode      => $mode_gp,
312   reg_req   => { in => [], out => [ "gp" ] },
313   #attr_type => "sparc_load_store_attr_t",
314   attr       => "int immediate_value",
315   custominit => "sparc_set_attr_imm(res, immediate_value);",
316
317 },
318
319 LoImm => {
320   irn_flags => [ "rematerializable" ],
321   comment   => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
322   state     => "exc_pinned",
323   ins       => [ "hireg" ],
324   outs      => [ "res" ],
325   mode      => $mode_gp,
326   reg_req   => { in => [ "gp" ], out => [ "gp" ] },
327   #attr_type => "sparc_load_store_attr_t",
328   attr       => "int immediate_value",
329   custominit => "sparc_set_attr_imm(res, immediate_value);",
330
331 },
332
333 LoadLo => {
334   op_flags  => [ "labeled", "fragile" ],
335   comment   => "construct LoadLo: Or(in, ptr, mem) = or in lo(ptr) -> reg",
336   state     => "exc_pinned",
337   ins       => [ "hireg", "ptr", "mem" ],
338   outs      => [ "res", "M" ],
339   reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
340   attr_type => "sparc_load_store_attr_t",
341   attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
342   emit      => '. or %S1, %%lo(%S2), %D1'
343 },
344
345 Store => {
346   op_flags  => [ "labeled", "fragile" ],
347   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
348   mode          => "mode_M",
349   state     => "exc_pinned",
350   ins       => [ "ptr", "val", "mem" ],
351   outs      => [ "mem" ],
352   reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
353   attr_type => "sparc_load_store_attr_t",
354   attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
355   emit      => '. st%SM %S2, [%S1%O]'
356 },
357
358 Mov => {
359   irn_flags => [ "rematerializable" ],
360   comment   => "construct Mov: Mov(src, dest) = MV src,dest",
361   arity     => "variable",
362   emit      => '. mov %R1I, %D1',
363   mode      => $mode_gp,
364   constructors => \%unop_operand_constructors,
365 },
366
367 Save => {
368         comment => "function prolog instruction. autom. saves sp & shifts the register window. previous out regs become the new in regs",
369         reg_req   => {
370                         in => [ "sp", "none"],
371                         out => [ "sp:I|S","none" ]
372         },
373         ins       => [ "stack", "mem" ],
374         outs      => [ "stack", "mem" ],
375         attr      => "int initial_stacksize",
376         attr_type => "sparc_save_attr_t",
377         init_attr => "\tinit_sparc_save_attr(res, initial_stacksize);",
378 },
379
380 AddSP => {
381         comment => "alloc stack space",
382         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
383         ins       => [ "stack", "size", "mem" ],
384         outs      => [ "stack", "addr", "M" ],
385         emit      => ". sub %S1, %S2, %D1\n",
386 },
387
388 SubSP => {
389         comment => "free stack space",
390         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
391         ins       => [ "stack", "size", "mem" ],
392         outs      => [ "stack", "M" ],
393         emit      => ". add %S1, %S2, %D1\n",
394 },
395
396 SymConst => {
397         op_flags  => [ "constlike" ],
398         irn_flags => [ "rematerializable" ],
399         attr      => "ir_entity *entity",
400         reg_req   => { out => [ "gp" ] },
401         attr_type => "sparc_symconst_attr_t",
402         mode      => $mode_gp,
403 },
404
405 FrameAddr => {
406         op_flags  => [ "constlike" ],
407         irn_flags => [ "rematerializable" ],
408         attr      => "ir_entity *entity",
409         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
410         ins       => [ "base" ],
411         attr_type => "sparc_symconst_attr_t",
412         mode      => $mode_gp,
413 },
414
415 Branch => {
416         op_flags  => [ "labeled", "cfopcode", "forking" ],
417         state     => "pinned",
418         mode      => "mode_T",
419         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
420         attr      => "int proj_num",
421         attr_type => "sparc_jmp_cond_attr_t",
422         init_attr => "\tset_sparc_jmp_cond_proj_num(res, proj_num);",
423 },
424
425 Jmp => {
426         state     => "pinned",
427         op_flags  => [ "cfopcode" ],
428         irn_flags => [ "simple_jump" ],
429         reg_req   => { out => [ "none" ] },
430         mode      => "mode_X",
431 },
432
433 Cmp => {
434         irn_flags    => [ "rematerializable", "modify_flags" ],
435         emit         => '. cmp %S1, %R2I',
436         mode         => $mode_flags,
437         attr_type    => "sparc_cmp_attr_t",
438         constructors => \%cmp_operand_constructors,
439 },
440
441 Tst => {
442         irn_flags    => [ "rematerializable", "modify_flags" ],
443         emit         => '. tst %S1',
444         mode         => $mode_flags,
445         attr_type    => "sparc_cmp_attr_t",
446         attr         => "bool ins_permuted, bool is_unsigned",
447         custominit   => "init_sparc_cmp_attr(res, ins_permuted, is_unsigned);",
448         reg_req      => { in => [ "gp" ], out => [ "flags" ] },
449         ins          => [ "left" ],
450 },
451
452 SwitchJmp => {
453         op_flags  => [ "labeled", "cfopcode", "forking" ],
454         state     => "pinned",
455         mode      => "mode_T",
456         attr      => "int n_projs, long def_proj_num",
457         init_attr => "\tset_sparc_jmp_switch_n_projs(res, n_projs);\n".
458                                         "\tset_sparc_jmp_switch_default_proj_num(res, def_proj_num);",
459         reg_req   => { in => [ "gp" ], out => [ "none" ] },
460         attr_type => "sparc_jmp_switch_attr_t",
461 },
462
463 ShiftLL => {
464   irn_flags => [ "rematerializable" ],
465   comment   => "construct shift logical left",
466   mode          => $mode_gp,
467   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
468   emit      => '. sll %S1, %R2I, %D1',
469   constructors => \%binop_operand_constructors,
470 },
471
472 ShiftLR => {
473   irn_flags => [ "rematerializable" ],
474   comment   => "construct shift logical right",
475   mode          => $mode_gp,
476   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
477   emit      => '. srl %S1, %R2I, %D1',
478   constructors => \%binop_operand_constructors,
479 },
480
481 ShiftRA => {
482   irn_flags => [ "rematerializable" ],
483   comment   => "construct shift right arithmetical",
484   mode          => $mode_gp,
485   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
486   emit      => '. sra %S1, %R2I, %D1',
487   constructors => \%binop_operand_constructors,
488 },
489
490 And => {
491   irn_flags => [ "rematerializable" ],
492   comment   => "construct logical and",
493   mode          => $mode_gp,
494   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
495   emit      => '. and %S1, %R2I, %D1',
496   constructors => \%binop_operand_constructors,
497 },
498
499 Or => {
500   irn_flags => [ "rematerializable" ],
501   comment   => "construct logical or",
502   mode          => $mode_gp,
503   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
504   emit      => '. or %S1, %R2I, %D1',
505   constructors => \%binop_operand_constructors,
506 },
507
508 Xor => {
509   irn_flags => [ "rematerializable" ],
510   comment   => "construct logical xor",
511   mode          => $mode_gp,
512   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
513   emit      => '. xor %S1, %R2I, %D1',
514   constructors => \%binop_operand_constructors,
515 },
516
517 Mul => {
518   state     => "exc_pinned",
519   comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
520   reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
521   outs      => [ "low", "high" ],
522   constructors => \%binop_operand_constructors,
523 #  emit      =>'. mul %S1, %R2I, %D1'
524 },
525
526 Mulh => {
527   state     => "exc_pinned",
528   comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
529   reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
530   outs      => [ "low", "high" ],
531   constructors => \%binop_operand_constructors,
532 },
533
534 Div => {
535   irn_flags => [ "rematerializable" ],
536   state     => "exc_pinned",
537 #  mode     => $mode_gp,
538   comment   => "construct Div: Div(a, b) = a / b",
539   reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
540   outs      => [ "res" ],
541   constructors => \%binop_operand_constructors,
542 #  emit      =>'. div %S1, %R2I, %D1'
543 },
544
545 Minus => {
546   irn_flags => [ "rematerializable" ],
547   mode      => $mode_gp,
548   comment   => "construct Minus: Minus(a) = -a",
549   #reg_req   => { in => [ "gp" ], out => [ "in_r1" ] },
550   reg_req   => { in => [ "gp" ], out => [ "gp" ] },
551   emit      => ". sub %%g0, %S1, %D1"
552 },
553
554 Not => {
555   irn_flags   => [ "rematerializable" ],
556   mode        => $mode_gp,
557   comment     => "construct Not: Not(a) = !a",
558   reg_req     => { in => [ "gp" ], out => [ "gp" ] },
559   emit        => '. xnor %S1, %%g0, %D1'
560 },
561
562 Nop => {
563         op_flags => [ "keep" ],
564         reg_req  => { in => [], out => [ "none" ] },
565         emit     => '. nop',
566 },
567
568 #Mul_i => {
569 #  irn_flags => "R",
570 #  comment   => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
571 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
572 #  emit      => '. mul %S1, %C, %D1'
573 #},
574 #
575 #And => {
576 #  op_flags  => "C",
577 #  irn_flags => "R",
578 #  comment   => "construct And: And(a, b) = And(b, a) = a AND b",
579 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
580 #  emit      => '. and %S1, %S2, %D1'
581 #},
582 #
583 #And_i => {
584 #  irn_flags => "R",
585 #  comment   => "construct And: And(a, const) = And(const, a) = a AND const",
586 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
587 #  emit      => '. and %S1, %C, %D1'
588 #},
589 #
590 #Or => {
591 #  op_flags  => "C",
592 #  irn_flags => "R",
593 #  comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
594 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
595 #  emit      => '. or %S1, %S2, %D1'
596 #},
597 #
598 #Or_i => {
599 #  op_flags  => "C",
600 #  irn_flags => "R",
601 #  comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
602 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
603 #  emit      => '. or %S1, %C, %D1'
604 #},
605 #
606 #Eor => {
607 #  op_flags  => "C",
608 #  irn_flags => "R",
609 #  comment   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
610 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
611 #  emit      => '. xor %S1, %S2, %D1'
612 #},
613 #
614 #Eor_i => {
615 #  irn_flags => "R",
616 #  comment   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
617 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
618 #  emit      => '. xor %S1, %C, %D1'
619 #},
620
621 # not commutative operations
622 #Shl => {
623 #  irn_flags => "R",
624 #  comment   => "construct Shl: Shl(a, b) = a << b",
625 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
626 #  emit      => '. shl %S1, %S2, %D1'
627 #},
628 #
629 #Shl_i => {
630 #  irn_flags => "R",
631 #  comment   => "construct Shl: Shl(a, const) = a << const",
632 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
633 #  emit      => '. shl %S1, %C, %D1'
634 #},
635 #
636 #Shr => {
637 #  irn_flags => "R",
638 #  comment   => "construct Shr: Shr(a, b) = a >> b",
639 #  reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
640 #  emit      => '. shr %S2, %D1'
641 #},
642 #
643 #Shr_i => {
644 #  irn_flags => "R",
645 #  comment   => "construct Shr: Shr(a, const) = a >> const",
646 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
647 #  emit      => '. shr %S1, %C, %D1'
648 #},
649 #
650 #RotR => {
651 #  irn_flags => "R",
652 #  comment   => "construct RotR: RotR(a, b) = a ROTR b",
653 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
654 #  emit      => '. ror %S1, %S2, %D1'
655 #},
656 #
657 #RotL => {
658 #  irn_flags => "R",
659 #  comment   => "construct RotL: RotL(a, b) = a ROTL b",
660 #  reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
661 #  emit      => '. rol %S1, %S2, %D1'
662 #},
663 #
664 #RotL_i => {
665 #  irn_flags => "R",
666 #  comment   => "construct RotL: RotL(a, const) = a ROTL const",
667 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
668 #  emit      => '. rol %S1, %C, %D1'
669 #},
670 #
671 #Minus => {
672 #  irn_flags => "R",
673 #  comment   => "construct Minus: Minus(a) = -a",
674 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
675 #  emit      => '. neg %S1, %D1'
676 #},
677 #
678 #Inc => {
679 #  irn_flags => "R",
680 #  comment   => "construct Increment: Inc(a) = a++",
681 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
682 #  emit      => '. inc %S1, %D1'
683 #},
684 #
685 #Dec => {
686 #  irn_flags => "R",
687 #  comment   => "construct Decrement: Dec(a) = a--",
688 #  reg_req   => { in => [ "gp" ], out => [ "gp" ] },
689 #  emit      => '. dec %S1, %D1'
690 #},
691 #
692 #Not => {
693 #  arity       => 1,
694 #  remat       => 1,
695 #  comment     => "construct Not: Not(a) = !a",
696 #  reg_req     => { in => [ "gp" ], out => [ "gp" ] },
697 #  emit        => '. not %S1, %D1'
698 #},
699
700 fAdd => {
701   op_flags  => [ "commutative" ],
702   irn_flags => [ "rematerializable" ],
703   comment   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
704   reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
705   emit      => '. fadd%FPM %S1, %S2, %D1'
706 },
707
708 fMul => {
709   op_flags  => [ "commutative" ],
710   comment   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
711   reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
712   emit      =>'. fmul%FPM %S1, %S2, %D1'
713 },
714
715 fsMuld => {
716   op_flags  => [ "commutative" ],
717   comment   => "construct FP single to double precision Mul: Mul(a, b) = Mul(b, a) = a * b",
718   reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
719   emit      =>'. fsmuld %S1, %S2, %D1'
720 },
721
722 FpSToFpD => {
723   irn_flags => [ "rematerializable" ],
724   comment   => "convert FP (single) to FP (double)",
725   reg_req   => { in => [ "fp" ], out => [ "fp" ] },
726   emit      =>'. FsTOd %S1, %D1'
727 },
728
729 FpDToFpS => {
730   irn_flags => [ "rematerializable" ],
731   comment   => "convert FP (double) to FP (single)",
732   reg_req   => { in => [ "fp" ], out => [ "fp" ] },
733   emit      =>'. FdTOs %S1, %D1'
734 },
735
736 FpSToInt => {
737   irn_flags => [ "rematerializable" ],
738   comment   => "convert integer to FP",
739   reg_req   => { in => [ "fp" ], out => [ "gp" ] },
740   emit      =>'. FiTOs %S1, %D1'
741 },
742
743 FpDToInt => {
744   irn_flags => [ "rematerializable" ],
745   comment   => "convert integer to FP",
746   reg_req   => { in => [ "fp" ], out => [ "gp" ] },
747   emit      =>'. FiTOd %S1, %D1'
748 },
749
750 IntToFpS => {
751   irn_flags => [ "rematerializable" ],
752   comment   => "convert FP (single) to integer",
753   reg_req   => { in => [ "gp" ], out => [ "fp" ] },
754   emit      =>'. FsTOi %S1, %D1'
755 },
756
757 IntToFpD => {
758   irn_flags => [ "rematerializable" ],
759   comment   => "convert FP (double) to integer",
760   reg_req   => { in => [ "gp" ], out => [ "fp" ] },
761   emit      =>'. FdTOi %S1, %D1'
762 },
763
764
765 #
766 #fMax => {
767 #  op_flags  => "C",
768 #  irn_flags => "R",
769 #  comment   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
770 #  reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
771 #  emit      =>'. fmax %S1, %S2, %D1'
772 #},
773 #
774 #fMin => {
775 #  op_flags  => "C",
776 #  irn_flags => "R",
777 #  comment   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
778 #  reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
779 #  emit      =>'. fmin %S1, %S2, %D1'
780 #},
781 #
782 ## not commutative operations
783 #
784 #fSub => {
785 #  irn_flags => "R",
786 #  comment   => "construct FP Sub: Sub(a, b) = a - b",
787 #  reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
788 #  emit      => '. fsub %S1, %S2, %D1'
789 #},
790 #
791 #fDiv => {
792 #  comment   => "construct FP Div: Div(a, b) = a / b",
793 #  reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
794 #  emit      => '. fdiv %S1, %S2, %D1'
795 #},
796 #
797 #fMinus => {
798 #  irn_flags => "R",
799 #  comment   => "construct FP Minus: Minus(a) = -a",
800 #  reg_req   => { in => [ "fp" ], out => [ "fp" ] },
801 #  emit      => '. fneg %S1, %D1'
802 #},
803 #
804 ## other operations
805 #
806 #fConst => {
807 #  op_flags  => "c",
808 #  irn_flags => "R",
809 #  comment   => "represents a FP constant",
810 #  reg_req   => { out => [ "fp" ] },
811 #  emit      => '. fmov %C, %D1',
812 #  cmp_attr  =>
813 #'
814 #       /* TODO: compare fConst attributes */
815 #       return 1;
816 #'
817 #},
818 #
819 ## Load / Store
820 #
821 #fLoad => {
822 #  op_flags  => [ "labeled", "fragile" ],
823 #  irn_flags => "R",
824 #  state     => "exc_pinned",
825 #  comment   => "construct FP Load: Load(ptr, mem) = LD ptr",
826 #  reg_req   => { in => [ "gp", "none" ], out => [ "fp" ] },
827 #  emit      => '. fmov (%S1), %D1'
828 #},
829 #
830 #fStore => {
831 #  op_flags  => [ "labeled", "fragile" ],
832 #  irn_flags => "R",
833 #  state     => "exc_pinned",
834 #  comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
835 #  reg_req   => { in => [ "gp", "fp", "none" ] },
836 #  emit      => '. fmov %S2, (%S1)'
837 #},
838
839 ); # end of %nodes