X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=ffcb5e7f73a2dc723028e29b6ec06d8f9a6ab7fe;hb=aef4d3b28b21856e05c0bd91552b51b69ed5ac50;hp=c019c54fdf5a38c23ffb057549a90fc9846505f5;hpb=a89ce28d527ba6d9ae4069d1f86ae0f5edbb1f71;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index c019c54fd..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) @@ -270,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);", ); @@ -286,7 +293,6 @@ $arch = "ia32"; # |_| # #--------------------------------------------------# -$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);"; $default_attr_type = "ia32_attr_t"; %init_attr = ( @@ -297,13 +303,17 @@ $default_attr_type = "ia32_attr_t"; 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);" + "\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 => "return ia32_compare_attr(attr_a, attr_b);", - ia32_x87_attr_t => "return ia32_compare_x87_attr(attr_a, attr_b);", - ia32_asm_attr_t => "return ia32_compare_asm_attr(attr_a, attr_b);" + 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 = ( @@ -323,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, }, @@ -404,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 @@ -433,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 @@ -531,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" ], @@ -544,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" ], @@ -696,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 @@ -725,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" ] @@ -734,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" ] @@ -743,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 => [] @@ -875,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", @@ -886,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", @@ -897,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" ], @@ -935,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", }, @@ -945,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", }, @@ -962,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 => [], }, @@ -1206,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 @@ -1228,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, @@ -1239,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', @@ -1273,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 @@ -1308,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, @@ -1341,14 +1360,9 @@ vfCmpCMov => { 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, @@ -1396,7 +1410,8 @@ 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", @@ -1405,7 +1420,8 @@ vfadd => { 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", @@ -1420,7 +1436,8 @@ 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", @@ -1433,7 +1450,8 @@ 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" ], @@ -1447,7 +1465,8 @@ 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", @@ -1462,6 +1481,7 @@ l_vfprem => { vfabs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", @@ -1471,46 +1491,23 @@ vfabs => { vfchs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", attr_type => "ia32_x87_attr_t", }, -vfsin => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - -vfcos => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - -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 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", @@ -1520,6 +1517,9 @@ 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", @@ -1529,8 +1529,10 @@ vfst => { # 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", @@ -1543,7 +1545,9 @@ 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", @@ -1552,6 +1556,7 @@ vfist => { l_vfist => { cmp_attr => "return 1;", + state => "exc_pinned", arity => 3, mode => "mode_M", }, @@ -1791,30 +1796,6 @@ fchs => { attr_type => "ia32_x87_attr_t", }, -fsin => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsin', - attr_type => "ia32_x87_attr_t", -}, - -fcos => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fcos', - attr_type => "ia32_x87_attr_t", -}, - -fsqrt => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsqrt $', - attr_type => "ia32_x87_attr_t", -}, - # x87 Load and Store fld => { @@ -1858,6 +1839,7 @@ fild => { fist => { op_flags => "R", + state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, emit => '. fist%XM %AM', @@ -1867,6 +1849,7 @@ fist => { fistp => { op_flags => "R", + state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, emit => '. fistp%XM %AM',