X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=2d06b0eb949755fc82db5f517d55097b4d4f7a60;hb=8c9bd910f70b291d3ffc76d87dd514236152053f;hp=7bd87102577e68af77a8f768eb149680db727da3;hpb=0de339082b546b3acc3822f35f7f3478af70162b;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 7bd871025..2d06b0eb9 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 => [ @@ -28,11 +28,17 @@ $arch = "ia32"; # comment => "any comment for constructor", # reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] }, # cmp_attr => "c source code for comparing node attributes", +# outs => { "out1", "out2" } # optional, creates pn_op_out1, ... consts +# 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" -# init_attr => "emit attribute initialization template" -# rd_constructor => "c source code which constructs an ir_node" +# attr => "attitional 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) @@ -51,13 +57,13 @@ $arch = "ia32"; # H irop_flag_highlevel # c irop_flag_constlike # K irop_flag_keep +# NB irop_flag_dump_noblock +# NI irop_flag_dump_noinput # # irn_flags: special node flags, OPTIONAL (default is 0) # 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") # @@ -72,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 # @@ -144,14 +147,14 @@ $arch = "ia32"; { mode => "mode_E" } ], vfp => [ - { name => "vf0", type => 1 | 16 }, - { name => "vf1", type => 1 | 16 }, - { name => "vf2", type => 1 | 16 }, - { name => "vf3", type => 1 | 16 }, - { name => "vf4", type => 1 | 16 }, - { name => "vf5", type => 1 | 16 }, - { name => "vf6", type => 1 | 16 }, - { name => "vf7", type => 1 | 16 }, + { name => "vf0", type => 1 }, + { name => "vf1", type => 1 }, + { name => "vf2", type => 1 }, + { name => "vf3", type => 1 }, + { name => "vf4", type => 1 }, + { name => "vf5", type => 1 }, + { name => "vf6", type => 1 }, + { name => "vf7", type => 1 }, { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes { name => "vfp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes { mode => "mode_E" } @@ -212,8 +215,8 @@ $arch = "ia32"; XXM => "${arch}_emit_xmm_mode_suffix(node);", XSD => "${arch}_emit_xmm_mode_suffix_s(node);", AM => "${arch}_emit_am(node);", - unop3 => "${arch}_emit_unop(node, 3);", - unop4 => "${arch}_emit_unop(node, 4);", + unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);", + unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);", binop => "${arch}_emit_binop(node);", x87_binop => "${arch}_emit_x87_binop(node);", CMP0 => "${arch}_emit_cmp_suffix_node(node, 0);", @@ -241,16 +244,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 { @@ -268,54 +269,60 @@ sub ia32_custom_init_attr { $custom_init_attr_func = \&ia32_custom_init_attr; %init_attr = ( - ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", - ia32_x87_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". - "\tinit_ia32_x87_attributes(res);", ia32_asm_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". "\tinit_ia32_x87_attributes(res);". "\tinit_ia32_asm_attributes(res);", - ia32_immediate_attr_t => + 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_immediate_attributes(res, symconst, symconst_sign, offset);", + "\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);", ia32_copyb_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". "\tinit_ia32_copyb_attributes(res, size);", - ia32_condcode_attr_t => + ia32_immediate_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". - "\tinit_ia32_condcode_attributes(res, pnc);", + "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);", + ia32_x87_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_x87_attributes(res);", ); %compare_attr = ( - ia32_attr_t => "ia32_compare_nodes_attr", - ia32_x87_attr_t => "ia32_compare_x87_attr", ia32_asm_attr_t => "ia32_compare_asm_attr", - ia32_immediate_attr_t => "ia32_compare_immediate_attr", - ia32_copyb_attr_t => "ia32_compare_copyb_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", ); %operands = ( ); -$mode_xmm = "mode_E"; -$mode_gp = "mode_Iu"; -$mode_flags = "mode_Iu"; -$mode_fpcw = "mode_fpcw"; -$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ]; -$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", - "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ]; +$mode_xmm = "mode_E"; +$mode_gp = "mode_Iu"; +$mode_flags = "mode_Iu"; +$mode_fpcw = "mode_fpcw"; +$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ]; +$status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ]; +$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", + "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ]; %nodes = ( 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", latency => 0, mode => $mode_gp, }, @@ -329,9 +336,10 @@ 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 ProduceVal => { op_flags => "c", irn_flags => "R", @@ -422,13 +430,13 @@ l_Adc => { Mul => { # we should not rematrialize this node. It produces 2 results and has - # very strict constrains + # very strict constraints state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], - out => [ "eax", "edx", "none" ] }, - ins => [ "base", "index", "mem", "val_high", "val_low" ], + 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" ], @@ -437,10 +445,10 @@ Mul => { l_Mul => { # we should not rematrialize this node. It produces 2 results and has - # very strict constrains + # very strict constraints op_flags => "C", cmp_attr => "return 1;", - outs => [ "EAX", "EDX", "M" ], + outs => [ "EAX", "flags", "EDX", "M" ], arity => 2 }, @@ -465,7 +473,7 @@ IMul1OP => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], out => [ "eax", "edx", "none" ] }, - ins => [ "base", "index", "mem", "val_high", "val_low" ], + ins => [ "base", "index", "mem", "left", "right" ], emit => '. imul%M %unop4', outs => [ "res_low", "res_high", "M" ], am => "source,binary", @@ -671,7 +679,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" ], @@ -685,7 +693,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" ], @@ -902,7 +910,7 @@ NegMem => { Minus64Bit => { irn_flags => "R", - reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "gp" ] }, + reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] }, outs => [ "low_res", "high_res" ], units => [ "GP" ], latency => 3, @@ -920,7 +928,7 @@ Inc => { units => [ "GP" ], mode => $mode_gp, latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, IncMem => { @@ -932,7 +940,7 @@ IncMem => { units => [ "GP" ], mode => "mode_M", latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, Dec => { @@ -945,7 +953,7 @@ Dec => { units => [ "GP" ], mode => $mode_gp, latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, DecMem => { @@ -957,7 +965,7 @@ DecMem => { units => [ "GP" ], mode => "mode_M", latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, Not => { @@ -1008,9 +1016,10 @@ Stc => { Cmp => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], + out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], - outs => [ "eflags" ], + outs => [ "eflags", "unused", "M" ], am => "source,binary", emit => '. cmp%M %binop', attr => "int ins_permuted, int cmp_unsigned", @@ -1136,7 +1145,7 @@ SwitchJmp => { reg_req => { in => [ "gp" ], out => [ "none" ] }, mode => "mode_T", attr_type => "ia32_condcode_attr_t", - attr => "pn_Cmp pnc", + attr => "long pnc", latency => 3, units => [ "BRANCH" ], modified_flags => $status_flags, @@ -1176,9 +1185,8 @@ GetEIP => { Unknown_GP => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "gp_UKNWN" ] }, + op_flags => "c|NB", + reg_req => { out => [ "gp_UKNWN:I" ] }, units => [], emit => "", latency => 0, @@ -1187,9 +1195,8 @@ Unknown_GP => { Unknown_VFP => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "vfp_UKNWN" ] }, + op_flags => "c|NB", + reg_req => { out => [ "vfp_UKNWN:I" ] }, units => [], emit => "", mode => "mode_E", @@ -1199,9 +1206,8 @@ Unknown_VFP => { Unknown_XMM => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "xmm_UKNWN" ] }, + op_flags => "c|NB", + reg_req => { out => [ "xmm_UKNWN:I" ] }, units => [], emit => "", latency => 0, @@ -1210,9 +1216,8 @@ Unknown_XMM => { NoReg_GP => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "gp_NOREG" ] }, + op_flags => "c|NB|NI", + reg_req => { out => [ "gp_NOREG:I" ] }, units => [], emit => "", latency => 0, @@ -1221,9 +1226,8 @@ NoReg_GP => { NoReg_VFP => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "vfp_NOREG" ] }, + op_flags => "c|NB|NI", + reg_req => { out => [ "vfp_NOREG:I" ] }, units => [], emit => "", mode => "mode_E", @@ -1233,9 +1237,8 @@ NoReg_VFP => { NoReg_XMM => { state => "pinned", - op_flags => "c", - irn_flags => "I", - reg_req => { out => [ "xmm_NOREG" ] }, + op_flags => "c|NB|NI", + reg_req => { out => [ "xmm_NOREG:I" ] }, units => [], emit => "", latency => 0, @@ -1245,8 +1248,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" ], @@ -1256,7 +1258,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", @@ -1312,21 +1314,6 @@ Load => { units => [ "GP" ], }, -l_Load => { - op_flags => "L|F", - cmp_attr => "return 1;", - outs => [ "res", "M" ], - arity => 2, -}, - -l_Store => { - op_flags => "L|F", - cmp_attr => "return 1;", - state => "exc_pinned", - arity => 3, - mode => "mode_M", -}, - Store => { op_flags => "L|F", state => "exc_pinned", @@ -1366,20 +1353,30 @@ 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" ], - am => "source,binary", + outs => [ "stack", "M" ], + am => "source,unary", latency => 2, units => [ "GP" ], }, 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:I|S" ], + 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" ], emit => '. pop%M %D0', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], @@ -1387,53 +1384,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 => [ "esp", "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 }, @@ -1458,13 +1453,29 @@ Bt => { state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] }, ins => [ "left", "right" ], - emit => '. bt%M %S0, %S1', + emit => '. bt%M %S1, %S0', units => [ "GP" ], latency => 1, mode => $mode_flags, modified_flags => $status_flags # only CF is set, but the other flags are undefined }, +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 +}, + #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # # / ____/ ____| ____| / _| | | | | | # @@ -1791,10 +1802,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, @@ -1981,12 +2004,6 @@ vfild => { attr_type => "ia32_x87_attr_t", }, -l_vfild => { - cmp_attr => "return 1;", - outs => [ "res", "M" ], - arity => 2, -}, - vfist => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ] }, @@ -2000,27 +2017,21 @@ vfist => { # SSE3 fisttp instruction vfisttp => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]}, ins => [ "base", "index", "mem", "val" ], + outs => [ "res", "M" ], latency => 4, units => [ "VFP" ], - mode => "mode_M", attr_type => "ia32_x87_attr_t", }, -l_vfist => { - cmp_attr => "return 1;", - state => "exc_pinned", - arity => 3, - mode => "mode_M", -}, - # constants vfldz => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2030,6 +2041,7 @@ vfldz => { vfld1 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2039,6 +2051,7 @@ vfld1 => { vfldpi => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2048,6 +2061,7 @@ vfldpi => { vfldln2 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2057,6 +2071,7 @@ vfldln2 => { vfldlg2 => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2066,6 +2081,7 @@ vfldlg2 => { vfldl2t => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2075,6 +2091,7 @@ vfldl2t => { vfldl2e => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, + outs => [ "res" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -2336,7 +2353,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, }, @@ -2345,7 +2362,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, @@ -2355,7 +2372,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, @@ -2366,7 +2383,7 @@ fisttp => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fist%M %AM', + emit => '. fisttp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2,