sparc: implement float->unsigned conversions
[libfirm] / ir / be / sparc / sparc_spec.pl
index e7a5f51..0ab5f73 100644 (file)
@@ -1,5 +1,4 @@
 # Creation: 2006/02/13
-# $Id$
 
 $arch = "sparc";
 
@@ -8,7 +7,7 @@ $mode_flags   = "mode_Bu";
 $mode_fpflags = "mode_Bu";
 $mode_fp      = "mode_F";
 $mode_fp2     = "mode_D";
-$mode_fp4     = "mode_E"; # not correct, we need to register a new mode
+$mode_fp4     = "mode_Q";
 
 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
 %reg_classes = (
@@ -104,9 +103,11 @@ $mode_fp4     = "mode_E"; # not correct, we need to register a new mode
 # emit source reg or imm dep. on node's arity
        RI  => "${arch}_emit_reg_or_imm(node, -1);",
        R1I => "${arch}_emit_reg_or_imm(node, 1);",
+       R2I => "${arch}_emit_reg_or_imm(node, 2);",
        S0  => "${arch}_emit_source_register(node, 0);",
        S1  => "${arch}_emit_source_register(node, 1);",
        D0  => "${arch}_emit_dest_register(node, 0);",
+       D1  => "${arch}_emit_dest_register(node, 1);",
        HIM => "${arch}_emit_high_immediate(node);",
        LM  => "${arch}_emit_load_mode(node);",
        SM  => "${arch}_emit_store_mode(node);",
@@ -119,29 +120,30 @@ $mode_fp4     = "mode_E"; # not correct, we need to register a new mode
        S0O1   => "${arch}_emit_source_reg_and_offset(node, 0, 1);",
        S1O2   => "${arch}_emit_source_reg_and_offset(node, 1, 2);",
 );
+$indent_line_func = "sparc_emit_indent()";
 
 $default_attr_type = "sparc_attr_t";
 $default_copy_attr = "sparc_copy_attr";
 
 %init_attr = (
-       sparc_attr_t             => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
-       sparc_load_store_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
-       sparc_jmp_cond_attr_t    => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
-       sparc_switch_jmp_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
-                                   "\tinit_sparc_switch_jmp_attributes(res, default_pn, jump_table);\n",
-       sparc_fp_attr_t          => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
+       sparc_attr_t             => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
+       sparc_load_store_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
+       sparc_jmp_cond_attr_t    => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);",
+       sparc_switch_jmp_attr_t  => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
+                                   "\tinit_sparc_switch_jmp_attributes(res, table, jump_table);\n",
+       sparc_fp_attr_t          => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
                                    "\tinit_sparc_fp_attributes(res, fp_mode);\n",
-       sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);".
+       sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);".
                                    "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
 );
 
 %compare_attr = (
        sparc_attr_t            => "cmp_attr_sparc",
-       sparc_load_store_attr_t => "cmp_attr_sparc_load_store",
-       sparc_jmp_cond_attr_t   => "cmp_attr_sparc_jmp_cond",
-       sparc_switch_jmp_attr_t => "cmp_attr_sparc_switch_jmp",
        sparc_fp_attr_t         => "cmp_attr_sparc_fp",
        sparc_fp_conv_attr_t    => "cmp_attr_sparc_fp_conv",
+       sparc_jmp_cond_attr_t   => "cmp_attr_sparc_jmp_cond",
+       sparc_load_store_attr_t => "cmp_attr_sparc_load_store",
+       sparc_switch_jmp_attr_t => "cmp_attr_sparc",
 );
 
 %custom_irn_flags = (
@@ -267,12 +269,19 @@ Add => {
 },
 
 AddCC => {
-       irn_flags    => [ "rematerializable" ],
+       irn_flags    => [ "rematerializable", "modifies_flags" ],
        emit         => '. addcc %S0, %R1I, %D0',
        outs         => [ "res", "flags" ],
        constructors => \%binopcc_operand_constructors,
 },
 
+AddCCZero => {
+       irn_flags    => [ "rematerializable", "modifies_flags" ],
+       emit         => '. addcc %S0, %R1I, %%g0',
+       mode         => $mode_flags,
+       constructors => \%binopcczero_operand_constructors,
+},
+
 AddX => {
        # At the moment not rematerializable because of assert in beflags.c/
        # (it claims that spiller can't rematerialize flag stuff correctly)
@@ -303,12 +312,19 @@ Sub => {
 },
 
 SubCC => {
-       irn_flags    => [ "rematerializable" ],
+       irn_flags    => [ "rematerializable", "modifies_flags" ],
        emit         => '. subcc %S0, %R1I, %D0',
        outs         => [ "res", "flags" ],
        constructors => \%binopcc_operand_constructors,
 },
 
+SubCCZero => {
+       irn_flags    => [ "rematerializable", "modifies_flags" ],
+       emit         => '. subcc %S0, %R1I, %%g0',
+       mode         => $mode_flags,
+       constructors => \%binopcczero_operand_constructors,
+},
+
 SubX => {
        # Not rematerializable (see AddX)
        emit         => '. subx %S0, %R1I, %D0',
@@ -407,22 +423,19 @@ Save => {
 },
 
 Restore => {
-       emit => '. restore %S0, %R1I, %D0',
-       outs => [ "stack" ],
-       ins  => [ "stack" ],
+       outs => [ "stack", "res" ],
        constructors => {
                imm => {
                        attr       => "ir_entity *immediate_entity, int32_t immediate_value",
                        custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
-                       reg_req    => { in => [ "sp" ], out => [ "sp:I|S" ] },
-                       ins        => [ "stack" ],
+                       reg_req    => { in => [ "frame_pointer", "gp" ], out => [ "sp:I|S", "gp" ] },
+                       ins        => [ "frame_pointer", "left" ],
                },
                reg => {
-                       reg_req    => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
-                       ins        => [ "stack", "increment" ],
+                       reg_req    => { in => [ "frame_pointer", "gp", "gp" ], out => [ "sp:I|S", "gp" ] },
+                       ins        => [ "frame_pointer", "left", "right" ],
                }
        },
-       mode => $mode_gp,
 },
 
 RestoreZero => {
@@ -502,7 +515,7 @@ Start => {
        ins       => [],
 },
 
-# This is a JumpLink instruction, but with the addition that you can add custom
+# This is a Jump instruction, but with the addition that you can add custom
 # register constraints to model your calling conventions
 Return => {
        state     => "pinned",
@@ -524,6 +537,8 @@ Return => {
        },
 },
 
+# This is a JumpLink instruction, but with the addition that you can add custom
+# register constraints to model your calling conventions
 Call => {
        irn_flags => [ "modifies_flags", "modifies_fp_flags", "has_delay_slot" ],
        state     => "exc_pinned",
@@ -533,7 +548,7 @@ Call => {
                imm => {
                        attr       => "ir_entity *entity, int32_t offset, bool aggregate_return",
                        custominit => "\tsparc_set_attr_imm(res, entity, offset);".
-                                     "\tif (aggregate_return) arch_add_irn_flags(res, sparc_arch_irn_flag_aggregate_return);",
+                                     "\tif (aggregate_return) arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_aggregate_return);",
                        arity     => "variable",
                        out_arity => "variable",
                },
@@ -541,7 +556,7 @@ Call => {
                        attr       => "bool aggregate_return",
                        arity      => "variable",
                        out_arity  => "variable",
-                       custominit => "\tif (aggregate_return) arch_add_irn_flags(res, sparc_arch_irn_flag_aggregate_return);",
+                       custominit => "\tif (aggregate_return) arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_aggregate_return);",
                }
        },
 },
@@ -559,9 +574,9 @@ SwitchJmp => {
        state        => "pinned",
        mode         => "mode_T",
        reg_req      => { in => [ "gp" ], out => [ ] },
+       out_arity    => "variable",
        attr_type    => "sparc_switch_jmp_attr_t",
-       attr         => "long default_pn, ir_entity *jump_table",
-       init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
+       attr         => "const ir_switch_table *table, ir_entity *jump_table",
 },
 
 Sll => {
@@ -676,6 +691,13 @@ Mul => {
        constructors => \%binop_operand_constructors,
 },
 
+MulCCZero => {
+       irn_flags    => [ "rematerializable", "modifies_flags" ],
+       emit         => '. smulcc %S0, %R1I, %%g0',
+       mode         => $mode_flags,
+       constructors => \%binopcczero_operand_constructors,
+},
+
 SMulh => {
        irn_flags    => [ "rematerializable" ],
        outs         => [ "low", "high" ],