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