- implemented __builtin_prefetch in ia32 BE
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 8686341..a4c7a72 100644 (file)
@@ -32,7 +32,7 @@ $arch = "ia32";
 #   ins       => { "in1", "in2" }   # optional, creates n_op_in1, ... consts
 #   mode      => "mode_Iu"          # optional, predefines the mode
 #   emit      => "emit code with templates",
-#   attr      => "attitional attribute arguments for constructor",
+#   attr      => "additional attribute arguments for constructor",
 #   init_attr => "emit attribute initialization template",
 #   rd_constructor => "c source code which constructs an ir_node",
 #   hash_func => "name of the hash function for this operation",
@@ -290,16 +290,20 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
        ia32_x87_attr_t =>
                "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n".
                "\tinit_ia32_x87_attributes(res);",
+       ia32_climbframe_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_climbframe_attributes(res, count);",
 );
 
 %compare_attr = (
        ia32_asm_attr_t       => "ia32_compare_asm_attr",
-       ia32_attr_t           => "ia32_compare_nodes_attr",
-       ia32_call_attr_t      => "ia32_compare_call_attr",
-       ia32_condcode_attr_t  => "ia32_compare_condcode_attr",
-       ia32_copyb_attr_t     => "ia32_compare_copyb_attr",
-       ia32_immediate_attr_t => "ia32_compare_immediate_attr",
-       ia32_x87_attr_t       => "ia32_compare_x87_attr",
+       ia32_attr_t            => "ia32_compare_nodes_attr",
+       ia32_call_attr_t       => "ia32_compare_call_attr",
+       ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
+       ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
+       ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
+       ia32_x87_attr_t        => "ia32_compare_x87_attr",
+       ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
 );
 
 %operands = (
@@ -583,6 +587,18 @@ Xor => {
        modified_flags => $status_flags
 },
 
+Xor0 => {
+       op_flags  => "c",
+       irn_flags => "R",
+       reg_req   => { out => [ "gp", "flags" ] },
+       outs      => [ "res", "flags" ],
+       emit      => ". xor%M %D0, %D0",
+       units     => [ "GP" ],
+       latency   => 1,
+       mode      => $mode_gp,
+       modified_flags => $status_flags
+},
+
 XorMem => {
        irn_flags => "R",
        state     => "exc_pinned",
@@ -662,6 +678,17 @@ Sbb => {
        modified_flags => $status_flags
 },
 
+Sbb0 => {
+       irn_flags => "R",
+       reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
+       outs      => [ "res", "flags" ],
+       emit      => ". sbb%M %D0, %D0",
+       units     => [ "GP" ],
+       latency   => 1,
+       mode      => $mode_gp,
+       modified_flags => $status_flags
+},
+
 l_Sub => {
        reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
        ins       => [ "minuend", "subtrahend" ],
@@ -1476,6 +1503,94 @@ Call => {
        modified_flags => $status_flags
 },
 
+#
+# a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
+#
+# PS: try gcc __builtin_frame_address(100000) :-)
+#
+ClimbFrame => {
+       reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
+       ins       => [ "frame", "cnt", "tmp" ],
+       outs      => [ "res" ],
+       latency   => 4, # random number
+       attr_type => "ia32_climbframe_attr_t",
+       attr      => "unsigned count",
+       units     => [ "GP" ],
+       mode      => $mode_gp
+},
+
+#
+# Intel style prefetching
+#
+Prefetch0 => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetch0 %AM",
+       units     => [ "GP" ],
+},
+
+Prefetch1 => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetch1 %AM",
+       units     => [ "GP" ],
+},
+
+Prefetch2 => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetch2 %AM",
+       units     => [ "GP" ],
+},
+
+PrefetchNTA => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetchnta %AM",
+       units     => [ "GP" ],
+},
+
+#
+# 3DNow! prefetch instructions
+#
+Prefetch => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetch %AM",
+       units     => [ "GP" ],
+},
+
+PrefetchW => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "mem" ],
+       outs      => [ "M" ],
+       latency   => 0,
+       emit      => ". prefetchw %AM",
+       units     => [ "GP" ],
+},
+
 #-----------------------------------------------------------------------------#
 #   _____ _____ ______    __ _             _                     _            #
 #  / ____/ ____|  ____|  / _| |           | |                   | |           #