sparc: initial support for Alloc/Free nodes
[libfirm] / ir / be / sparc / sparc_spec.pl
index 41330e8..592c65a 100644 (file)
@@ -123,14 +123,14 @@ $default_copy_attr = "sparc_copy_attr";
 
 
 %init_attr = (
-       sparc_attr_t             => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
-       sparc_load_store_attr_t  => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
-       sparc_jmp_cond_attr_t    => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
-       sparc_switch_jmp_attr_t  => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+       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, flags, in_reqs, exec_units, n_res);\n".
+       sparc_fp_attr_t          => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
                                    "\tinit_sparc_fp_attributes(res, fp_mode);\n",
-       sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);".
+       sparc_fp_conv_attr_t     => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, exec_units, n_res);".
                                    "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
 );
 
@@ -144,8 +144,8 @@ $default_copy_attr = "sparc_copy_attr";
 );
 
 %custom_irn_flags = (
-       modifies_flags    => "sparc_arch_irn_flag_modifies_flags",
-       modifies_fp_flags => "sparc_arch_irn_flag_modifies_fp_flags",
+       modifies_flags    => "(arch_irn_flags_t)sparc_arch_irn_flag_modifies_flags",
+       modifies_fp_flags => "(arch_irn_flags_t)sparc_arch_irn_flag_modifies_fp_flags",
 );
 
 my %cmp_operand_constructors = (
@@ -174,6 +174,33 @@ my %binop_operand_constructors = (
        },
 );
 
+my %binopcc_operand_constructors = (
+       imm => {
+               attr       => "ir_entity *immediate_entity, int32_t immediate_value",
+               custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
+               reg_req    => { in => [ "gp" ], out => [ "gp", "flags" ] },
+               ins        => [ "left" ],
+       },
+       reg => {
+               reg_req    => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
+               ins        => [ "left", "right" ],
+       },
+);
+
+my %binopx_operand_constructors = (
+       imm => {
+               attr       => "ir_entity *immediate_entity, int32_t immediate_value",
+               custominit => "sparc_set_attr_imm(res, immediate_entity, immediate_value);",
+               reg_req    => { in => [ "gp", "flags" ], out => [ "gp" ] },
+               ins        => [ "left", "carry" ],
+       },
+       reg => {
+               reg_req    => { in => [ "gp", "gp", "flags" ], out => [ "gp" ] },
+               ins        => [ "left", "right", "carry" ],
+       },
+);
+
+
 my %binopcczero_operand_constructors = (
        imm => {
                attr       => "ir_entity *immediate_entity, int32_t immediate_value",
@@ -237,6 +264,33 @@ Add => {
        constructors => \%binop_operand_constructors,
 },
 
+AddCC => {
+       irn_flags    => [ "rematerializable" ],
+       emit         => '. addcc %S0, %R1I, %D0',
+       outs         => [ "res", "flags" ],
+       constructors => \%binopcc_operand_constructors,
+},
+
+AddX => {
+       # At the moment not rematerializable because of assert in beflags.c/
+       # (it claims that spiller can't rematerialize flag stuff correctly)
+       #irn_flags    => [ "rematerializable" ],
+       emit         => '. addx %S0, %R1I, %D0',
+       constructors => \%binopx_operand_constructors,
+       mode         => $mode_gp,
+},
+
+AddCC_t => {
+       ins       => [ "left", "right" ],
+       outs      => [ "res", "flags" ],
+       attr_type => "",
+},
+
+AddX_t => {
+       ins       => [ "left", "right", "flags_input" ],
+       attr_type => "",
+},
+
 Sub => {
        irn_flags    => [ "rematerializable" ],
        mode         => $mode_gp,
@@ -244,9 +298,34 @@ Sub => {
        constructors => \%binop_operand_constructors,
 },
 
+SubCC => {
+       irn_flags    => [ "rematerializable" ],
+       emit         => '. subcc %S0, %R1I, %D0',
+       outs         => [ "res", "flags" ],
+       constructors => \%binopcc_operand_constructors,
+},
+
+SubX => {
+       # Not rematerializable (see AddX)
+       emit         => '. subx %S0, %R1I, %D0',
+       constructors => \%binopx_operand_constructors,
+       mode         => $mode_gp,
+},
+
+SubCC_t => {
+       ins       => [ "left", "right" ],
+       outs      => [ "res", "flags" ],
+       attr_type => "",
+},
+
+SubX_t => {
+       ins       => [ "left", "right", "flags_input" ],
+       attr_type => "",
+},
+
 # Load / Store
 Ld => {
-       op_flags  => [ "labeled", "fragile" ],
+       op_flags  => [ "labeled" ],
        state     => "exc_pinned",
        constructors => {
                imm => {
@@ -279,7 +358,7 @@ SetHi => {
 },
 
 St => {
-       op_flags  => [ "labeled", "fragile" ],
+       op_flags  => [ "labeled" ],
        mode      => "mode_M",
        state     => "exc_pinned",
        constructors => {
@@ -305,6 +384,7 @@ St => {
 Save => {
        emit      => '. save %S0, %R1I, %D0',
        outs      => [ "stack" ],
+       ins       => [ "stack" ],
        constructors => {
                imm => {
                        attr       => "ir_entity *immediate_entity, int32_t immediate_value",
@@ -317,11 +397,13 @@ Save => {
                        ins        => [ "stack", "increment" ],
                }
        },
+       mode => $mode_gp,
 },
 
 Restore => {
        emit => '. restore %S0, %R1I, %D0',
        outs => [ "stack" ],
+       ins  => [ "stack" ],
        constructors => {
                imm => {
                        attr       => "ir_entity *immediate_entity, int32_t immediate_value",
@@ -334,27 +416,31 @@ Restore => {
                        ins        => [ "stack", "increment" ],
                }
        },
+       mode => $mode_gp,
 },
 
 RestoreZero => {
-       emit => '. restore',
-       outs => [ ],
-       ins  => [ ],
-       mode => "mode_T",
+       reg_req => { in => [ "frame_pointer" ], out => [ "sp:I|S" ] },
+       ins     => [ "frame_pointer" ],
+       outs    => [ "stack" ],
+       emit    => '. restore',
+       mode    => $mode_gp,
 },
 
 SubSP => {
-       reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
-       ins       => [ "stack", "size", "mem" ],
-       outs      => [ "stack", "addr", "M" ],
-       emit      => ". sub %S0, %S1, %D0\n",
+       reg_req => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
+       ins     => [ "stack", "size" ],
+       outs    => [ "stack" ],
+       emit    => ". sub %S0, %S1, %D0\n",
+       mode    => $mode_gp,
 },
 
 AddSP => {
-       reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
-       ins       => [ "stack", "size", "mem" ],
-       outs      => [ "stack", "M" ],
-       emit      => ". add %S0, %S1, %D0\n",
+       reg_req => { in => [ "sp", "gp" ], out => [ "sp:I|S" ] },
+       ins     => [ "stack", "size" ],
+       outs    => [ "stack" ],
+       emit    => ". add %S0, %S1, %D0\n",
+       mode    => $mode_gp,
 },
 
 FrameAddr => {
@@ -373,9 +459,11 @@ Bicc => {
        state     => "pinned",
        mode      => "mode_T",
        attr_type => "sparc_jmp_cond_attr_t",
-       attr      => "pn_Cmp pnc, bool is_unsigned",
-       init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, is_unsigned);",
+       attr      => "ir_relation relation, bool is_unsigned",
+       init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, is_unsigned);",
        reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
+       ins       => [ "flags" ],
+       outs      => [ "false", "true" ],
 },
 
 fbfcc => {
@@ -383,9 +471,11 @@ fbfcc => {
        state     => "pinned",
        mode      => "mode_T",
        attr_type => "sparc_jmp_cond_attr_t",
-       attr      => "pn_Cmp pnc",
-       init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, false);",
+       attr      => "ir_relation relation",
+       init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, false);",
        reg_req   => { in => [ "fpflags" ], out => [ "none", "none" ] },
+       ins       => [ "flags" ],
+       outs      => [ "false", "true" ],
 },
 
 Ba => {
@@ -396,21 +486,29 @@ Ba => {
        mode      => "mode_X",
 },
 
+Start => {
+       state     => "pinned",
+       out_arity => "variable",
+       ins       => [],
+},
+
 # This is a JumpLink instruction, but with the addition that you can add custom
 # register constraints to model your calling conventions
 Return => {
+       state     => "pinned",
+       op_flags  => [ "cfopcode" ],
        arity     => "variable",
-       out_arity => "variable",
+       mode      => "mode_X",
        constructors => {
                imm => {
                        attr       => "ir_entity *entity, int32_t offset",
                        custominit => "\tsparc_set_attr_imm(res, entity, offset);",
                        arity     => "variable",
-                       out_arity => "variable",
+                       reg_req   => { out => [ "none" ] },
                },
                reg => {
                        arity     => "variable",
-                       out_arity => "variable",
+                       reg_req   => { out => [ "none" ] },
                }
        },
 },
@@ -422,14 +520,17 @@ Call => {
        out_arity => "variable",
        constructors => {
                imm => {
-                       attr       => "ir_entity *entity, int32_t offset",
-                       custominit => "\tsparc_set_attr_imm(res, entity, offset);",
+                       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);",
                        arity     => "variable",
                        out_arity => "variable",
                },
                reg => {
-                       arity     => "variable",
-                       out_arity => "variable",
+                       attr       => "bool aggregate_return",
+                       arity      => "variable",
+                       out_arity  => "variable",
+                       custominit => "\tif (aggregate_return) arch_add_irn_flags(res, sparc_arch_irn_flag_aggregate_return);",
                }
        },
 },
@@ -657,7 +758,7 @@ fneg => {
        irn_flags => [ "rematerializable" ],
        reg_req   => { in => [ "fp" ], out => [ "fp" ] },
        # note that we only need the first register even for wide-values
-       emit      => '. fneg %S0, %D0',
+       emit      => '. fnegs %S0, %D0',
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
        ins          => [ "val" ],
@@ -748,7 +849,7 @@ fftoi => {
 },
 
 Ldf => {
-       op_flags  => [ "labeled", "fragile" ],
+       op_flags  => [ "labeled" ],
        state     => "exc_pinned",
        constructors => {
                s => {
@@ -770,7 +871,7 @@ Ldf => {
 },
 
 Stf => {
-       op_flags  => [ "labeled", "fragile" ],
+       op_flags  => [ "labeled" ],
        state     => "exc_pinned",
        constructors => {
                s => {