X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=709e1dbe57235bc976b4692be2e3e7bd81a0c804;hb=435d56a4e04e517c9dfb3e25bcad1ac44f9de2d2;hp=a4dfb4a870355490dde1c7fa652a050e7e5005e8;hpb=49b320c8933a8d8eab7163d5516c951220b5b62d;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index a4dfb4a87..709e1dbe5 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -32,12 +32,13 @@ $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", # latency => "latency of this operation (can be float)" # attr_type => "name of the attribute struct", +# modified_flags => [ "CF", ... ] # optional, list of modified flags # }, # # ... # (all nodes you need to describe) @@ -196,19 +197,22 @@ $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);", + SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);", + SI0 => "${arch}_emit_source_register_or_immediate(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);", D1 => "${arch}_emit_dest_register(node, 1);", + DS0 => "${arch}_emit_dest_register_size(node, 0);", 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);", @@ -289,16 +293,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 = ( @@ -335,7 +343,7 @@ Asm => { init_attr => "attr->asm_text = asm_text;\n". "\tattr->register_map = register_map;\n", latency => 10, - modified_flags => 1, + modified_flags => $status_flags, }, # "allocates" a free register @@ -471,10 +479,10 @@ IMul1OP => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], - out => [ "eax", "edx", "none" ] }, + out => [ "eax", "flags", "edx", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], emit => '. imul%M %unop4', - outs => [ "res_low", "res_high", "M" ], + outs => [ "res_low", "flags", "res_high", "M" ], am => "source,binary", latency => 5, units => [ "GP" ], @@ -582,6 +590,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", @@ -661,6 +681,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" ], @@ -705,7 +736,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, @@ -755,7 +786,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, @@ -805,7 +836,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, @@ -836,7 +867,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, @@ -861,7 +892,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, @@ -886,7 +917,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" ], @@ -923,7 +954,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, @@ -948,7 +979,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, @@ -973,7 +1004,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, @@ -1309,7 +1340,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" ], }, @@ -1447,6 +1478,9 @@ LdTls => { latency => 1, }, +# +# BT supports source address mode, but this is unused yet +# Bt => { irn_flags => "R", state => "exc_pinned", @@ -1459,6 +1493,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 => { @@ -1475,6 +1557,179 @@ 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, +}, + +# +# Undefined Instruction on ALL x86 CPU's +# +UD2 => { + state => "pinned", + reg_req => { in => [ "none" ], out => [ "none" ] }, + ins => [ "mem" ], + latency => 0, + emit => ". .value 0x0b0f", + units => [ "GP" ], + mode => mode_M, +}, + +# +# outport +# +Outport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, + ins => [ "port", "value", "mem" ], + emit => '. out%M %SS0, %SI1', + units => [ "GP" ], + latency => 1, + mode => mode_M, + modified_flags => $status_flags +}, + +# +# inport +# +Inport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, + ins => [ "port", "mem" ], + outs => [ "res", "M" ], + emit => '. in%M %DS0, %SS0', + units => [ "GP" ], + latency => 1, + mode => mode_T, + modified_flags => $status_flags +}, + +# +# 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" ], +}, + #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # # / ____/ ____| ____| / _| | | | | | # @@ -1801,10 +2056,22 @@ CopyB_i => { # Conversions +Cwtl => { + state => "exc_pinned", + reg_req => { in => [ "eax" ], out => [ "eax" ] }, + ins => [ "val" ], + outs => [ "res" ], + emit => '. cwtl', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, +}, + Conv_I2I => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "res", "M" ], am => "source,unary", units => [ "GP" ], latency => 1,