X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=4bbb018ad9ea086367b3ff0ce7faf933a11feb73;hb=c1fdf770d4d000dd5cf22daead32369342c5f5d1;hp=11c9064a8a113f96fcf7eb993ef9f56dc8eb1301;hpb=9ed9f4495b1688416395fb6b8e575a77df52ebf1;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 11c9064a8..4bbb018ad 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -28,10 +28,15 @@ $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", # }, # @@ -51,6 +56,8 @@ $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: @@ -144,14 +151,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,9 +219,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);", - unop5 => "${arch}_emit_unop(node, 5);", + 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);", @@ -247,11 +253,9 @@ sub ia32_custom_init_attr { 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 { @@ -269,44 +273,50 @@ 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 = ( @@ -317,6 +327,7 @@ Immediate => { reg_req => { out => [ "gp_NOREG" ] }, 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, }, @@ -333,6 +344,7 @@ Asm => { modified_flags => 1, }, +# "allocates" a free register ProduceVal => { op_flags => "c", irn_flags => "R", @@ -423,13 +435,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" ], @@ -438,10 +450,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 }, @@ -466,7 +478,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", @@ -607,7 +619,7 @@ Sub => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "flags", "none" ] }, - ins => [ "base", "index", "mem", "left", "right" ], + ins => [ "base", "index", "mem", "minuend", "subtrahend" ], outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. sub%M %binop', @@ -621,7 +633,7 @@ SubMem => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, - ins => [ "base", "index", "mem", "val" ], + ins => [ "base", "index", "mem", "subtrahend" ], emit => '. sub%M %SI3, %AM', units => [ "GP" ], latency => 1, @@ -633,7 +645,7 @@ SubMem8Bit => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, - ins => [ "base", "index", "mem", "val" ], + ins => [ "base", "index", "mem", "subtrahend" ], emit => '. sub%M %SB3, %AM', units => [ "GP" ], latency => 1, @@ -645,7 +657,7 @@ Sbb => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4 !in_r5", "flags", "none" ] }, - ins => [ "base", "index", "mem", "left", "right", "eflags" ], + ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ], outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. sbb%M %binop', @@ -657,23 +669,23 @@ Sbb => { l_Sub => { reg_req => { in => [ "none", "none" ], out => [ "none" ] }, - ins => [ "left", "right" ], + ins => [ "minuend", "subtrahend" ], }, l_Sbb => { reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, - ins => [ "left", "right", "eflags" ], + ins => [ "minuend", "subtrahend", "eflags" ], }, IDiv => { op_flags => "F|L", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax", "edx", "gp" ], + reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], out => [ "eax", "flags", "none", "edx", "none" ] }, - ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], + ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], - am => "source,ternary", - emit => ". idiv%M %unop5", + am => "source,unary", + emit => ". idiv%M %unop3", latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -682,12 +694,12 @@ IDiv => { Div => { op_flags => "F|L", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax", "edx", "gp" ], + reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], out => [ "eax", "flags", "none", "edx", "none" ] }, - ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], + ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], - am => "source,ternary", - emit => ". div%M %unop5", + am => "source,unary", + emit => ". div%M %unop3", latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -903,7 +915,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, @@ -915,12 +927,13 @@ Inc => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, + ins => [ "val" ], outs => [ "res", "flags" ], emit => '. inc %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, IncMem => { @@ -932,19 +945,20 @@ IncMem => { units => [ "GP" ], mode => "mode_M", latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, Dec => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, + ins => [ "val" ], outs => [ "res", "flags" ], emit => '. dec %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, DecMem => { @@ -956,7 +970,7 @@ DecMem => { units => [ "GP" ], mode => "mode_M", latency => 1, - modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] + modified_flags => $status_flags_wo_cf }, Not => { @@ -1007,9 +1021,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", @@ -1135,7 +1150,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, @@ -1175,7 +1190,7 @@ GetEIP => { Unknown_GP => { state => "pinned", - op_flags => "c", + op_flags => "c|NB", irn_flags => "I", reg_req => { out => [ "gp_UKNWN" ] }, units => [], @@ -1186,7 +1201,7 @@ Unknown_GP => { Unknown_VFP => { state => "pinned", - op_flags => "c", + op_flags => "c|NB", irn_flags => "I", reg_req => { out => [ "vfp_UKNWN" ] }, units => [], @@ -1198,18 +1213,18 @@ Unknown_VFP => { Unknown_XMM => { state => "pinned", - op_flags => "c", + op_flags => "c|NB", irn_flags => "I", reg_req => { out => [ "xmm_UKNWN" ] }, units => [], emit => "", latency => 0, - mode => "mode_E" + mode => $mode_xmm }, NoReg_GP => { state => "pinned", - op_flags => "c", + op_flags => "c|NB|NI", irn_flags => "I", reg_req => { out => [ "gp_NOREG" ] }, units => [], @@ -1220,7 +1235,7 @@ NoReg_GP => { NoReg_VFP => { state => "pinned", - op_flags => "c", + op_flags => "c|NB|NI", irn_flags => "I", reg_req => { out => [ "vfp_NOREG" ] }, units => [], @@ -1232,7 +1247,7 @@ NoReg_VFP => { NoReg_XMM => { state => "pinned", - op_flags => "c", + op_flags => "c|NB|NI", irn_flags => "I", reg_req => { out => [ "xmm_NOREG" ] }, units => [], @@ -1288,7 +1303,7 @@ FnstCWNOP => { Cltd => { # we should not rematrialize this node. It has very strict constraints. reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] }, - ins => [ "val", "globbered" ], + ins => [ "val", "clobbered" ], emit => '. cltd', latency => 1, mode => $mode_gp, @@ -1311,21 +1326,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", @@ -1365,11 +1365,11 @@ Lea => { Push => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp", "none" ] }, ins => [ "base", "index", "mem", "val", "stack" ], - emit => '. push%M %unop4', + emit => '. push%M %unop3', outs => [ "stack:I|S", "M" ], - am => "source,binary", + am => "source,unary", latency => 2, units => [ "GP" ], }, @@ -1403,7 +1403,7 @@ Enter => { }, Leave => { - reg_req => { in => [ "esp", "ebp" ], out => [ "ebp", "esp" ] }, + reg_req => { in => [ "ebp" ], out => [ "ebp", "esp" ] }, emit => '. leave', outs => [ "frame:I", "stack:I|S" ], latency => 3, @@ -1452,6 +1452,32 @@ LdTls => { latency => 1, }, +Bt => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] }, + ins => [ "left", "right" ], + 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", "fpcw", "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:I|S", "fpcw:I", "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 +}, #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # @@ -1469,7 +1495,16 @@ xZero => { emit => '. xorp%XSD %D0, %D0', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm +}, + +xPzero => { + irn_flags => "R", + reg_req => { out => [ "xmm" ] }, + emit => '. pxor %D0, %D0', + latency => 3, + units => [ "SSE" ], + mode => $mode_xmm }, # produces all 1 bits @@ -1479,7 +1514,7 @@ xAllOnes => { emit => '. pcmpeqb %D0, %D0', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, # integer shift left, dword @@ -1487,9 +1522,19 @@ xPslld => { irn_flags => "R", reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, emit => '. pslld %SI1, %D0', + latency => 3, units => [ "SSE" ], - mode => "mode_E", - latency => 1, + mode => $mode_xmm +}, + +# integer shift left, qword +xPsllq => { + irn_flags => "R", + reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, + emit => '. psllq %SI1, %D0', + latency => 3, + units => [ "SSE" ], + mode => $mode_xmm }, # integer shift right, dword @@ -1497,9 +1542,9 @@ xPsrld => { irn_flags => "R", reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, emit => '. psrld %SI1, %D0', - units => [ "SSE" ], - mode => "mode_E", latency => 1, + units => [ "SSE" ], + mode => $mode_xmm }, # mov from integer to SSE register @@ -1507,9 +1552,9 @@ xMovd => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "xmm" ] }, emit => '. movd %S0, %D0', - units => [ "SSE" ], - mode => "mode_E", latency => 1, + units => [ "SSE" ], + mode => $mode_xmm }, # commutative operations @@ -1523,7 +1568,7 @@ xAdd => { emit => '. add%XXM %binop', latency => 4, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMul => { @@ -1535,7 +1580,7 @@ xMul => { emit => '. mul%XXM %binop', latency => 4, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMax => { @@ -1547,7 +1592,7 @@ xMax => { emit => '. max%XXM %binop', latency => 2, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMin => { @@ -1559,7 +1604,7 @@ xMin => { emit => '. min%XXM %binop', latency => 2, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xAnd => { @@ -1571,7 +1616,7 @@ xAnd => { emit => '. andp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xOr => { @@ -1583,7 +1628,7 @@ xOr => { emit => '. orp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xXor => { @@ -1595,7 +1640,7 @@ xXor => { emit => '. xorp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, # not commutative operations @@ -1609,26 +1654,26 @@ xAndNot => { emit => '. andnp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xSub => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, - ins => [ "base", "index", "mem", "left", "right" ], + ins => [ "base", "index", "mem", "minuend", "subtrahend" ], am => "source,binary", emit => '. sub%XXM %binop', latency => 4, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xDiv => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5", "none" ] }, - ins => [ "base", "index", "mem", "left", "right" ], + ins => [ "base", "index", "mem", "dividend", "divisor" ], am => "source,binary", outs => [ "res", "M" ], emit => '. div%XXM %binop', @@ -1791,7 +1836,7 @@ Conv_I2FP => { am => "source,unary", latency => 10, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm, }, Conv_FP2I => { @@ -1811,7 +1856,7 @@ Conv_FP2FP => { am => "source,unary", latency => 8, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm, }, #----------------------------------------------------------# @@ -1859,7 +1904,7 @@ vfsub => { # irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] }, - ins => [ "base", "index", "mem", "left", "right", "fpcw" ], + ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ], am => "source,binary", latency => 4, units => [ "VFP" ], @@ -1870,7 +1915,7 @@ vfsub => { vfdiv => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none" ] }, - ins => [ "base", "index", "mem", "left", "right", "fpcw" ], + ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ], am => "source,binary", outs => [ "res", "M" ], latency => 20, @@ -1950,12 +1995,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" ] }, @@ -1966,11 +2005,15 @@ vfist => { attr_type => "ia32_x87_attr_t", }, -l_vfist => { - cmp_attr => "return 1;", +# SSE3 fisttp instruction +vfisttp => { state => "exc_pinned", - arity => 3, - mode => "mode_M", + reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]}, + ins => [ "base", "index", "mem", "val" ], + outs => [ "res", "M" ], + latency => 4, + units => [ "VFP" ], + attr_type => "ia32_x87_attr_t", }, @@ -2294,7 +2337,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, }, @@ -2303,7 +2346,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, @@ -2313,7 +2356,18 @@ 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, +}, + +# SSE3 firsttp instruction +fisttp => { + state => "exc_pinned", + rd_constructor => "NONE", + reg_req => { }, + emit => '. fisttp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2,