7 $mode_flags = "mode_Bu";
10 # The node description is done as a perl hash initializer with the
11 # following structure:
16 # arity => "0|1|2|3 ... |variable|dynamic|any", # optional
17 # state => "floats|pinned|mem_pinned|exc_pinned", # optional
19 # { type => "type 1", name => "name 1" },
20 # { type => "type 2", name => "name 2" },
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
38 # ... # (all nodes you need to describe)
40 # ); # close the %nodes initializer
42 # state: state of the operation, OPTIONAL (default is "floats")
44 # arity: arity of the operation, MUST NOT BE OMITTED
46 # args: the OPTIONAL arguments of the node constructor (debug, irg and block
47 # are always the first 3 arguments and are always autmatically
49 # If this key is missing the following arguments will be created:
50 # for i = 1 .. arity: ir_node *op_i
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
56 # comment: OPTIONAL comment for the node constructor
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
65 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
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
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.
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 },
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
109 { name => "y", realname => "y", type => 4 }, # the multiply/divide state register
110 { mode => $mode_flags, flags => "manual_ra" }
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" }
121 # fp registers can be accessed any time
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 },
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);",
189 $default_attr_type = "sparc_attr_t";
190 $default_copy_attr = "sparc_copy_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);",
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",
217 # addressing modes: imm, reg, reg +/- imm, reg + reg
218 # max. imm = 13 bits signed (-4096 ... 4096)
221 my %cmp_operand_constructors = (
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" ] },
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" ],
237 my %unop_operand_constructors = (
239 attr => "int immediate_value",
240 custominit => "sparc_set_attr_imm(res, immediate_value);",
241 reg_req => { in => [], out => [ "gp" ] },
244 reg_req => { in => [ "gp" ], out => [ "gp" ] },
248 my %binop_operand_constructors = (
250 attr => "int immediate_value",
251 custominit => "sparc_set_attr_imm(res, immediate_value);",
252 reg_req => { in => [ "gp" ], out => [ "gp" ] },
256 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
257 ins => [ "left", "right" ],
264 irn_flags => [ "rematerializable" ],
265 comment => "construct Add: Add(a, b) = Add(b, a) = a + b",
267 emit => '. add %S1, %R2I, %D1',
268 constructors => \%binop_operand_constructors,
272 irn_flags => [ "rematerializable" ],
273 comment => "construct Sub: Sub(a, b) = a - b",
275 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
276 emit => '. sub %S1, %R2I, %D1',
277 constructors => \%binop_operand_constructors,
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'
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',
307 irn_flags => [ "rematerializable" ],
308 comment => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
309 state => "exc_pinned",
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);",
320 irn_flags => [ "rematerializable" ],
321 comment => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
322 state => "exc_pinned",
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);",
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'
346 op_flags => [ "labeled", "fragile" ],
347 comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",
349 state => "exc_pinned",
350 ins => [ "ptr", "val", "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]'
359 irn_flags => [ "rematerializable" ],
360 comment => "construct Mov: Mov(src, dest) = MV src,dest",
362 emit => '. mov %R1I, %D1',
364 constructors => \%unop_operand_constructors,
368 comment => "function prolog instruction. autom. saves sp & shifts the register window. previous out regs become the new in regs",
370 in => [ "sp", "none"],
371 out => [ "sp:I|S","none" ]
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);",
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",
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",
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",
406 op_flags => [ "constlike" ],
407 irn_flags => [ "rematerializable" ],
408 attr => "ir_entity *entity",
409 reg_req => { in => [ "gp" ], out => [ "gp" ] },
411 attr_type => "sparc_symconst_attr_t",
416 op_flags => [ "labeled", "cfopcode", "forking" ],
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);",
427 op_flags => [ "cfopcode" ],
428 irn_flags => [ "simple_jump" ],
429 reg_req => { out => [ "none" ] },
434 irn_flags => [ "rematerializable", "modify_flags" ],
435 emit => '. cmp %S1, %R2I',
437 attr_type => "sparc_cmp_attr_t",
438 constructors => \%cmp_operand_constructors,
442 irn_flags => [ "rematerializable", "modify_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" ] },
453 op_flags => [ "labeled", "cfopcode", "forking" ],
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",
464 irn_flags => [ "rematerializable" ],
465 comment => "construct shift logical left",
467 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
468 emit => '. sll %S1, %R2I, %D1',
469 constructors => \%binop_operand_constructors,
473 irn_flags => [ "rematerializable" ],
474 comment => "construct shift logical right",
476 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
477 emit => '. srl %S1, %R2I, %D1',
478 constructors => \%binop_operand_constructors,
482 irn_flags => [ "rematerializable" ],
483 comment => "construct shift right arithmetical",
485 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
486 emit => '. sra %S1, %R2I, %D1',
487 constructors => \%binop_operand_constructors,
491 irn_flags => [ "rematerializable" ],
492 comment => "construct logical and",
494 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
495 emit => '. and %S1, %R2I, %D1',
496 constructors => \%binop_operand_constructors,
500 irn_flags => [ "rematerializable" ],
501 comment => "construct logical or",
503 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
504 emit => '. or %S1, %R2I, %D1',
505 constructors => \%binop_operand_constructors,
509 irn_flags => [ "rematerializable" ],
510 comment => "construct logical xor",
512 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
513 emit => '. xor %S1, %R2I, %D1',
514 constructors => \%binop_operand_constructors,
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'
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,
535 irn_flags => [ "rematerializable" ],
536 state => "exc_pinned",
538 comment => "construct Div: Div(a, b) = a / b",
539 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
541 constructors => \%binop_operand_constructors,
542 # emit =>'. div %S1, %R2I, %D1'
546 irn_flags => [ "rematerializable" ],
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"
555 irn_flags => [ "rematerializable" ],
557 comment => "construct Not: Not(a) = !a",
558 reg_req => { in => [ "gp" ], out => [ "gp" ] },
559 emit => '. xnor %S1, %%g0, %D1'
563 op_flags => [ "keep" ],
564 reg_req => { in => [], out => [ "none" ] },
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'
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'
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'
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'
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'
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'
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'
621 # not commutative operations
624 # comment => "construct Shl: Shl(a, b) = a << b",
625 # reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
626 # emit => '. shl %S1, %S2, %D1'
631 # comment => "construct Shl: Shl(a, const) = a << const",
632 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
633 # emit => '. shl %S1, %C, %D1'
638 # comment => "construct Shr: Shr(a, b) = a >> b",
639 # reg_req => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
640 # emit => '. shr %S2, %D1'
645 # comment => "construct Shr: Shr(a, const) = a >> const",
646 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
647 # emit => '. shr %S1, %C, %D1'
652 # comment => "construct RotR: RotR(a, b) = a ROTR b",
653 # reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
654 # emit => '. ror %S1, %S2, %D1'
659 # comment => "construct RotL: RotL(a, b) = a ROTL b",
660 # reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
661 # emit => '. rol %S1, %S2, %D1'
666 # comment => "construct RotL: RotL(a, const) = a ROTL const",
667 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
668 # emit => '. rol %S1, %C, %D1'
673 # comment => "construct Minus: Minus(a) = -a",
674 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
675 # emit => '. neg %S1, %D1'
680 # comment => "construct Increment: Inc(a) = a++",
681 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
682 # emit => '. inc %S1, %D1'
687 # comment => "construct Decrement: Dec(a) = a--",
688 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
689 # emit => '. dec %S1, %D1'
695 # comment => "construct Not: Not(a) = !a",
696 # reg_req => { in => [ "gp" ], out => [ "gp" ] },
697 # emit => '. not %S1, %D1'
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'
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'
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'
723 irn_flags => [ "rematerializable" ],
724 comment => "convert FP (single) to FP (double)",
725 reg_req => { in => [ "fp" ], out => [ "fp" ] },
726 emit =>'. FsTOd %S1, %D1'
730 irn_flags => [ "rematerializable" ],
731 comment => "convert FP (double) to FP (single)",
732 reg_req => { in => [ "fp" ], out => [ "fp" ] },
733 emit =>'. FdTOs %S1, %D1'
737 irn_flags => [ "rematerializable" ],
738 comment => "convert integer to FP",
739 reg_req => { in => [ "fp" ], out => [ "gp" ] },
740 emit =>'. FiTOs %S1, %D1'
744 irn_flags => [ "rematerializable" ],
745 comment => "convert integer to FP",
746 reg_req => { in => [ "fp" ], out => [ "gp" ] },
747 emit =>'. FiTOd %S1, %D1'
751 irn_flags => [ "rematerializable" ],
752 comment => "convert FP (single) to integer",
753 reg_req => { in => [ "gp" ], out => [ "fp" ] },
754 emit =>'. FsTOi %S1, %D1'
758 irn_flags => [ "rematerializable" ],
759 comment => "convert FP (double) to integer",
760 reg_req => { in => [ "gp" ], out => [ "fp" ] },
761 emit =>'. FdTOi %S1, %D1'
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'
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'
782 ## not commutative operations
786 # comment => "construct FP Sub: Sub(a, b) = a - b",
787 # reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
788 # emit => '. fsub %S1, %S2, %D1'
792 # comment => "construct FP Div: Div(a, b) = a / b",
793 # reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
794 # emit => '. fdiv %S1, %S2, %D1'
799 # comment => "construct FP Minus: Minus(a) = -a",
800 # reg_req => { in => [ "fp" ], out => [ "fp" ] },
801 # emit => '. fneg %S1, %D1'
809 # comment => "represents a FP constant",
810 # reg_req => { out => [ "fp" ] },
811 # emit => '. fmov %C, %D1',
814 # /* TODO: compare fConst attributes */
822 # op_flags => [ "labeled", "fragile" ],
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'
831 # op_flags => [ "labeled", "fragile" ],
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)'