X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=709e1dbe57235bc976b4692be2e3e7bd81a0c804;hb=435d56a4e04e517c9dfb3e25bcad1ac44f9de2d2;hp=77be75ee3d0f4e041ed85f542f295031281bf48f;hpb=204b50be1f8a4dd30a43eeb86b02c46d07a49ead;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 77be75ee3..709e1dbe5 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -17,7 +17,7 @@ $arch = "ia32"; # # => { # op_flags => "N|L|C|X|I|F|Y|H|c|K", -# irn_flags => "R|N|I|S" +# irn_flags => "R|N" # arity => "0|1|2|3 ... |variable|dynamic|any", # state => "floats|pinned|mem_pinned|exc_pinned", # args => [ @@ -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) @@ -63,8 +64,6 @@ $arch = "ia32"; # following irn_flags are supported: # R rematerializeable # N not spillable -# I ignore for register allocation -# S modifies stack pointer # # state: state of the operation, OPTIONAL (default is "floats") # @@ -79,10 +78,7 @@ $arch = "ia32"; # # outs: if a node defines more than one output, the names of the projections # nodes having outs having automatically the mode mode_T -# One can also annotate some flags for each out, additional to irn_flags. -# They are separated from name with a colon ':', and concatenated by pipe '|' -# Only I and S are available at the moment (same meaning as in irn_flags). -# example: [ "frame:I", "stack:I|S", "M" ] +# example: [ "frame", "stack", "M" ] # # comment: OPTIONAL comment for the node constructor # @@ -201,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);", @@ -248,16 +247,14 @@ sub ia32_custom_init_attr { my $res = ""; if(defined($node->{modified_flags})) { - $res .= "\tset_ia32_flags(res, get_ia32_flags(res) | arch_irn_flags_modify_flags);\n"; + $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"; } if(defined($node->{am})) { my $am = $node->{am}; if($am eq "source,unary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_unary);"; + $res .= "\tset_ia32_am_support(res, ia32_am_unary);"; } elsif($am eq "source,binary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_binary);"; - } elsif($am eq "source,ternary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_ternary);"; + $res .= "\tset_ia32_am_support(res, ia32_am_binary);"; } elsif($am eq "none") { # nothing to do } else { @@ -281,6 +278,9 @@ $custom_init_attr_func = \&ia32_custom_init_attr; "\tinit_ia32_asm_attributes(res);", ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + ia32_call_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_call_attributes(res, pop, call_tp);", ia32_condcode_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". "\tinit_ia32_condcode_attributes(res, pnc);", @@ -293,15 +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_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 = ( @@ -321,8 +326,7 @@ $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", Immediate => { state => "pinned", op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "gp_NOREG" ] }, + reg_req => { out => [ "gp_NOREG:I" ] }, attr => "ir_entity *symconst, int symconst_sign, long offset", attr_type => "ia32_immediate_attr_t", hash_func => "ia32_hash_Immediate", @@ -339,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 @@ -436,10 +440,10 @@ Mul => { # very strict constraints 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 => '. mul%M %unop4', - outs => [ "res_low", "res_high", "M" ], + outs => [ "res_low", "flags", "res_high", "M" ], am => "source,binary", latency => 10, units => [ "GP" ], @@ -451,7 +455,7 @@ l_Mul => { # very strict constraints op_flags => "C", cmp_attr => "return 1;", - outs => [ "EAX", "EDX", "M" ], + outs => [ "EAX", "flags", "EDX", "M" ], arity => 2 }, @@ -475,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" ], @@ -586,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", @@ -665,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" ], @@ -682,7 +709,7 @@ IDiv => { out => [ "eax", "flags", "none", "edx", "none" ] }, ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], - am => "source,ternary", + am => "source,unary", emit => ". idiv%M %unop3", latency => 25, units => [ "GP" ], @@ -696,7 +723,7 @@ Div => { out => [ "eax", "flags", "none", "edx", "none" ] }, ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], - am => "source,ternary", + am => "source,unary", emit => ". div%M %unop3", latency => 25, units => [ "GP" ], @@ -709,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, @@ -759,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, @@ -809,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, @@ -840,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, @@ -865,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, @@ -890,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" ], @@ -927,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, @@ -952,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, @@ -977,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, @@ -1189,8 +1216,7 @@ GetEIP => { Unknown_GP => { state => "pinned", op_flags => "c|NB", - irn_flags => "I", - reg_req => { out => [ "gp_UKNWN" ] }, + reg_req => { out => [ "gp_UKNWN:I" ] }, units => [], emit => "", latency => 0, @@ -1200,8 +1226,7 @@ Unknown_GP => { Unknown_VFP => { state => "pinned", op_flags => "c|NB", - irn_flags => "I", - reg_req => { out => [ "vfp_UKNWN" ] }, + reg_req => { out => [ "vfp_UKNWN:I" ] }, units => [], emit => "", mode => "mode_E", @@ -1212,8 +1237,7 @@ Unknown_VFP => { Unknown_XMM => { state => "pinned", op_flags => "c|NB", - irn_flags => "I", - reg_req => { out => [ "xmm_UKNWN" ] }, + reg_req => { out => [ "xmm_UKNWN:I" ] }, units => [], emit => "", latency => 0, @@ -1223,8 +1247,7 @@ Unknown_XMM => { NoReg_GP => { state => "pinned", op_flags => "c|NB|NI", - irn_flags => "I", - reg_req => { out => [ "gp_NOREG" ] }, + reg_req => { out => [ "gp_NOREG:I" ] }, units => [], emit => "", latency => 0, @@ -1234,8 +1257,7 @@ NoReg_GP => { NoReg_VFP => { state => "pinned", op_flags => "c|NB|NI", - irn_flags => "I", - reg_req => { out => [ "vfp_NOREG" ] }, + reg_req => { out => [ "vfp_NOREG:I" ] }, units => [], emit => "", mode => "mode_E", @@ -1246,8 +1268,7 @@ NoReg_VFP => { NoReg_XMM => { state => "pinned", op_flags => "c|NB|NI", - irn_flags => "I", - reg_req => { out => [ "xmm_NOREG" ] }, + reg_req => { out => [ "xmm_NOREG:I" ] }, units => [], emit => "", latency => 0, @@ -1257,8 +1278,7 @@ NoReg_XMM => { ChangeCW => { state => "pinned", op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "fp_cw" ] }, + reg_req => { out => [ "fpcw:I" ] }, mode => $mode_fpcw, latency => 3, units => [ "GP" ], @@ -1268,7 +1288,7 @@ ChangeCW => { FldCW => { op_flags => "L|F", state => "pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] }, ins => [ "base", "index", "mem" ], latency => 5, emit => ". fldcw %AM", @@ -1320,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" ], }, @@ -1363,10 +1383,10 @@ Lea => { Push => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] }, ins => [ "base", "index", "mem", "val", "stack" ], emit => '. push%M %unop3', - outs => [ "stack:I|S", "M" ], + outs => [ "stack", "M" ], am => "source,unary", latency => 2, units => [ "GP" ], @@ -1374,9 +1394,19 @@ Push => { Pop => { state => "exc_pinned", - reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp" ] }, + reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] }, + ins => [ "mem", "stack" ], + outs => [ "res", "M", "unused", "stack" ], + emit => '. pop%M %D0', + latency => 3, # Pop is more expensive than Push on Athlon + units => [ "GP" ], +}, + +PopEbp => { + state => "exc_pinned", + reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] }, ins => [ "mem", "stack" ], - outs => [ "res", "M", "unused", "stack:I|S" ], + outs => [ "res", "M", "unused", "stack" ], emit => '. pop%M %D0', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], @@ -1384,53 +1414,51 @@ Pop => { PopMem => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp" ] }, + reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] }, ins => [ "base", "index", "mem", "stack" ], - outs => [ "unused0", "M", "unused1", "stack:I|S" ], + outs => [ "unused0", "M", "unused1", "stack" ], emit => '. pop%M %AM', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], }, Enter => { - reg_req => { in => [ "esp" ], out => [ "ebp", "esp", "none" ] }, + reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] }, emit => '. enter', - outs => [ "frame:I", "stack:I|S", "M" ], + outs => [ "frame", "stack", "M" ], latency => 15, units => [ "GP" ], }, Leave => { - reg_req => { in => [ "ebp" ], out => [ "ebp", "esp" ] }, + reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] }, emit => '. leave', - outs => [ "frame:I", "stack:I|S" ], + outs => [ "frame", "stack" ], latency => 3, units => [ "GP" ], }, AddSP => { - irn_flags => "I", state => "pinned", - reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "in_r4", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] }, ins => [ "base", "index", "mem", "stack", "size" ], am => "source,binary", emit => '. addl %binop', latency => 1, - outs => [ "stack:I|S", "M" ], + outs => [ "stack", "M" ], units => [ "GP" ], modified_flags => $status_flags }, SubSP => { -#irn_flags => "I", state => "pinned", - reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "in_r4", "gp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] }, ins => [ "base", "index", "mem", "stack", "size" ], am => "source,binary", emit => ". subl %binop\n". ". movl %%esp, %D1", latency => 2, - outs => [ "stack:I|S", "addr", "M" ], + outs => [ "stack", "addr", "M" ], units => [ "GP" ], modified_flags => $status_flags }, @@ -1450,6 +1478,9 @@ LdTls => { latency => 1, }, +# +# BT supports source address mode, but this is unused yet +# Bt => { irn_flags => "R", state => "exc_pinned", @@ -1462,6 +1493,243 @@ 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 => { + in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ], + out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ] + }, + ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ], + outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ], + attr_type => "ia32_call_attr_t", + attr => "unsigned pop, ir_type *call_tp", + am => "source,unary", + units => [ "BRANCH" ], + latency => 4, # random number + 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" ], +}, + #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # # / ____/ ____| ____| / _| | | | | | # @@ -1788,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, @@ -2005,6 +2285,7 @@ vfisttp => { vfldz => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2014,6 +2295,7 @@ vfldz => { vfld1 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2023,6 +2305,7 @@ vfld1 => { vfldpi => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2032,6 +2315,7 @@ vfldpi => { vfldln2 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2041,6 +2325,7 @@ vfldln2 => { vfldlg2 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2050,6 +2335,7 @@ vfldlg2 => { vfldl2t => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2059,6 +2345,7 @@ vfldl2t => { vfldl2e => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2320,7 +2607,7 @@ fild => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fild%M %AM', + emit => '. fild%XM %AM', attr_type => "ia32_x87_attr_t", latency => 2, }, @@ -2329,7 +2616,7 @@ fist => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fist%M %AM', + emit => '. fist%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, @@ -2339,7 +2626,7 @@ fistp => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fistp%M %AM', + emit => '. fistp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, @@ -2350,7 +2637,7 @@ fisttp => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fisttp%M %AM', + emit => '. fisttp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2,