X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=e33debbfa9fc6839aec051cfb3e8809476fbb094;hb=da230f5e2ba4806c03f611a3585154b316610bb4;hp=51ba13bf5a9e116ddad8d9e422b7bbcdc91dadac;hpb=8e779d23665105e51f6278f7ed461019bef813af;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 51ba13bf5..e33debbfa 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -253,6 +253,13 @@ $arch = "ia32"; S3 => "${arch}_emit_source_register(env, node, 3);", S4 => "${arch}_emit_source_register(env, node, 4);", S5 => "${arch}_emit_source_register(env, node, 5);", + SB1 => "${arch}_emit_8bit_source_register(env, node, 1);", + SB2 => "${arch}_emit_8bit_source_register(env, node, 2);", + SW0 => "${arch}_emit_16bit_source_register(env, node, 0);", + SI0 => "${arch}_emit_source_register_or_immediate(env, node, 0);", + SI1 => "${arch}_emit_source_register_or_immediate(env, node, 1);", + SI2 => "${arch}_emit_source_register_or_immediate(env, node, 2);", + SI3 => "${arch}_emit_source_register_or_immediate(env, node, 3);", D0 => "${arch}_emit_dest_register(env, node, 0);", D1 => "${arch}_emit_dest_register(env, node, 1);", D2 => "${arch}_emit_dest_register(env, node, 2);", @@ -262,7 +269,6 @@ $arch = "ia32"; X0 => "${arch}_emit_x87_name(env, node, 0);", X1 => "${arch}_emit_x87_name(env, node, 1);", X2 => "${arch}_emit_x87_name(env, node, 2);", - C => "${arch}_emit_immediate(env, node);", SE => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));", ME => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n ia32_emit_mode_suffix(env, node);", @@ -294,6 +300,7 @@ $arch = "ia32"; #--------------------------------------------------# $default_attr_type = "ia32_attr_t"; +$default_copy_attr = "ia32_copy_attr"; %init_attr = ( ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", @@ -333,8 +340,9 @@ Immediate => { op_flags => "c", irn_flags => "I", reg_req => { out => [ "gp_NOREG" ] }, - attr => "ir_entity *symconst, int symconst_sign, tarval *offset", + attr => "ir_entity *symconst, int symconst_sign, long offset", attr_type => "ia32_immediate_attr_t", + latency => 0, mode => $mode_gp, }, @@ -343,6 +351,18 @@ Asm => { arity => "variable", out_arity => "variable", attr_type => "ia32_asm_attr_t", + latency => 100, +}, + +ProduceVal => { + op_flags => "c", + irn_flags => "R", + reg_req => { out => [ "gp" ] }, + emit => "", + units => [ ], + latency => 0, + mode => $mode_gp, + cmp_attr => "return 1;", }, #-----------------------------------------------------------------# @@ -371,14 +391,26 @@ Add => { reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, ins => [ "base", "index", "left", "right", "mem" ], emit => '. add%M %binop', + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +AddMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "val", "mem" ], + emit => ". add%M %SI2, %AM", + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + Adc => { reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, emit => '. adc%M %binop', + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags @@ -391,8 +423,8 @@ Add64Bit => { emit => ' . movl %S0, %D0 . movl %S1, %D1 -. addl %S2, %D0 -. adcl %S3, %D1 +. addl %SI2, %D0 +. adcl %SI3, %D1 ', outs => [ "low_res", "high_res" ], units => [ "GP" ], @@ -419,6 +451,7 @@ Mul => { emit => '. mul%M %unop3', outs => [ "EAX", "EDX", "M" ], ins => [ "base", "index", "val_high", "val_low", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", latency => 10, units => [ "GP" ], modified_flags => $status_flags @@ -436,7 +469,9 @@ l_Mul => { IMul => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, + ins => [ "base", "index", "left", "right", "mem" ], emit => '. imul%M %binop', + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", latency => 5, units => [ "GP" ], mode => $mode_gp, @@ -449,44 +484,83 @@ IMul1OP => { emit => '. imul%M %unop3', outs => [ "EAX", "EDX", "M" ], ins => [ "base", "index", "val_high", "val_low", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", latency => 5, units => [ "GP" ], modified_flags => $status_flags }, l_IMul => { + # we should not rematrialize this node. It produces 2 results and has + # very strict constrains op_flags => "C", cmp_attr => "return 1;", + outs => [ "EAX", "EDX", "M" ], arity => 2 }, And => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", emit => '. and%M %binop', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +AndMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. and%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + Or => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", emit => '. or%M %binop', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +OrMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "val", "mem" ], + emit => '. or%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + Xor => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", emit => '. xor%M %binop', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +XorMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "val", "mem" ], + emit => '. xor%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + l_Xor => { op_flags => "C", cmp_attr => "return 1;", @@ -499,14 +573,28 @@ l_Xor => { Sub => { irn_flags => "R", reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", emit => '. sub%M %binop', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +SubMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "val", "mem" ], + emit => '. sub%M %SI2, %AM', + units => [ "GP" ], + mode => 'mode_M', + modified_flags => $status_flags +}, + Sbb => { reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3 !in_r4" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + init_attr => "set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);", emit => '. sbb%M %binop', units => [ "GP" ], mode => $mode_gp, @@ -520,8 +608,8 @@ Sub64Bit => { emit => ' . movl %S0, %D0 . movl %S1, %D1 -. subl %S2, %D0 -. sbbl %S3, %D1 +. subl %SI2, %D0 +. sbbl %SI3, %D1 ', outs => [ "low_res", "high_res" ], units => [ "GP" ], @@ -542,11 +630,15 @@ l_Sbb => { IDiv => { op_flags => "F|L", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] }, + reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], + out => [ "eax", "edx", "none" ] }, + ins => [ "base", "index", "left_low", "left_high", "right", "mem" ], + outs => [ "div_res", "mod_res", "M" ], attr => "ia32_op_flavour_t dm_flav", - init_attr => "attr->data.op_flav = dm_flav;", + init_attr => + "attr->data.op_flav = dm_flav;". + "set_ia32_am_support(res, ia32_am_Full, ia32_am_ternary);", emit => ". idiv%M %unop4", - outs => [ "div_res", "mod_res", "M" ], latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -555,11 +647,15 @@ IDiv => { Div => { op_flags => "F|L", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] }, + reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], + out => [ "eax", "edx", "none" ] }, + ins => [ "base", "index", "left_low", "left_high", "right", "mem" ], + outs => [ "div_res", "mod_res", "M" ], attr => "ia32_op_flavour_t dm_flav", - init_attr => "attr->data.op_flav = dm_flav;", + init_attr => + "attr->data.op_flav = dm_flav;". + "set_ia32_am_support(res, ia32_am_Full, ia32_am_ternary);", emit => ". div%M %unop4", - outs => [ "div_res", "mod_res", "M" ], latency => 25, units => [ "GP" ], modified_flags => $status_flags @@ -567,50 +663,49 @@ 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', + reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2" ] }, + ins => [ "left", "right" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);", + emit => '. shl %SB1, %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, -l_Shl => { +ShlMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "count", "mem" ], + emit => '. shl%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + +l_ShlDep => { cmp_attr => "return 1;", - arity => 2 + # value, cnt, dependency + arity => 3 }, ShlD => { - irn_flags => "R", + # FIXME: WHY? the right requirement is in_r3 !in_r5, especially this is the same as in Shl + # # 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. - reg_req => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] }, - emit => -' -if (get_ia32_immop_type(node) == ia32_ImmNone) { - if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shld%M %%cl, %S3, %AM - } else { - . shld%M %%cl, %S3, %S2 - } -} else { - if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shld%M %C, %S3, %AM - } else { - . shld%M %C, %S3, %S2 - } -} -', + # 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" ] }, + + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx" ], out => [ "in_r1 !in_r3" ] }, + ins => [ "left_high", "left_low", "right" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_ternary);", + emit => '. shld%M %SB2, %S1, %S0', latency => 6, units => [ "GP" ], mode => $mode_gp, @@ -624,20 +719,34 @@ l_ShlD => { Shr => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] }, - emit => '. shr%M %binop', + reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2" ] }, + ins => [ "val", "count" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);", + emit => '. shr %SB1, %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, -l_Shr => { +ShrMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "count", "mem" ], + emit => '. shr%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + +l_ShrDep => { cmp_attr => "return 1;", - arity => 2 + # value, cnt, dependency + arity => 3 }, ShrD => { - irn_flags => "R", + # FIXME: WHY? the right requirement is in_r3 !in_r5, especially this is the same as in Shr + # # 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 @@ -646,22 +755,13 @@ ShrD => { # 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 => ' -if (get_ia32_immop_type(node) == ia32_ImmNone) { - if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shrd%M %%cl, %S3, %AM - } else { - . shrd%M %%cl, %S3, %S2 - } -} else { - if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shrd%M %C, %S3, %AM - } else { - . shrd%M %C, %S3, %S2 - } -} -', + # reg_req => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] }, + + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx" ], out => [ "in_r1 !in_r3" ] }, + ins => [ "left_high", "left_low", "right" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_ternary);", + emit => '. shrd%M %SB2, %S1, %S0', latency => 6, units => [ "GP" ], mode => $mode_gp, @@ -675,57 +775,105 @@ l_ShrD => { Sar => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] }, - emit => '. sar%M %binop', + reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2" ] }, + ins => [ "val", "count" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);", + emit => '. sar %SB1, %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +SarMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "count", "mem" ], + emit => '. sar%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + l_Sar => { cmp_attr => "return 1;", + # value, cnt arity => 2 }, +l_SarDep => { + cmp_attr => "return 1;", + # value, cnt, dependency + arity => 3 +}, + Ror => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] }, - emit => '. ror%M %binop', + reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2" ] }, + ins => [ "val", "count" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);", + emit => '. ror %SB1, %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +RorMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "count", "mem" ], + emit => '. ror%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + Rol => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] }, - emit => '. rol%M %binop', + reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2" ] }, + ins => [ "val", "count" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_binary);", + emit => '. rol %SB1, %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +RolMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "ecx", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "count", "mem" ], + emit => '. rol%M %SI2, %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + # unary operations Neg => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. neg%M %unop2', - ins => [ "base", "index", "val", "mem" ], + reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, + emit => '. neg %S0', + ins => [ "val" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);", units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, +NegMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "mem" ], + emit => '. neg%M %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => $status_flags +}, + Minus64Bit => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp" ], out => [ "!in", "!in" ] }, - emit => ' -. movl %S0, %D0 -. movl %S0, %D1 -. subl %S1, %D0 -. sbbl %S2, %D1 -', + reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "gp" ] }, outs => [ "low_res", "high_res" ], units => [ "GP" ], modified_flags => $status_flags @@ -739,64 +887,126 @@ l_Neg => { Inc => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. inc%M %unop2', + reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);", + emit => '. inc %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] }, +IncMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "mem" ], + emit => '. inc%M %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] +}, + Dec => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - emit => '. dec%M %unop2', + reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);", + emit => '. dec %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] }, +DecMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "mem" ], + emit => '. dec%M %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ] +}, + Not => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] }, - ins => [ "base", "index", "val", "mem" ], - emit => '. not%M %unop2', + reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, + ins => [ "val" ], + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);", + emit => '. not %S0', units => [ "GP" ], mode => $mode_gp, modified_flags => [] }, +NotMem => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "mem" ], + emit => '. not%M %AM', + units => [ "GP" ], + mode => "mode_M", + modified_flags => [], +}, + # other operations -CondJmp => { +CmpJmp => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none"] }, + reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], + out => [ "none", "none"] }, + ins => [ "base", "index", "left", "right", "mem" ], outs => [ "false", "true" ], + attr => "long pnc", + init_attr => + "attr->pn_code = pnc;". + "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", latency => 3, units => [ "BRANCH" ], }, -TestJmp => { +CmpJmp8Bit => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "eax ebx ecx edx", + "none" ], + out => [ "none", "none"] }, + ins => [ "base", "index", "left", "right", "mem" ], outs => [ "false", "true" ], + attr => "long pnc", + init_attr => + "attr->pn_code = pnc;". + "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", latency => 3, units => [ "BRANCH" ], }, -CJmpAM => { +TestJmp => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], + out => [ "none", "none" ] }, + ins => [ "base", "index", "left", "right", "mem" ], outs => [ "false", "true" ], + attr => "long pnc", + init_attr => + "attr->pn_code = pnc;". + "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", + latency => 3, units => [ "BRANCH" ], }, -CJmp => { +TestJmp8Bit => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp", "gp" ] }, + reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "eax ebx ecx edx", + "none" ], + out => [ "none", "none" ] }, + ins => [ "base", "index", "left", "right", "mem" ], + outs => [ "false", "true" ], + attr => "long pnc", + init_attr => + "attr->pn_code = pnc;". + "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", + latency => 3, units => [ "BRANCH" ], }, @@ -806,6 +1016,17 @@ SwitchJmp => { reg_req => { in => [ "gp" ], out => [ "none" ] }, latency => 3, units => [ "BRANCH" ], + mode => "mode_T", +}, + +IJmp => { + state => "pinned", + op_flags => "X", + reg_req => { in => [ "gp" ] }, + emit => '. jmp *%S0', + units => [ "BRANCH" ], + mode => "mode_X", + modified_flags => [] }, Const => { @@ -813,6 +1034,8 @@ Const => { irn_flags => "R", reg_req => { out => [ "gp" ] }, units => [ "GP" ], + attr => "ir_entity *symconst, int symconst_sign, long offset", + attr_type => "ia32_immediate_attr_t", mode => $mode_gp, }, @@ -891,8 +1114,9 @@ ChangeCW => { FldCW => { op_flags => "L|F", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] }, + ins => [ "base", "index", "mem" ], latency => 5, emit => ". fldcw %AM", mode => $mode_fpcw, @@ -902,8 +1126,9 @@ FldCW => { FnstCW => { op_flags => "L|F", - state => "exc_pinned", + state => "pinned", reg_req => { in => [ "gp", "gp", "fp_cw", "none" ], out => [ "none" ] }, + ins => [ "base", "index", "fpcw", "mem" ], latency => 5, emit => ". fnstcw %AM", mode => "mode_M", @@ -913,21 +1138,26 @@ 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", "edx" ], out => [ "edx" ] }, + ins => [ "val", "globbered" ], 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, - emit => ". mov%SE%ME%.l %AM, %D0", + ins => [ "base", "index", "mem" ], outs => [ "res", "M" ], + latency => 0, + emit => ". mov%SE%ME%.l %AM, %D0", units => [ "GP" ], }, @@ -950,8 +1180,9 @@ Store => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] }, - emit => '. mov%M %binop', - latency => 3, + ins => [ "base", "index", "val", "mem" ], + emit => '. mov%M %SI2, %AM', + latency => 2, units => [ "GP" ], mode => "mode_M", }, @@ -960,15 +1191,16 @@ Store8Bit => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] }, - emit => '. mov%M %binop', - latency => 3, + emit => '. mov%M %SB2, %AM', + latency => 2, units => [ "GP" ], mode => "mode_M", }, Lea => { irn_flags => "R", - reg_req => { in => [ "gp", "gp" ], out => [ "in_r1" ] }, + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + ins => [ "base", "index" ], emit => '. leal %AM, %D0', latency => 2, units => [ "GP" ], @@ -981,7 +1213,8 @@ Push => { emit => '. push%M %unop2', ins => [ "base", "index", "val", "stack", "mem" ], outs => [ "stack:I|S", "M" ], - latency => 3, + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", + latency => 2, units => [ "GP" ], modified_flags => [], }, @@ -991,7 +1224,8 @@ Pop => { emit => '. pop%M %DAM1', outs => [ "stack:I|S", "res", "M" ], ins => [ "base", "index", "stack", "mem" ], - latency => 4, + init_attr => "set_ia32_am_support(res, ia32_am_Dest, ia32_am_unary);", + latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], modified_flags => [], }, @@ -1014,7 +1248,9 @@ Leave => { AddSP => { irn_flags => "I", + state => "pinned", reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] }, + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", emit => '. addl %binop', outs => [ "stack:S", "M" ], units => [ "GP" ], @@ -1022,10 +1258,13 @@ AddSP => { }, SubSP => { - irn_flags => "I", - reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] }, - emit => '. subl %binop', - outs => [ "stack:S", "M" ], +#irn_flags => "I", + state => "pinned", + reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "gp", "none" ] }, + init_attr => "set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);", + emit => ". subl %binop\n". + ". movl %%esp, %D1", + outs => [ "stack:I|S", "addr", "M" ], units => [ "GP" ], modified_flags => $status_flags }, @@ -1038,11 +1277,9 @@ LdTls => { # the int instruction int => { - reg_req => { in => [ "none" ], out => [ "none" ] }, + reg_req => { in => [ "gp" ], out => [ "none" ] }, mode => "mode_M", - attr => "tarval *tv", - init_attr => "\tset_ia32_Immop_tarval(res, tv);", - emit => '. int %C', + emit => '. int %SI0', units => [ "GP" ], cmp_attr => "return 1;", }, @@ -1057,6 +1294,15 @@ int => { # |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ # #-----------------------------------------------------------------------------# +xZero => { + irn_flags => "R", + reg_req => { out => [ "xmm" ] }, + emit => '. xorp%XSD %D1, %D1', + latency => 3, + units => [ "SSE" ], + mode => "mode_E", +}, + # commutative operations xAdd => { @@ -1160,25 +1406,18 @@ xCmp => { mode => "mode_E", }, -xCondJmp => { +xCmpJmp => { state => "pinned", op_flags => "L|X|Y", reg_req => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "none", "none" ] }, + ins => [ "base", "index", "left", "right", "mem" ], outs => [ "false", "true" ], + attr => "long pnc", + init_attr => "attr->pn_code = pnc;", latency => 5, units => [ "SSE" ], }, -xConst => { - op_flags => "c", - irn_flags => "R", - reg_req => { out => [ "xmm" ] }, - emit => '. mov%XXM %C, %D0', - latency => 2, - units => [ "SSE" ], - mode => "mode_E", -}, - # Load / Store xLoad => { @@ -1186,8 +1425,10 @@ xLoad => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] }, emit => '. mov%XXM %AM, %D0', + attr => "ir_mode *load_mode", + init_attr => "attr->ls_mode = load_mode;", outs => [ "res", "M" ], - latency => 2, + latency => 0, units => [ "SSE" ], }, @@ -1195,8 +1436,8 @@ xStore => { op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "xmm", "none" ] }, - emit => '. mov%XXM %binop', - latency => 2, + emit => '. mov%XXM %S2, %AM', + latency => 0, units => [ "SSE" ], mode => "mode_M", }, @@ -1207,7 +1448,7 @@ xStoreSimple => { reg_req => { in => [ "gp", "gp", "xmm", "none" ] }, ins => [ "base", "index", "val", "mem" ], emit => '. mov%XXM %S2, %AM', - latency => 2, + latency => 0, units => [ "SSE" ], mode => "mode_M", }, @@ -1243,29 +1484,6 @@ l_SSEtoX87 => { arity => 3, }, -GetST0 => { - op_flags => "L|F", - irn_flags => "I", - state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ] }, - emit => '. fstp%XM %AM', - latency => 4, - units => [ "SSE" ], - mode => "mode_M", -}, - -SetST0 => { - op_flags => "L|F", - irn_flags => "I", - state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "vf0", "none" ] }, - ins => [ "base", "index", "mem" ], - emit => '. fld%XM %AM', - outs => [ "res", "M" ], - latency => 2, - units => [ "SSE" ], -}, - # CopyB CopyB => { @@ -1289,18 +1507,24 @@ CopyB_i => { # Conversions Conv_I2I => { - reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] }, - units => [ "GP" ], - ins => [ "base", "index", "val", "mem" ], - mode => $mode_gp, + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] }, + units => [ "GP" ], + ins => [ "base", "index", "val", "mem" ], + attr => "ir_mode *smaller_mode", + init_attr => "attr->ls_mode = smaller_mode;", + 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, + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] }, + ins => [ "base", "index", "val", "mem" ], + units => [ "GP" ], + attr => "ir_mode *smaller_mode", + init_attr => "attr->ls_mode = smaller_mode;", + mode => $mode_gp, modified_flags => $status_flags }, @@ -1327,8 +1551,45 @@ Conv_FP2FP => { CmpCMov => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] }, - ins => [ "cmp_left", "cmp_right", "val_true", "val_false" ], + reg_req => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], out => [ "in_r7" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", "val_false" ], + attr => "pn_Cmp pn_code", + init_attr => "attr->pn_code = pn_code;", + latency => 2, + units => [ "GP" ], + mode => $mode_gp, +}, + +CmpCMov8Bit => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], out => [ "in_r7" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", "val_false" ], + attr => "pn_Cmp pn_code", + init_attr => "attr->pn_code = pn_code;", + latency => 2, + units => [ "GP" ], + mode => $mode_gp, +}, + +TestCMov => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], + out => [ "in_r7" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", + "val_false" ], + attr => "pn_Cmp pn_code", + init_attr => "attr->pn_code = pn_code;", + latency => 2, + units => [ "GP" ], + mode => $mode_gp, +}, + +TestCMov8Bit => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], + out => [ "in_r7" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", + "val_false" ], attr => "pn_Cmp pn_code", init_attr => "attr->pn_code = pn_code;", latency => 2, @@ -1346,16 +1607,58 @@ xCmpCMov => { vfCmpCMov => { irn_flags => "R", - reg_req => { in => [ "vfp", "vfp", "gp", "gp" ], out => [ "in_r4" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "gp", "gp" ], + out => [ "in_r7" ] }, + ins => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", + "val_false" ], latency => 10, - units => [ "VFP" ], + units => [ "VFP", "GP" ], 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" ] }, + reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], + 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, +}, + +CmpSet8Bit => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "eax ebx ecx edx", + "none" ], + 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, +}, + +TestSet => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], + 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, +}, + +TestSet8Bit => { + irn_flags => "R", + reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "eax ebx ecx edx", + "none" ], + 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;", @@ -1406,7 +1709,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", @@ -1415,7 +1719,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", @@ -1430,7 +1735,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", @@ -1443,7 +1749,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" ], @@ -1457,7 +1764,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", @@ -1472,6 +1780,7 @@ l_vfprem => { vfabs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", @@ -1481,46 +1790,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 *load_mode", + init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", @@ -1530,6 +1816,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", @@ -1539,8 +1828,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", @@ -1553,8 +1844,9 @@ l_vfild => { }, vfist => { - reg_req => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] }, state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] }, + ins => [ "base", "index", "val", "fpcw", "mem" ], latency => 4, units => [ "VFP" ], mode => "mode_M", @@ -1634,23 +1926,16 @@ vfldl2e => { attr_type => "ia32_x87_attr_t", }, -vfConst => { - op_flags => "c", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - latency => 3, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - # other -vfCondJmp => { +vfCmpJmp => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "none", "none", "eax" ] }, + reg_req => { in => [ "vfp", "vfp" ], out => [ "none", "none", "eax" ] }, + ins => [ "left", "right" ], outs => [ "false", "true", "temp_reg_eax" ], + attr => "long pnc", + init_attr => "attr->attr.pn_code = pnc;", latency => 10, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", @@ -1679,7 +1964,7 @@ faddp => { op_flags => "R", rd_constructor => "NONE", reg_req => { }, - emit => '. faddp %x87_binop', + emit => '. faddp%XM %x87_binop', attr_type => "ia32_x87_attr_t", }, @@ -1695,7 +1980,7 @@ fmulp => { op_flags => "R", rd_constructor => "NONE", reg_req => { }, - emit => '. fmulp %x87_binop',, + emit => '. fmulp%XM %x87_binop',, attr_type => "ia32_x87_attr_t", }, @@ -1712,7 +1997,7 @@ fsubp => { rd_constructor => "NONE", reg_req => { }, # see note about gas bugs - emit => '. fsubrp %x87_binop', + emit => '. fsubrp%XM %x87_binop', attr_type => "ia32_x87_attr_t", }, @@ -1731,7 +2016,7 @@ fsubrp => { irn_flags => "R", reg_req => { }, # see note about gas bugs - emit => '. fsubp %x87_binop', + emit => '. fsubp%XM %x87_binop', attr_type => "ia32_x87_attr_t", }, @@ -1766,7 +2051,7 @@ fdivp => { rd_constructor => "NONE", reg_req => { }, # see note about gas bugs - emit => '. fdivrp %x87_binop', + emit => '. fdivrp%XM %x87_binop', attr_type => "ia32_x87_attr_t", }, @@ -1783,7 +2068,7 @@ fdivrp => { rd_constructor => "NONE", reg_req => { }, # see note about gas bugs - emit => '. fdivp %x87_binop', + emit => '. fdivp%XM %x87_binop', attr_type => "ia32_x87_attr_t", }, @@ -1803,30 +2088,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 => { @@ -1864,7 +2125,7 @@ fild => { op_flags => "R", rd_constructor => "NONE", reg_req => { }, - emit => '. fild%XM %AM', + emit => '. fild%M %AM', attr_type => "ia32_x87_attr_t", }, @@ -1873,7 +2134,7 @@ fist => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fist%XM %AM', + emit => '. fist%M %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", }, @@ -1883,7 +2144,7 @@ fistp => { state => "exc_pinned", rd_constructor => "NONE", reg_req => { }, - emit => '. fistp%XM %AM', + emit => '. fistp%M %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", },