X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=2ccf12d41b7c606db247076519db46b1b27456bc;hb=41658443cdd74a5ce93c986ab9e623cc92d11f38;hp=0f53511ebf3314f77bec811989429a481d2c1a56;hpb=65d5ca1d03d9541530b4bb2433ceddb3926a7b0f;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 0f53511eb..2ccf12d41 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -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", @@ -197,9 +197,11 @@ $arch = "ia32"; S1 => "${arch}_emit_source_register(node, 1);", S2 => "${arch}_emit_source_register(node, 2);", S3 => "${arch}_emit_source_register(node, 3);", + SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);", SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);", SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);", SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);", + SH0 => "${arch}_emit_8bit_high_source_register(node, 0);", SI1 => "${arch}_emit_source_register_or_immediate(node, 1);", SI3 => "${arch}_emit_source_register_or_immediate(node, 3);", D0 => "${arch}_emit_dest_register(node, 0);", @@ -207,9 +209,7 @@ $arch = "ia32"; DB0 => "${arch}_emit_8bit_dest_register(node, 0);", X0 => "${arch}_emit_x87_register(node, 0);", X1 => "${arch}_emit_x87_register(node, 1);", - SE => "${arch}_emit_extend_suffix(get_ia32_ls_mode(node));", - ME => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n - ia32_emit_mode_suffix(node);", + EX => "${arch}_emit_extend_suffix(node);", M => "${arch}_emit_mode_suffix(node);", XM => "${arch}_emit_x87_mode_suffix(node);", XXM => "${arch}_emit_xmm_mode_suffix(node);", @@ -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" ], @@ -706,7 +733,7 @@ Shl => { out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. shl %SB1, %S0', + emit => '. shl%M %SB1, %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -756,7 +783,7 @@ Shr => { out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. shr %SB1, %S0', + emit => '. shr%M %SB1, %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, @@ -806,7 +833,7 @@ Sar => { out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. sar %SB1, %S0', + emit => '. sar%M %SB1, %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -837,7 +864,7 @@ Ror => { out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. ror %SB1, %S0', + emit => '. ror%M %SB1, %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -862,7 +889,7 @@ Rol => { out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. rol %SB1, %S0', + emit => '. rol%M %SB1, %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -887,7 +914,7 @@ Neg => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, - emit => '. neg %S0', + emit => '. neg%M %S0', ins => [ "val" ], outs => [ "res", "flags" ], units => [ "GP" ], @@ -924,7 +951,7 @@ Inc => { out => [ "in_r1", "flags" ] }, ins => [ "val" ], outs => [ "res", "flags" ], - emit => '. inc %S0', + emit => '. inc%M %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, @@ -949,7 +976,7 @@ Dec => { out => [ "in_r1", "flags" ] }, ins => [ "val" ], outs => [ "res", "flags" ], - emit => '. dec %S0', + emit => '. dec%M %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, @@ -974,7 +1001,7 @@ Not => { out => [ "in_r1", "flags" ] }, ins => [ "val" ], outs => [ "res", "flags" ], - emit => '. not %S0', + emit => '. not%M %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -1310,7 +1337,7 @@ Load => { ins => [ "base", "index", "mem" ], outs => [ "res", "M", "X_exc" ], latency => 0, - emit => ". mov%SE%ME%.l %AM, %D0", + emit => ". mov%EX%.l %AM, %D0", units => [ "GP" ], }, @@ -1448,6 +1475,9 @@ LdTls => { latency => 1, }, +# +# BT supports source address mode, but this is unused yet +# Bt => { irn_flags => "R", state => "exc_pinned", @@ -1460,6 +1490,54 @@ Bt => { modified_flags => $status_flags # only CF is set, but the other flags are undefined }, +Bsf => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. bsf%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + +Bsr => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. bsr%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + +# +# SSE4.2 or SSE4a popcnt instruction +# +Popcnt => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. popcnt%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + Call => { state => "exc_pinned", reg_req => { @@ -1476,6 +1554,135 @@ 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 +}, + +# +# bswap +# +Bswap => { + irn_flags => "R", + reg_req => { in => [ "gp" ], + out => [ "in_r1" ] }, + emit => '. bswap%M %S0', + ins => [ "val" ], + units => [ "GP" ], + latency => 1, + mode => $mode_gp, +}, + +# +# bswap16, use xchg here +# +Bswap16 => { + irn_flags => "R", + reg_req => { in => [ "eax ebx ecx edx" ], + out => [ "in_r1" ] }, + emit => '. xchg %SB0, %SH0', + ins => [ "val" ], + units => [ "GP" ], + latency => 1, + mode => $mode_gp, +}, + +# +# BreakPoint +# +Breakpoint => { + state => "pinned", + reg_req => { in => [ "none" ], out => [ "none" ] }, + ins => [ "mem" ], + latency => 0, + emit => ". int3", + units => [ "GP" ], + mode => mode_M, +}, + +# +# 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 => ". prefetcht0 %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 => ". prefetcht1 %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 => ". prefetcht2 %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" ], +}, + #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # # / ____/ ____| ____| / _| | | | | | #