X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=ffcb5e7f73a2dc723028e29b6ec06d8f9a6ab7fe;hb=aef4d3b28b21856e05c0bd91552b51b69ed5ac50;hp=68c196355300fb6d501509984dc7e618afc17095;hpb=774486f37ed015066db8a5a12492d924b25bfc1d;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 68c196355..ffcb5e7f7 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -33,6 +33,7 @@ $arch = "ia32"; # init_attr => "emit attribute initialization template" # rd_constructor => "c source code which constructs an ir_node" # latency => "latency of this operation (can be float)" +# attr_type => "name of the attribute struct", # }, # # ... # (all nodes you need to describe) @@ -121,6 +122,17 @@ $arch = "ia32"; { name => "gp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes { mode => "mode_Iu" } ], + mmx => [ + { name => "mm0", type => 4 }, + { name => "mm1", type => 4 }, + { name => "mm2", type => 4 }, + { name => "mm3", type => 4 }, + { name => "mm4", type => 4 }, + { name => "mm5", type => 4 }, + { name => "mm6", type => 4 }, + { name => "mm7", type => 4 }, + { mode => "mode_E" } + ], xmm => [ { name => "xmm0", type => 1 }, { name => "xmm1", type => 1 }, @@ -259,7 +271,13 @@ $arch = "ia32"; XXM => "${arch}_emit_xmm_mode_suffix(env, node);", XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);", AM => "${arch}_emit_am(env, node);", - unop => "${arch}_emit_unop(env, node);", + unop0 => "${arch}_emit_unop(env, node, 0);", + unop1 => "${arch}_emit_unop(env, node, 1);", + unop2 => "${arch}_emit_unop(env, node, 2);", + unop3 => "${arch}_emit_unop(env, node, 3);", + unop4 => "${arch}_emit_unop(env, node, 4);", + DAM0 => "${arch}_emit_am_or_dest_register(env, node, 0);", + DAM1 => "${arch}_emit_am_or_dest_register(env, node, 0);", binop => "${arch}_emit_binop(env, node);", x87_binop => "${arch}_emit_x87_binop(env, node);", ); @@ -275,9 +293,29 @@ $arch = "ia32"; # |_| # #--------------------------------------------------# -$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);"; $default_attr_type = "ia32_attr_t"; +%init_attr = ( + ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + ia32_x87_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n". + "\tinit_ia32_x87_attributes(res);", + ia32_asm_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n". + "\tinit_ia32_x87_attributes(res);". + "\tinit_ia32_asm_attributes(res);", + ia32_immediate_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n". + "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);" +); + +%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", +); + %operands = ( ); @@ -295,6 +333,8 @@ Immediate => { op_flags => "c", irn_flags => "I", reg_req => { out => [ "gp_NOREG" ] }, + attr => "ir_entity *symconst, int symconst_sign, long offset", + attr_type => "ia32_immediate_attr_t", mode => $mode_gp, }, @@ -302,6 +342,7 @@ Asm => { mode => "mode_T", arity => "variable", out_arity => "variable", + attr_type => "ia32_asm_attr_t", }, #-----------------------------------------------------------------# @@ -375,8 +416,9 @@ Mul => { # we should not rematrialize this node. It produces 2 results and has # very strict constrains reg_req => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] }, - emit => '. mul%M %unop', + emit => '. mul%M %unop3', outs => [ "EAX", "EDX", "M" ], + ins => [ "base", "index", "val_high", "val_low", "mem" ], latency => 10, units => [ "GP" ], modified_flags => $status_flags @@ -404,8 +446,9 @@ IMul => { IMul1OP => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] }, - emit => '. imul%M %unop', + emit => '. imul%M %unop3', outs => [ "EAX", "EDX", "M" ], + ins => [ "base", "index", "val_high", "val_low", "mem" ], latency => 5, units => [ "GP" ], modified_flags => $status_flags @@ -502,7 +545,7 @@ IDiv => { reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] }, attr => "ia32_op_flavour_t dm_flav", init_attr => "attr->data.op_flav = dm_flav;", - emit => ". idiv%M %unop", + emit => ". idiv%M %unop4", outs => [ "div_res", "mod_res", "M" ], latency => 25, units => [ "GP" ], @@ -515,7 +558,7 @@ Div => { reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] }, attr => "ia32_op_flavour_t dm_flav", init_attr => "attr->data.op_flav = dm_flav;", - emit => ". div%M %unop", + emit => ". div%M %unop4", outs => [ "div_res", "mod_res", "M" ], latency => 25, units => [ "GP" ], @@ -524,6 +567,9 @@ Div => { Shl => { irn_flags => "R", + # "in_r3" would be enough as out requirement, but the register allocator + # does strange things then and doesn't respect the constraint for in4 + # if the same value is attached to in3 and in4 (if you have "i << i" in C) reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] }, ins => [ "base", "index", "left", "right", "mem" ], emit => '. shl%M %binop', @@ -542,11 +588,12 @@ ShlD => { # Out requirements is: different from all in # This is because, out must be different from LowPart and ShiftCount. # We could say "!ecx !in_r4" but it can occur, that all values live through - # this Shift and the only value dying is the ShiftCount. Then there would be a - # register missing, as result must not be ecx and all other registers are - # occupied. What we should write is "!in_r4 !in_r5", but this is not supported - # (and probably never will). So we create artificial interferences of the result - # with all inputs, so the spiller can always assure a free register. + # this Shift and the only value dying is the ShiftCount. Then there would be + # a register missing, as result must not be ecx and all other registers are + # occupied. What we should write is "!in_r4 !in_r5", but this is not + # supported (and probably never will). So we create artificial interferences + # of the result with all inputs, so the spiller can always assure a free + # register. reg_req => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] }, emit => ' @@ -663,7 +710,8 @@ Rol => { Neg => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. neg%M %unop', + emit => '. neg%M %unop2', + ins => [ "base", "index", "val", "mem" ], units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags @@ -692,7 +740,7 @@ l_Neg => { Inc => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. inc%M %unop', + emit => '. inc%M %unop2', units => [ "GP" ], mode => $mode_gp, modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] @@ -701,7 +749,7 @@ Inc => { Dec => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. dec%M %unop', + emit => '. dec%M %unop2', units => [ "GP" ], mode => $mode_gp, modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] @@ -710,7 +758,8 @@ Dec => { Not => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. not%M %unop', + ins => [ "base", "index", "val", "mem" ], + emit => '. not%M %unop2', units => [ "GP" ], mode => $mode_gp, modified_flags => [] @@ -784,7 +833,8 @@ Unknown_VFP => { reg_req => { out => [ "vfp_UKNWN" ] }, units => [], emit => "", - mode => "mode_E" + mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, Unknown_XMM => { @@ -814,7 +864,8 @@ NoReg_VFP => { reg_req => { out => [ "vfp_NOREG" ] }, units => [], emit => "", - mode => "mode_E" + mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, NoReg_XMM => { @@ -840,7 +891,7 @@ ChangeCW => { FldCW => { op_flags => "L|F", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] }, latency => 5, emit => ". fldcw %AM", @@ -851,7 +902,7 @@ FldCW => { FnstCW => { op_flags => "L|F", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "fp_cw", "none" ], out => [ "none" ] }, latency => 5, emit => ". fnstcw %AM", @@ -862,19 +913,23 @@ FnstCW => { Cltd => { # we should not rematrialize this node. It produces 2 results and has # very strict constrains - reg_req => { in => [ "gp" ], out => [ "eax in_r1", "edx" ] }, + reg_req => { in => [ "eax" ], out => [ "edx" ] }, + ins => [ "val" ], emit => '. cltd', - outs => [ "EAX", "EDX" ], + mode => $mode_gp, units => [ "GP" ], }, # Load / Store +# +# Note that we add additional latency values depending on address mode, so a +# lateny of 0 for load is correct Load => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] }, - latency => 3, + latency => 0, emit => ". mov%SE%ME%.l %AM, %D0", outs => [ "res", "M" ], units => [ "GP" ], @@ -900,7 +955,7 @@ Store => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, emit => '. mov%M %binop', - latency => 3, + latency => 2, units => [ "GP" ], mode => "mode_M", }, @@ -910,7 +965,7 @@ Store8Bit => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] }, emit => '. mov%M %binop', - latency => 3, + latency => 2, units => [ "GP" ], mode => "mode_M", }, @@ -927,18 +982,20 @@ Lea => { Push => { reg_req => { in => [ "gp", "gp", "gp", "esp", "none" ], out => [ "esp", "none" ] }, - emit => '. push%M %unop', + emit => '. push%M %unop2', + ins => [ "base", "index", "val", "stack", "mem" ], outs => [ "stack:I|S", "M" ], - latency => 3, + latency => 2, units => [ "GP" ], modified_flags => [], }, Pop => { reg_req => { in => [ "gp", "gp", "esp", "none" ], out => [ "esp", "gp", "none" ] }, - emit => '. pop%M %unop', + emit => '. pop%M %DAM1', outs => [ "stack:I|S", "res", "M" ], - latency => 4, + ins => [ "base", "index", "stack", "mem" ], + latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], modified_flags => [], }, @@ -1171,7 +1228,7 @@ CvtSI2SS => { CvtSI2SD => { op_flags => "L|F", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "xmm" ] }, - emit => '. cvtsi2sd %unop', + emit => '. cvtsi2sd %unop2', latency => 2, units => [ "SSE" ], mode => $mode_xmm @@ -1193,7 +1250,7 @@ l_SSEtoX87 => { GetST0 => { op_flags => "L|F", irn_flags => "I", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "none" ] }, emit => '. fstp%XM %AM', latency => 4, @@ -1204,7 +1261,7 @@ GetST0 => { SetST0 => { op_flags => "L|F", irn_flags => "I", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "vf0", "none" ] }, ins => [ "base", "index", "mem" ], emit => '. fld%XM %AM', @@ -1238,12 +1295,14 @@ CopyB_i => { Conv_I2I => { reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] }, units => [ "GP" ], + ins => [ "base", "index", "val", "mem" ], mode => $mode_gp, modified_flags => $status_flags }, Conv_I2I8Bit => { reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] }, + ins => [ "base", "index", "val", "mem" ], units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags @@ -1273,14 +1332,9 @@ Conv_FP2FP => { CmpCMov => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] }, - latency => 2, - units => [ "GP" ], - mode => $mode_gp, -}, - -PsiCondCMov => { - irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp" ], out => [ "in_r3" ] }, + ins => [ "cmp_left", "cmp_right", "val_true", "val_false" ], + attr => "pn_Cmp pn_code", + init_attr => "attr->pn_code = pn_code;", latency => 2, units => [ "GP" ], mode => $mode_gp, @@ -1300,19 +1354,15 @@ vfCmpCMov => { latency => 10, units => [ "VFP" ], mode => $mode_gp, + attr_type => "ia32_x87_attr_t", }, CmpSet => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "eax ebx ecx edx" ] }, - latency => 2, - units => [ "GP" ], - mode => $mode_gp, -}, - -PsiCondSet => { - irn_flags => "R", - reg_req => { in => [ "gp" ], out => [ "eax ebx ecx edx" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem" ], + attr => "pn_Cmp pn_code", + init_attr => "attr->pn_code = pn_code;", latency => 2, units => [ "GP" ], mode => $mode_gp, @@ -1332,6 +1382,7 @@ vfCmpSet => { latency => 10, units => [ "VFP" ], mode => $mode_gp, + attr_type => "ia32_x87_attr_t", }, vfCMov => { @@ -1340,6 +1391,7 @@ vfCMov => { latency => 10, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, #----------------------------------------------------------# @@ -1358,18 +1410,22 @@ vfCMov => { vfadd => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfmul => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, l_vfmul => { @@ -1380,10 +1436,12 @@ l_vfmul => { vfsub => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, l_vfsub => { @@ -1392,10 +1450,12 @@ l_vfsub => { }, vfdiv => { - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp", "none" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp", "none" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], outs => [ "res", "M" ], latency => 20, units => [ "VFP" ], + attr_type => "ia32_x87_attr_t", }, l_vfdiv => { @@ -1405,10 +1465,12 @@ l_vfdiv => { }, vfprem => { - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 20, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, l_vfprem => { @@ -1419,41 +1481,21 @@ l_vfprem => { vfabs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfchs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", -}, - -vfsin => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", -}, - -vfcos => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", -}, - -vfsqrt => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 30, - units => [ "VFP" ], - mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, # virtual Load and Store @@ -1462,27 +1504,38 @@ vfld => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, + ins => [ "base", "index", "mem" ], outs => [ "res", "M" ], + attr => "ir_mode *store_mode", + init_attr => "attr->attr.ls_mode = store_mode;", latency => 2, units => [ "VFP" ], + attr_type => "ia32_x87_attr_t", }, vfst => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "vfp", "none" ] }, + ins => [ "base", "index", "val", "mem" ], + attr => "ir_mode *store_mode", + init_attr => "attr->attr.ls_mode = store_mode;", latency => 2, units => [ "VFP" ], mode => "mode_M", + attr_type => "ia32_x87_attr_t", }, # Conversions vfild => { + state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, outs => [ "res", "M" ], + ins => [ "base", "index", "mem" ], latency => 4, units => [ "VFP" ], + attr_type => "ia32_x87_attr_t", }, l_vfild => { @@ -1492,14 +1545,18 @@ l_vfild => { }, vfist => { + state => "exc_pinned", reg_req => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] }, + ins => [ "base", "index", "val", "fpcw", "mem" ], 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", }, @@ -1513,6 +1570,7 @@ vfldz => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfld1 => { @@ -1521,6 +1579,7 @@ vfld1 => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfldpi => { @@ -1529,6 +1588,7 @@ vfldpi => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfldln2 => { @@ -1537,6 +1597,7 @@ vfldln2 => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfldlg2 => { @@ -1545,6 +1606,7 @@ vfldlg2 => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfldl2t => { @@ -1553,6 +1615,7 @@ vfldl2t => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfldl2e => { @@ -1561,16 +1624,17 @@ vfldl2e => { latency => 4, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, vfConst => { op_flags => "c", irn_flags => "R", -# init_attr => " set_ia32_ls_mode(res, mode);", reg_req => { out => [ "vfp" ] }, latency => 3, units => [ "VFP" ], mode => "mode_E", + attr_type => "ia32_x87_attr_t", }, # other @@ -1582,6 +1646,7 @@ vfCondJmp => { outs => [ "false", "true", "temp_reg_eax" ], latency => 10, units => [ "VFP" ], + attr_type => "ia32_x87_attr_t", }, #------------------------------------------------------------------------# @@ -1600,6 +1665,7 @@ fadd => { rd_constructor => "NONE", reg_req => { }, emit => '. fadd%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, faddp => { @@ -1607,6 +1673,7 @@ faddp => { rd_constructor => "NONE", reg_req => { }, emit => '. faddp %x87_binop', + attr_type => "ia32_x87_attr_t", }, fmul => { @@ -1614,6 +1681,7 @@ fmul => { rd_constructor => "NONE", reg_req => { }, emit => '. fmul%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, fmulp => { @@ -1621,6 +1689,7 @@ fmulp => { rd_constructor => "NONE", reg_req => { }, emit => '. fmulp %x87_binop',, + attr_type => "ia32_x87_attr_t", }, fsub => { @@ -1628,6 +1697,7 @@ fsub => { rd_constructor => "NONE", reg_req => { }, emit => '. fsub%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, fsubp => { @@ -1636,6 +1706,7 @@ fsubp => { reg_req => { }, # see note about gas bugs emit => '. fsubrp %x87_binop', + attr_type => "ia32_x87_attr_t", }, fsubr => { @@ -1644,6 +1715,7 @@ fsubr => { irn_flags => "R", reg_req => { }, emit => '. fsubr%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, fsubrp => { @@ -1653,6 +1725,7 @@ fsubrp => { reg_req => { }, # see note about gas bugs emit => '. fsubp %x87_binop', + attr_type => "ia32_x87_attr_t", }, fprem => { @@ -1660,6 +1733,7 @@ fprem => { rd_constructor => "NONE", reg_req => { }, emit => '. fprem1', + attr_type => "ia32_x87_attr_t", }, # this node is just here, to keep the simulator running @@ -1669,6 +1743,7 @@ fpremp => { rd_constructor => "NONE", reg_req => { }, emit => '. fprem1', + attr_type => "ia32_x87_attr_t", }, fdiv => { @@ -1676,6 +1751,7 @@ fdiv => { rd_constructor => "NONE", reg_req => { }, emit => '. fdiv%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, fdivp => { @@ -1684,6 +1760,7 @@ fdivp => { reg_req => { }, # see note about gas bugs emit => '. fdivrp %x87_binop', + attr_type => "ia32_x87_attr_t", }, fdivr => { @@ -1691,6 +1768,7 @@ fdivr => { rd_constructor => "NONE", reg_req => { }, emit => '. fdivr%XM %x87_binop', + attr_type => "ia32_x87_attr_t", }, fdivrp => { @@ -1699,6 +1777,7 @@ fdivrp => { reg_req => { }, # see note about gas bugs emit => '. fdivp %x87_binop', + attr_type => "ia32_x87_attr_t", }, fabs => { @@ -1706,6 +1785,7 @@ fabs => { rd_constructor => "NONE", reg_req => { }, emit => '. fabs', + attr_type => "ia32_x87_attr_t", }, fchs => { @@ -1713,27 +1793,7 @@ fchs => { rd_constructor => "NONE", reg_req => { }, emit => '. fchs', -}, - -fsin => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsin', -}, - -fcos => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fcos', -}, - -fsqrt => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsqrt $', + attr_type => "ia32_x87_attr_t", }, # x87 Load and Store @@ -1744,6 +1804,7 @@ fld => { state => "exc_pinned", reg_req => { }, emit => '. fld%XM %AM', + attr_type => "ia32_x87_attr_t", }, fst => { @@ -1753,6 +1814,7 @@ fst => { reg_req => { }, emit => '. fst%XM %AM', mode => "mode_M", + attr_type => "ia32_x87_attr_t", }, fstp => { @@ -1762,6 +1824,7 @@ fstp => { reg_req => { }, emit => '. fstp%XM %AM', mode => "mode_M", + attr_type => "ia32_x87_attr_t", }, # Conversions @@ -1771,22 +1834,27 @@ fild => { rd_constructor => "NONE", reg_req => { }, emit => '. fild%XM %AM', + attr_type => "ia32_x87_attr_t", }, fist => { op_flags => "R", + state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, emit => '. fist%XM %AM', mode => "mode_M", + attr_type => "ia32_x87_attr_t", }, fistp => { op_flags => "R", + state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, emit => '. fistp%XM %AM', mode => "mode_M", + attr_type => "ia32_x87_attr_t", }, # constants @@ -1796,6 +1864,7 @@ fldz => { irn_flags => "R", reg_req => { }, emit => '. fldz', + attr_type => "ia32_x87_attr_t", }, fld1 => { @@ -1803,6 +1872,7 @@ fld1 => { irn_flags => "R", reg_req => { }, emit => '. fld1', + attr_type => "ia32_x87_attr_t", }, fldpi => { @@ -1810,6 +1880,7 @@ fldpi => { irn_flags => "R", reg_req => { }, emit => '. fldpi', + attr_type => "ia32_x87_attr_t", }, fldln2 => { @@ -1817,6 +1888,7 @@ fldln2 => { irn_flags => "R", reg_req => { }, emit => '. fldln2', + attr_type => "ia32_x87_attr_t", }, fldlg2 => { @@ -1824,6 +1896,7 @@ fldlg2 => { irn_flags => "R", reg_req => { }, emit => '. fldlg2', + attr_type => "ia32_x87_attr_t", }, fldl2t => { @@ -1831,6 +1904,7 @@ fldl2t => { irn_flags => "R", reg_req => { }, emit => '. fldll2t', + attr_type => "ia32_x87_attr_t", }, fldl2e => { @@ -1838,6 +1912,7 @@ fldl2e => { irn_flags => "R", reg_req => { }, emit => '. fldl2e', + attr_type => "ia32_x87_attr_t", }, # fxch, fpush, fpop @@ -1849,6 +1924,7 @@ fxch => { reg_req => { }, cmp_attr => "return 1;", emit => '. fxch %X0', + attr_type => "ia32_x87_attr_t", }, fpush => { @@ -1856,6 +1932,7 @@ fpush => { reg_req => {}, cmp_attr => "return 1;", emit => '. fld %X0', + attr_type => "ia32_x87_attr_t", }, fpushCopy => { @@ -1863,6 +1940,7 @@ fpushCopy => { reg_req => { in => [ "vfp"], out => [ "vfp" ] }, cmp_attr => "return 1;", emit => '. fld %X0', + attr_type => "ia32_x87_attr_t", }, fpop => { @@ -1870,6 +1948,7 @@ fpop => { reg_req => { }, cmp_attr => "return 1;", emit => '. fstp %X0', + attr_type => "ia32_x87_attr_t", }, # compare @@ -1877,31 +1956,37 @@ fpop => { fcomJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", }, fcompJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", }, fcomppJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", }, fcomrJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", }, fcomrpJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", }, fcomrppJmp => { op_flags => "L|X|Y", reg_req => { }, + attr_type => "ia32_x87_attr_t", },