X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=f43c63df0205a10bd90ce90904b03bb04420abd4;hb=ded7d1acca9b4ec44bf5b0955f1247fef77f7541;hp=c669fcbc71517abfb578c3b7881b3928d1a49be3;hpb=68fafa84d901d4d48e7e54fa202c69e8e51f8f8c;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index c669fcbc7..f43c63df0 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -197,6 +197,7 @@ $arch = "ia32"; 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);", + 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);", @@ -213,8 +214,6 @@ $arch = "ia32"; AM => "${arch}_emit_am(node);", unop3 => "${arch}_emit_unop(node, 3);", unop4 => "${arch}_emit_unop(node, 4);", - unop5 => "${arch}_emit_unop(node, 5);", - DAM0 => "${arch}_emit_am_or_dest_register(node, 0);", binop => "${arch}_emit_binop(node);", x87_binop => "${arch}_emit_x87_binop(node);", CMP0 => "${arch}_emit_cmp_suffix_node(node, 0);", @@ -246,20 +245,10 @@ sub ia32_custom_init_attr { } if(defined($node->{am})) { my $am = $node->{am}; - if($am eq "full,binary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Full, ia32_am_binary);"; - } elsif($am eq "full,unary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Full, ia32_am_unary);"; - } elsif($am eq "source,unary") { + if($am eq "source,unary") { $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_unary);"; } elsif($am eq "source,binary") { $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_binary);"; - } elsif($am eq "dest,unary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);"; - } elsif($am eq "dest,binary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);"; - } elsif($am eq "dest,ternary") { - $res .= "\tset_ia32_am_support(res, ia32_am_Dest, ia32_am_ternary);"; } elsif($am eq "source,ternary") { $res .= "\tset_ia32_am_support(res, ia32_am_Source, ia32_am_ternary);"; } elsif($am eq "none") { @@ -343,6 +332,7 @@ Asm => { modified_flags => 1, }, +# "allocates" a free register ProduceVal => { op_flags => "c", irn_flags => "R", @@ -375,7 +365,7 @@ Add => { ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], emit => '. add%M %binop', - am => "full,binary", + am => "source,binary", units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -413,7 +403,7 @@ Adc => { ins => [ "base", "index", "mem", "left", "right", "eflags" ], outs => [ "res", "flags", "M" ], emit => '. adc%M %binop', - am => "full,binary", + am => "source,binary", units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -500,7 +490,7 @@ And => { ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], op_modes => "commutative | am | immediate | mode_neutral", - am => "full,binary", + am => "source,binary", emit => '. and%M %binop', units => [ "GP" ], latency => 1, @@ -539,7 +529,7 @@ Or => { out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], - am => "full,binary", + am => "source,binary", emit => '. or%M %binop', units => [ "GP" ], latency => 1, @@ -578,7 +568,7 @@ Xor => { out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], - am => "full,binary", + am => "source,binary", emit => '. xor%M %binop', units => [ "GP" ], latency => 1, @@ -617,9 +607,9 @@ 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 => "full,binary", + am => "source,binary", emit => '. sub%M %binop', units => [ "GP" ], latency => 1, @@ -631,7 +621,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, @@ -643,7 +633,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, @@ -655,9 +645,9 @@ 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 => "full,binary", + am => "source,binary", emit => '. sbb%M %binop', units => [ "GP" ], latency => 1, @@ -667,23 +657,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" ], - out => [ "eax", "flags", "none", "edx" ] }, - ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], - outs => [ "div_res", "flags", "M", "mod_res" ], + reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], + 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", - emit => ". idiv%M %unop5", + emit => ". idiv%M %unop3", latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -692,12 +682,12 @@ IDiv => { Div => { op_flags => "F|L", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax", "edx", "gp" ], - out => [ "eax", "flags", "none", "edx" ] }, - ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], - outs => [ "div_res", "flags", "M", "mod_res" ], + reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], + 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", - emit => ". div%M %unop5", + emit => ". div%M %unop3", latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -925,6 +915,7 @@ Inc => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, + ins => [ "val" ], outs => [ "res", "flags" ], emit => '. inc %S0', units => [ "GP" ], @@ -949,6 +940,7 @@ Dec => { irn_flags => "R", reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, + ins => [ "val" ], outs => [ "res", "flags" ], emit => '. dec %S0', units => [ "GP" ], @@ -1017,9 +1009,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", @@ -1145,7 +1138,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, @@ -1174,6 +1167,15 @@ Const => { mode => $mode_gp, }, +GetEIP => { + op_flags => "c", + reg_req => { out => [ "gp" ] }, + units => [ "GP" ], + latency => 5, + mode => $mode_gp, + modified_flags => $status_flags, +}, + Unknown_GP => { state => "pinned", op_flags => "c", @@ -1205,7 +1207,7 @@ Unknown_XMM => { units => [], emit => "", latency => 0, - mode => "mode_E" + mode => $mode_xmm }, NoReg_GP => { @@ -1289,7 +1291,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, @@ -1304,9 +1306,9 @@ Cltd => { Load => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_exc" ], latency => 0, emit => ". mov%SE%ME%.l %AM, %D0", units => [ "GP" ], @@ -1330,8 +1332,9 @@ l_Store => { Store => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%M %SI3, %AM', latency => 2, units => [ "GP" ], @@ -1341,8 +1344,9 @@ Store => { Store8Bit => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%M %SB3, %AM', latency => 2, units => [ "GP" ], @@ -1364,9 +1368,9 @@ 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", latency => 2, @@ -1375,11 +1379,20 @@ Push => { Pop => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "gp", "none", "none", "esp" ] }, - emit => '. pop%M %DAM0', + reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp" ] }, + ins => [ "mem", "stack" ], outs => [ "res", "M", "unused", "stack:I|S" ], + emit => '. pop%M %D0', + latency => 3, # Pop is more expensive than Push on Athlon + units => [ "GP" ], +}, + +PopMem => { + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp" ] }, ins => [ "base", "index", "mem", "stack" ], - am => "dest,unary", + outs => [ "unused0", "M", "unused1", "stack:I|S" ], + emit => '. pop%M %AM', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], }, @@ -1408,7 +1421,7 @@ AddSP => { am => "source,binary", emit => '. addl %binop', latency => 1, - outs => [ "stack:S", "M" ], + outs => [ "stack:I|S", "M" ], units => [ "GP" ], modified_flags => $status_flags }, @@ -1427,6 +1440,14 @@ SubSP => { modified_flags => $status_flags }, +RepPrefix => { + op_flags => "K", + state => "pinned", + mode => "mode_M", + emit => ". rep", + latency => 0, +}, + LdTls => { irn_flags => "R", reg_req => { out => [ "gp" ] }, @@ -1434,6 +1455,17 @@ 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 +}, #-----------------------------------------------------------------------------# # _____ _____ ______ __ _ _ _ # @@ -1444,13 +1476,73 @@ LdTls => { # |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ # #-----------------------------------------------------------------------------# +# produces a 0/+0.0 xZero => { irn_flags => "R", reg_req => { out => [ "xmm" ] }, 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 +xAllOnes => { + irn_flags => "R", + reg_req => { out => [ "xmm" ] }, + emit => '. pcmpeqb %D0, %D0', + latency => 3, + units => [ "SSE" ], + mode => $mode_xmm +}, + +# integer shift left, dword +xPslld => { + irn_flags => "R", + reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, + emit => '. pslld %SI1, %D0', + latency => 3, + units => [ "SSE" ], + 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 +xPsrld => { + irn_flags => "R", + reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, + emit => '. psrld %SI1, %D0', + latency => 1, + units => [ "SSE" ], + mode => $mode_xmm +}, + +# mov from integer to SSE register +xMovd => { + irn_flags => "R", + reg_req => { in => [ "gp" ], out => [ "xmm" ] }, + emit => '. movd %S0, %D0', + latency => 1, + units => [ "SSE" ], + mode => $mode_xmm }, # commutative operations @@ -1464,7 +1556,7 @@ xAdd => { emit => '. add%XXM %binop', latency => 4, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMul => { @@ -1476,7 +1568,7 @@ xMul => { emit => '. mul%XXM %binop', latency => 4, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMax => { @@ -1488,7 +1580,7 @@ xMax => { emit => '. max%XXM %binop', latency => 2, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xMin => { @@ -1500,7 +1592,7 @@ xMin => { emit => '. min%XXM %binop', latency => 2, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xAnd => { @@ -1512,7 +1604,7 @@ xAnd => { emit => '. andp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xOr => { @@ -1524,7 +1616,7 @@ xOr => { emit => '. orp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, xXor => { @@ -1536,7 +1628,7 @@ xXor => { emit => '. xorp%XSD %binop', latency => 3, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm }, # not commutative operations @@ -1550,26 +1642,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', @@ -1600,12 +1692,12 @@ Ucomi => { xLoad => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none", "none" ] }, ins => [ "base", "index", "mem" ], + outs => [ "res", "M", "X_exc" ], emit => '. mov%XXM %AM, %D0', attr => "ir_mode *load_mode", init_attr => "attr->ls_mode = load_mode;", - outs => [ "res", "M" ], latency => 0, units => [ "SSE" ], }, @@ -1613,8 +1705,9 @@ xLoad => { xStore => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%XXM %S3, %AM', latency => 0, units => [ "SSE" ], @@ -1731,7 +1824,7 @@ Conv_I2FP => { am => "source,unary", latency => 10, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm, }, Conv_FP2I => { @@ -1751,7 +1844,7 @@ Conv_FP2FP => { am => "source,unary", latency => 8, units => [ "SSE" ], - mode => "mode_E", + mode => $mode_xmm, }, #----------------------------------------------------------# @@ -1799,7 +1892,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" ], @@ -1810,7 +1903,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, @@ -1853,9 +1946,9 @@ vfld => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_exc" ], attr => "ir_mode *load_mode", init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, @@ -1867,8 +1960,9 @@ vfst => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], attr => "ir_mode *store_mode", init_attr => "attr->attr.ls_mode = store_mode;", latency => 2, @@ -1905,6 +1999,17 @@ vfist => { attr_type => "ia32_x87_attr_t", }, +# SSE3 fisttp instruction +vfisttp => { + state => "exc_pinned", + 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", +}, + l_vfist => { cmp_attr => "return 1;", state => "exc_pinned", @@ -2258,6 +2363,17 @@ fistp => { latency => 2, }, +# SSE3 firsttp instruction +fisttp => { + state => "exc_pinned", + rd_constructor => "NONE", + reg_req => { }, + emit => '. fisttp%M %AM', + mode => "mode_M", + attr_type => "ia32_x87_attr_t", + latency => 2, +}, + # constants fldz => {