X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=bedbeb1af376bc757b112bda487a027c3caf77c8;hb=30b992a490bfdcccb934dbe90710b663898c001f;hp=2f5de98214959f3ef46ab6444c7c37628342ebbf;hpb=86c66a17beb4bdf09924135e6caf817960ef648c;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 2f5de9821..bedbeb1af 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -1,179 +1,68 @@ -# Creation: 2005/10/19 -# $Id$ # This is the specification for the ia32 assembler Firm-operations -use File::Basename; - -my $myname = $0; - -# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...) $arch = "ia32"; -# The node description is done as a perl hash initializer with the -# following structure: -# -# %nodes = ( -# -# => { -# op_flags => "N|L|C|X|I|F|Y|H|c|K|n", -# irn_flags => "R|N" -# arity => "0|1|2|3 ... |variable|dynamic|any", -# state => "floats|pinned|mem_pinned|exc_pinned", -# args => [ -# { type => "type 1", name => "name 1" }, -# { type => "type 2", name => "name 2" }, -# ... -# ], -# comment => "any comment for constructor", -# reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] }, -# cmp_attr => "c source code for comparing node attributes", -# outs => { "out1", "out2" } # optional, creates pn_op_out1, ... consts -# ins => { "in1", "in2" } # optional, creates n_op_in1, ... consts -# mode => "mode_Iu" # optional, predefines the mode -# emit => "emit code with templates", -# attr => "additional attribute arguments for constructor", -# init_attr => "emit attribute initialization template", -# hash_func => "name of the hash function for this operation", -# latency => "latency of this operation (can be float)" -# attr_type => "name of the attribute struct", -# modified_flags => [ "CF", ... ] # optional, list of modified flags -# }, -# -# ... # (all nodes you need to describe) -# -# ); # close the %nodes initializer - -# op_flags: flags for the operation, OPTIONAL (default is "N") -# the op_flags correspond to the firm irop_flags: -# N irop_flag_none -# L irop_flag_labeled -# C irop_flag_commutative -# X irop_flag_cfopcode -# I irop_flag_ip_cfopcode -# F irop_flag_fragile -# Y irop_flag_forking -# H irop_flag_highlevel -# c irop_flag_constlike -# K irop_flag_keep -# NB irop_flag_dump_noblock -# NI irop_flag_dump_noinput -# -# irn_flags: special node flags, OPTIONAL (default is 0) -# following irn_flags are supported: -# R rematerializeable -# N not spillable -# -# state: state of the operation, OPTIONAL (default is "floats") -# -# arity: arity of the operation, MUST NOT BE OMITTED -# -# args: the OPTIONAL arguments of the node constructor (debug, irg and block -# are always the first 3 arguments and are always autmatically -# created) -# If this key is missing the following arguments will be created: -# for i = 1 .. arity: ir_node *op_i -# ir_mode *mode -# -# outs: if a node defines more than one output, the names of the projections -# nodes having outs having automatically the mode mode_T -# example: [ "frame", "stack", "M" ] -# -# comment: OPTIONAL comment for the node constructor -# -# rd_constructor: for every operation there will be a -# new_rd__ function with the arguments from above -# which creates the ir_node corresponding to the defined operation -# you can either put the complete source code of this function here -# -# This key is OPTIONAL. If omitted, the following constructor will -# be created: -# if (!op__) assert(0); -# for i = 1 to arity -# set in[i] = op_i -# done -# res = new_ir_node(db, irg, block, op__, mode, arity, in) -# return res -# -# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3 -# +$mode_xmm = "mode_D"; +$mode_mmx = "mode_D"; +$mode_fp87 = "ia32_mode_E"; +$mode_gp = "mode_Iu"; +$mode_flags = "mode_Iu"; +$mode_fpcw = "ia32_mode_fpcw"; -# register types: -# 0 - no special type -# 1 - caller save (register must be saved by the caller of a function) -# 2 - callee save (register must be saved by the called function) -# 4 - ignore (do not automatically assign this register) -# 8 - emitter can choose an arbitrary register of this class -# 16 - the register is a virtual one -# 32 - register represents a state -# NOTE: Last entry of each class is the largest Firm-Mode a register can hold %reg_classes = ( gp => [ - { name => "edx", type => 1 }, - { name => "ecx", type => 1 }, - { name => "eax", type => 1 }, - { name => "ebx", type => 2 }, - { name => "esi", type => 2 }, - { name => "edi", type => 2 }, - { name => "ebp", type => 2 }, - { name => "esp", type => 4 }, - { name => "gp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes - { name => "gp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes - { mode => "mode_Iu" } + { name => "edx", dwarf => 2 }, + { name => "ecx", dwarf => 1 }, + { name => "eax", dwarf => 0 }, + { name => "ebx", dwarf => 3 }, + { name => "esi", dwarf => 6 }, + { name => "edi", dwarf => 7 }, + { name => "ebp", dwarf => 5 }, + { name => "esp", dwarf => 4, type => "ignore" }, + { name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes + { mode => $mode_gp } ], 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", flags => "manual_ra" } + { name => "mm0", dwarf => 29, type => "ignore" }, + { name => "mm1", dwarf => 30, type => "ignore" }, + { name => "mm2", dwarf => 31, type => "ignore" }, + { name => "mm3", dwarf => 32, type => "ignore" }, + { name => "mm4", dwarf => 33, type => "ignore" }, + { name => "mm5", dwarf => 34, type => "ignore" }, + { name => "mm6", dwarf => 35, type => "ignore" }, + { name => "mm7", dwarf => 36, type => "ignore" }, + { mode => $mode_mmx, flags => "manual_ra" } ], xmm => [ - { name => "xmm0", type => 1 }, - { name => "xmm1", type => 1 }, - { name => "xmm2", type => 1 }, - { name => "xmm3", type => 1 }, - { name => "xmm4", type => 1 }, - { name => "xmm5", type => 1 }, - { name => "xmm6", type => 1 }, - { name => "xmm7", type => 1 }, - { name => "xmm_NOREG", type => 4 | 16 }, # we need a dummy register for NoReg nodes - { name => "xmm_UKNWN", type => 4 | 8 | 16}, # we need a dummy register for Unknown nodes - { mode => "mode_E" } + { name => "xmm0", dwarf => 21 }, + { name => "xmm1", dwarf => 22 }, + { name => "xmm2", dwarf => 23 }, + { name => "xmm3", dwarf => 24 }, + { name => "xmm4", dwarf => 25 }, + { name => "xmm5", dwarf => 26 }, + { name => "xmm6", dwarf => 27 }, + { name => "xmm7", dwarf => 28 }, + { name => "xmm_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes + { mode => $mode_xmm } ], - vfp => [ - { name => "vf0", type => 1 }, - { name => "vf1", type => 1 }, - { name => "vf2", type => 1 }, - { name => "vf3", type => 1 }, - { name => "vf4", type => 1 }, - { name => "vf5", type => 1 }, - { name => "vf6", type => 1 }, - { name => "vf7", type => 1 }, - { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes - { name => "vfp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes - { mode => "mode_E" } - ], - st => [ - { name => "st0", realname => "st", type => 4 }, - { name => "st1", realname => "st(1)", type => 4 }, - { name => "st2", realname => "st(2)", type => 4 }, - { name => "st3", realname => "st(3)", type => 4 }, - { name => "st4", realname => "st(4)", type => 4 }, - { name => "st5", realname => "st(5)", type => 4 }, - { name => "st6", realname => "st(6)", type => 4 }, - { name => "st7", realname => "st(7)", type => 4 }, - { mode => "mode_E", flags => "manual_ra" } + fp => [ + { name => "st0", realname => "st", dwarf => 11 }, + { name => "st1", realname => "st(1)", dwarf => 12 }, + { name => "st2", realname => "st(2)", dwarf => 13 }, + { name => "st3", realname => "st(3)", dwarf => 14 }, + { name => "st4", realname => "st(4)", dwarf => 15 }, + { name => "st5", realname => "st(5)", dwarf => 16 }, + { name => "st6", realname => "st(6)", dwarf => 17 }, + { name => "st7", realname => "st(7)", dwarf => 18 }, + { name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes + { mode => $mode_fp87 } ], fp_cw => [ # the floating point control word - { name => "fpcw", type => 4|32 }, - { mode => "mode_fpcw", flags => "manual_ra|state" } + { name => "fpcw", dwarf => 37, type => "ignore | state" }, + { mode => $mode_fpcw, flags => "manual_ra | state" } ], flags => [ - { name => "eflags", type => 0 }, + { name => "eflags", dwarf => 9 }, { mode => "mode_Iu", flags => "manual_ra" } ], ); # %reg_classes @@ -190,43 +79,6 @@ $arch = "ia32"; bundels_per_cycle => 1 ); # vliw -%emit_templates = ( - S0 => "${arch}_emit_source_register(node, 0);", - S1 => "${arch}_emit_source_register(node, 1);", - S2 => "${arch}_emit_source_register(node, 2);", - S3 => "${arch}_emit_source_register(node, 3);", - SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);", - 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);", - SH0 => "${arch}_emit_8bit_high_source_register(node, 0);", - SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);", - SI0 => "${arch}_emit_source_register_or_immediate(node, 0);", - 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);", - DS0 => "${arch}_emit_dest_register_size(node, 0);", - DB0 => "${arch}_emit_8bit_dest_register(node, 0);", - X0 => "${arch}_emit_x87_register(node, 0);", - X1 => "${arch}_emit_x87_register(node, 1);", - EX => "${arch}_emit_extend_suffix(node);", - M => "${arch}_emit_mode_suffix(node);", - XM => "${arch}_emit_x87_mode_suffix(node);", - XXM => "${arch}_emit_xmm_mode_suffix(node);", - XSD => "${arch}_emit_xmm_mode_suffix_s(node);", - AM => "${arch}_emit_am(node);", - unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);", - unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);", - binop => "${arch}_emit_binop(node);", - x87_binop => "${arch}_emit_x87_binop(node);", - CMP0 => "${arch}_emit_cmp_suffix_node(node, 0);", - CMP3 => "${arch}_emit_cmp_suffix_node(node, 3);", -); - - - - $default_op_attr_type = "ia32_op_attr_t"; $default_attr_type = "ia32_attr_t"; $default_copy_attr = "ia32_copy_attr"; @@ -238,7 +90,7 @@ sub ia32_custom_init_attr { my $res = ""; if(defined($node->{modified_flags})) { - $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"; + $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"; } if(defined($node->{am})) { my $am = $node->{am}; @@ -264,49 +116,46 @@ $custom_init_attr_func = \&ia32_custom_init_attr; %init_attr = ( ia32_asm_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_x87_attributes(res);". "\tinit_ia32_asm_attributes(res);", ia32_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);", + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);", ia32_call_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_call_attributes(res, pop, call_tp);", ia32_condcode_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". - "\tinit_ia32_condcode_attributes(res, pnc);", + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". + "\tinit_ia32_condcode_attributes(res, condition_code);", + ia32_switch_attr_t => + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". + "\tinit_ia32_switch_attributes(res, switch_table);", ia32_copyb_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_copyb_attributes(res, size);", ia32_immediate_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);", ia32_x87_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_x87_attributes(res);", ia32_climbframe_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n". "\tinit_ia32_climbframe_attributes(res, count);", ); %compare_attr = ( - ia32_asm_attr_t => "ia32_compare_asm_attr", + ia32_asm_attr_t => "ia32_compare_asm_attr", ia32_attr_t => "ia32_compare_nodes_attr", ia32_call_attr_t => "ia32_compare_call_attr", ia32_condcode_attr_t => "ia32_compare_condcode_attr", ia32_copyb_attr_t => "ia32_compare_copyb_attr", + ia32_switch_attr_t => "ia32_compare_nodes_attr", ia32_immediate_attr_t => "ia32_compare_immediate_attr", ia32_x87_attr_t => "ia32_compare_x87_attr", ia32_climbframe_attr_t => "ia32_compare_climbframe_attr", ); -%operands = ( -); - -$mode_xmm = "mode_E"; -$mode_gp = "mode_Iu"; -$mode_flags = "mode_Iu"; -$mode_fpcw = "mode_fpcw"; $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ]; $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ]; $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", @@ -316,7 +165,8 @@ $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", Immediate => { state => "pinned", - op_flags => "c", + op_flags => [ "constlike" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "gp_NOREG:I" ] }, attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset", attr_type => "ia32_immediate_attr_t", @@ -339,8 +189,8 @@ Asm => { # "allocates" a free register ProduceVal => { - op_flags => "c|n", - irn_flags => "R", + op_flags => [ "constlike", "cse_neutral" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, emit => "", units => [ ], @@ -350,13 +200,13 @@ ProduceVal => { }, Add => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], - emit => '. add%M %binop', + emit => 'add%M %B', am => "source,binary", units => [ "GP" ], latency => 1, @@ -365,11 +215,11 @@ Add => { }, AddMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => ". add%M %SI3, %AM", + emit => "add%M %#S3, %AM", units => [ "GP" ], latency => 1, mode => "mode_M", @@ -377,11 +227,11 @@ AddMem => { }, AddMem8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => ". add%M %SB3, %AM", + emit => "add%M %#S3, %AM", units => [ "GP" ], latency => 1, mode => "mode_M", @@ -394,7 +244,7 @@ Adc => { out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right", "eflags" ], outs => [ "res", "flags", "M" ], - emit => '. adc%M %binop', + emit => 'adc%M %B', am => "source,binary", units => [ "GP" ], latency => 1, @@ -403,14 +253,15 @@ Adc => { }, l_Add => { - op_flags => "C", - reg_req => { in => [ "none", "none" ], out => [ "none" ] }, ins => [ "left", "right" ], + attr_type => "", + dump_func => "NULL", }, l_Adc => { - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "left", "right", "eflags" ], + attr_type => "", + dump_func => "NULL", }, Mul => { @@ -420,7 +271,7 @@ Mul => { reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], out => [ "eax", "flags", "none", "edx" ] }, ins => [ "base", "index", "mem", "left", "right" ], - emit => '. mul%M %unop4', + emit => 'mul%M %AS4', outs => [ "res_low", "flags", "M", "res_high" ], am => "source,binary", latency => 10, @@ -429,18 +280,14 @@ Mul => { }, l_Mul => { - # we should not rematrialize this node. It produces 2 results and has - # very strict constraints - op_flags => "C", - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none" ], - out => [ "none", "none", "none", "none" ] }, ins => [ "left", "right" ], outs => [ "res_low", "flags", "M", "res_high" ], + attr_type => "", + dump_func => "NULL", }, IMul => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", # TODO: adjust out requirements for the 3 operand form # (no need for should_be_same then) @@ -456,12 +303,12 @@ IMul => { }, IMul1OP => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], out => [ "eax", "flags", "none", "edx" ] }, ins => [ "base", "index", "mem", "left", "right" ], - emit => '. imul%M %unop4', + emit => 'imul%M %AS4', outs => [ "res_low", "flags", "M", "res_high" ], am => "source,binary", latency => 5, @@ -470,23 +317,21 @@ IMul1OP => { }, l_IMul => { - op_flags => "C", - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none" ], - out => [ "none", "none", "none", "none" ] }, ins => [ "left", "right" ], outs => [ "res_low", "flags", "M", "res_high" ], + attr_type => "", + dump_func => "NULL", }, And => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. and%M %binop', + emit => 'and%M %B', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -494,11 +339,11 @@ And => { }, AndMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. and%M %SI3, %AM', + emit => 'and%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -506,11 +351,11 @@ AndMem => { }, AndMem8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. and%M %SB3, %AM', + emit => 'and%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -518,14 +363,14 @@ AndMem8Bit => { }, Or => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. or%M %binop', + emit => 'or%M %B', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -533,11 +378,11 @@ Or => { }, OrMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. or%M %SI3, %AM', + emit => 'or%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -545,11 +390,11 @@ OrMem => { }, OrMem8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. or%M %SB3, %AM', + emit => 'or%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -557,14 +402,14 @@ OrMem8Bit => { }, Xor => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. xor%M %binop', + emit => 'xor%M %B', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -572,11 +417,11 @@ Xor => { }, Xor0 => { - op_flags => "c", - irn_flags => "R", + op_flags => [ "constlike" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp", "flags" ] }, outs => [ "res", "flags" ], - emit => ". xor%M %D0, %D0", + emit => "xor%M %D0, %D0", units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -584,11 +429,11 @@ Xor0 => { }, XorMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. xor%M %SI3, %AM', + emit => 'xor%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -596,11 +441,11 @@ XorMem => { }, XorMem8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. xor%M %SB3, %AM', + emit => 'xor%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -608,14 +453,14 @@ XorMem8Bit => { }, Sub => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "flags", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. sub%M %binop', + emit => 'sub%M %B', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -623,11 +468,11 @@ Sub => { }, SubMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "subtrahend" ], - emit => '. sub%M %SI3, %AM', + emit => 'sub%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => 'mode_M', @@ -635,11 +480,11 @@ SubMem => { }, SubMem8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "subtrahend" ], - emit => '. sub%M %SB3, %AM', + emit => 'sub%M %#S3, %AM', units => [ "GP" ], latency => 1, mode => 'mode_M', @@ -649,11 +494,11 @@ SubMem8Bit => { Sbb => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], - out => [ "in_r4 !in_r5", "flags", "none" ] }, + out => [ "in_r4", "flags", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. sbb%M %binop', + emit => 'sbb%M %B', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -662,10 +507,10 @@ Sbb => { Sbb0 => { # Spiller currently fails when rematerializing flag consumers - # irn_flags => "R", + # irn_flags => [ "rematerializable" ], reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] }, outs => [ "res", "flags" ], - emit => ". sbb%M %D0, %D0", + emit => "sbb%M %D0, %D0", units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -673,50 +518,52 @@ Sbb0 => { }, l_Sub => { - reg_req => { in => [ "none", "none" ], out => [ "none" ] }, ins => [ "minuend", "subtrahend" ], + attr_type => "", + dump_func => "NULL", }, l_Sbb => { - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "minuend", "subtrahend", "eflags" ], + attr_type => "", + dump_func => "NULL", }, IDiv => { - op_flags => "F|L", + op_flags => [ "fragile", "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], - out => [ "eax", "flags", "none", "edx", "none" ] }, + out => [ "eax", "flags", "none", "edx", "none", "none" ] }, ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], - outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], + outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ], am => "source,unary", - emit => ". idiv%M %unop3", + emit => "idiv%M %AS3", latency => 25, units => [ "GP" ], modified_flags => $status_flags }, Div => { - op_flags => "F|L", + op_flags => [ "fragile", "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ], - out => [ "eax", "flags", "none", "edx", "none" ] }, + out => [ "eax", "flags", "none", "edx", "none", "none" ] }, ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ], - outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], + outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ], am => "source,unary", - emit => ". div%M %unop3", + emit => "div%M %AS3", latency => 25, units => [ "GP" ], modified_flags => $status_flags }, Shl => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. shl%M %SB1, %S0', + emit => 'shl%M % [ "GP" ], latency => 1, mode => $mode_gp, @@ -724,49 +571,37 @@ Shl => { }, ShlMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "count" ], - emit => '. shl%M %SB3, %AM', + emit => 'shl%M % [ "GP" ], latency => 1, mode => "mode_M", modified_flags => $status_flags }, -l_ShlDep => { - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, - ins => [ "val", "count", "dep" ], -}, - ShlD => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "gp", "ecx" ], out => [ "in_r1 !in_r2 !in_r3", "flags" ] }, ins => [ "val_high", "val_low", "count" ], outs => [ "res", "flags" ], - emit => ". shld%M %SB2, %S1, %D0", + emit => "shld%M % 6, units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, -l_ShlD => { - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, - ins => [ "val_high", "val_low", "count" ], -}, - Shr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. shr%M %SB1, %S0', + emit => 'shr%M % [ "GP" ], mode => $mode_gp, latency => 1, @@ -774,49 +609,37 @@ Shr => { }, ShrMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "count" ], - emit => '. shr%M %SB3, %AM', + emit => 'shr%M % [ "GP" ], mode => "mode_M", latency => 1, modified_flags => $status_flags }, -l_ShrDep => { - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, - ins => [ "val", "count", "dep" ], -}, - ShrD => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "gp", "ecx" ], out => [ "in_r1 !in_r2 !in_r3", "flags" ] }, ins => [ "val_high", "val_low", "count" ], outs => [ "res", "flags" ], - emit => ". shrd%M %SB2, %S1, %D0", + emit => "shrd%M % 6, units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags }, -l_ShrD => { - cmp_attr => "return 1;", - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, - ins => [ "val_high", "val_low", "count" ], -}, - Sar => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. sar%M %SB1, %S0', + emit => 'sar%M % [ "GP" ], latency => 1, mode => $mode_gp, @@ -824,30 +647,24 @@ Sar => { }, SarMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "count" ], - emit => '. sar%M %SB3, %AM', + emit => 'sar%M % [ "GP" ], latency => 1, mode => "mode_M", modified_flags => $status_flags }, -l_SarDep => { - cmp_attr => "return 1;", - ins => [ "val", "count", "dep" ], - reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, -}, - Ror => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. ror%M %SB1, %S0', + emit => 'ror%M % [ "GP" ], latency => 1, mode => $mode_gp, @@ -855,11 +672,11 @@ Ror => { }, RorMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "count" ], - emit => '. ror%M %SB3, %AM', + emit => 'ror%M % [ "GP" ], latency => 1, mode => "mode_M", @@ -867,12 +684,12 @@ RorMem => { }, Rol => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], outs => [ "res", "flags" ], - emit => '. rol%M %SB1, %S0', + emit => 'rol%M % [ "GP" ], latency => 1, mode => $mode_gp, @@ -880,11 +697,11 @@ Rol => { }, RolMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "count" ], - emit => '. rol%M %SB3, %AM', + emit => 'rol%M % [ "GP" ], latency => 1, mode => "mode_M", @@ -892,10 +709,10 @@ RolMem => { }, Neg => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, - emit => '. neg%M %S0', + emit => 'neg%M %S0', ins => [ "val" ], outs => [ "res", "flags" ], units => [ "GP" ], @@ -905,11 +722,11 @@ Neg => { }, NegMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], - emit => '. neg%M %AM', + emit => 'neg%M %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -917,7 +734,7 @@ NegMem => { }, Minus64Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] }, outs => [ "low_res", "high_res" ], units => [ "GP" ], @@ -927,12 +744,12 @@ Minus64Bit => { Inc => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], outs => [ "res", "flags" ], - emit => '. inc%M %S0', + emit => 'inc%M %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, @@ -940,11 +757,11 @@ Inc => { }, IncMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], - emit => '. inc%M %AM', + emit => 'inc%M %AM', units => [ "GP" ], mode => "mode_M", latency => 1, @@ -952,12 +769,12 @@ IncMem => { }, Dec => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], outs => [ "res", "flags" ], - emit => '. dec%M %S0', + emit => 'dec%M %S0', units => [ "GP" ], mode => $mode_gp, latency => 1, @@ -965,11 +782,11 @@ Dec => { }, DecMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], - emit => '. dec%M %AM', + emit => 'dec%M %AM', units => [ "GP" ], mode => "mode_M", latency => 1, @@ -977,12 +794,12 @@ DecMem => { }, Not => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], - out => [ "in_r1", "flags" ] }, + out => [ "in_r1" ] }, ins => [ "val" ], - outs => [ "res", "flags" ], - emit => '. not%M %S0', + outs => [ "res" ], + emit => 'not%M %S0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -990,11 +807,11 @@ Not => { }, NotMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], - emit => '. not%M %AM', + emit => 'not%M %AM', units => [ "GP" ], latency => 1, mode => "mode_M", @@ -1003,7 +820,7 @@ NotMem => { Cmc => { reg_req => { in => [ "flags" ], out => [ "flags" ] }, - emit => '.cmc', + emit => 'cmc', units => [ "GP" ], latency => 1, mode => $mode_flags, @@ -1012,7 +829,7 @@ Cmc => { Stc => { reg_req => { out => [ "flags" ] }, - emit => '.stc', + emit => 'stc', units => [ "GP" ], latency => 1, mode => $mode_flags, @@ -1020,17 +837,16 @@ Stc => { }, Cmp => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "eflags", "unused", "M" ], am => "source,binary", - emit => '. cmp%M %binop', - attr => "int ins_permuted, int cmp_unsigned", - init_attr => "attr->data.ins_permuted = ins_permuted;\n". - "\tattr->data.cmp_unsigned = cmp_unsigned;\n", + emit => 'cmp%M %B', + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, @@ -1038,35 +854,47 @@ Cmp => { }, Cmp8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "eflags", "unused", "M" ], am => "source,binary", - emit => '. cmpb %binop', - attr => "int ins_permuted, int cmp_unsigned", - init_attr => "attr->data.ins_permuted = ins_permuted;\n". - "\tattr->data.cmp_unsigned = cmp_unsigned;\n", + emit => 'cmpb %B', + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, modified_flags => $status_flags }, +XorHighLow => { + irn_flags => [ "rematerializable" ], + state => "exc_pinned", + reg_req => { in => [ "eax ebx ecx edx" ], + out => [ "in_r1", "flags" ] }, + emit => 'xorb %>S0, % [ "value" ], + outs => [ "res", "flags" ], + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags, +}, + Test => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "eflags", "unused", "M" ], am => "source,binary", - emit => '. test%M %binop', - attr => "int ins_permuted, int cmp_unsigned", - init_attr => "attr->data.ins_permuted = ins_permuted;\n". - "\tattr->data.cmp_unsigned = cmp_unsigned;\n", + emit => 'test%M %B', + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, @@ -1074,17 +902,16 @@ Test => { }, Test8Bit => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "eflags", "unused", "M" ], am => "source,binary", - emit => '. testb %binop', - attr => "int ins_permuted, int cmp_unsigned", - init_attr => "attr->data.ins_permuted = ins_permuted;\n". - "\tattr->data.cmp_unsigned = cmp_unsigned;\n", + emit => 'testb %B', + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, @@ -1092,34 +919,40 @@ Test8Bit => { }, Setcc => { - #irn_flags => "R", + #irn_flags => [ "rematerializable" ], reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] }, ins => [ "eflags" ], outs => [ "res" ], attr_type => "ia32_condcode_attr_t", - attr => "pn_Cmp pnc", - init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", + attr => "ia32_condition_code_t condition_code", + # The way we handle Setcc with float nodes (potentially) destroys the flags + # (when we emit the setX; setp; orb and the setX;setnp;andb sequences) + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n" + . "\tif (condition_code & ia32_cc_additional_float_cases) {\n" + . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n" + . "\t\t/* attr->latency = 3; */\n" + . "\t}\n", latency => 1, units => [ "GP" ], mode => $mode_gp, }, SetccMem => { - #irn_flags => "R", + #irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] }, ins => [ "base", "index", "mem","eflags" ], attr_type => "ia32_condcode_attr_t", - attr => "pn_Cmp pnc", + attr => "ia32_condition_code_t condition_code", init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", - emit => '. set%CMP3 %AM', + emit => 'set%P3 %AM', latency => 1, units => [ "GP" ], mode => 'mode_M', }, CMovcc => { - #irn_flags => "R", + #irn_flags => [ "rematerializable" ], state => "exc_pinned", # (note: leave the false,true order intact to make it compatible with other # ia32_binary ops) @@ -1129,7 +962,7 @@ CMovcc => { outs => [ "res", "flags", "M" ], am => "source,binary", attr_type => "ia32_condcode_attr_t", - attr => "pn_Cmp pnc", + attr => "ia32_condition_code_t condition_code", latency => 1, units => [ "GP" ], mode => $mode_gp, @@ -1137,33 +970,32 @@ CMovcc => { Jcc => { state => "pinned", - op_flags => "L|X|Y", + op_flags => [ "cfopcode", "forking" ], reg_req => { in => [ "eflags" ], out => [ "none", "none" ] }, ins => [ "eflags" ], outs => [ "false", "true" ], attr_type => "ia32_condcode_attr_t", - attr => "pn_Cmp pnc", + attr => "ia32_condition_code_t condition_code", latency => 2, units => [ "BRANCH" ], }, SwitchJmp => { state => "pinned", - op_flags => "L|X|Y", - reg_req => { in => [ "gp" ] }, - mode => "mode_T", - attr_type => "ia32_condcode_attr_t", - attr => "long pnc", - latency => 3, + op_flags => [ "cfopcode", "forking" ], + reg_req => { in => [ "gp", "gp" ] }, + ins => [ "base", "index" ], + out_arity => "variable", + attr_type => "ia32_switch_attr_t", + attr => "const ir_switch_table *switch_table", + latency => 2, units => [ "BRANCH" ], - modified_flags => $status_flags, - init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements }, Jmp => { state => "pinned", - irn_flags => "J", - op_flags => "X", + irn_flags => [ "simple_jump" ], + op_flags => [ "cfopcode" ], reg_req => { out => [ "none" ] }, latency => 1, units => [ "BRANCH" ], @@ -1172,21 +1004,23 @@ Jmp => { IJmp => { state => "pinned", - op_flags => "X", - reg_req => { in => [ "gp", "gp", "none", "gp" ] }, + op_flags => [ "cfopcode", "unknown_jump" ], + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "none", "flags", "none" ] }, ins => [ "base", "index", "mem", "target" ], + outs => [ "jmp", "flags", "M" ], am => "source,unary", - emit => '. jmp *%unop3', + emit => 'jmp %*AS3', latency => 1, units => [ "BRANCH" ], mode => "mode_X", - init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements }, Const => { - op_flags => "c", - irn_flags => "R", + op_flags => [ "constlike" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, + emit => "movl %I, %D0", units => [ "GP" ], attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset", attr_type => "ia32_immediate_attr_t", @@ -1194,8 +1028,17 @@ Const => { mode => $mode_gp, }, +Unknown => { + op_flags => [ "constlike" ], + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "gp" ] }, + latency => 0, + emit => '', + mode => $mode_gp, +}, + GetEIP => { - op_flags => "c", + op_flags => [ "constlike" ], reg_req => { out => [ "gp" ] }, units => [ "GP" ], latency => 5, @@ -1203,40 +1046,10 @@ GetEIP => { modified_flags => $status_flags, }, -Unknown_GP => { - state => "pinned", - op_flags => "c|NB", - reg_req => { out => [ "gp_UKNWN:I" ] }, - units => [], - emit => "", - latency => 0, - mode => $mode_gp -}, - -Unknown_VFP => { - state => "pinned", - op_flags => "c|NB", - reg_req => { out => [ "vfp_UKNWN:I" ] }, - units => [], - emit => "", - mode => "mode_E", - latency => 0, - attr_type => "ia32_x87_attr_t", -}, - -Unknown_XMM => { - state => "pinned", - op_flags => "c|NB", - reg_req => { out => [ "xmm_UKNWN:I" ] }, - units => [], - emit => "", - latency => 0, - mode => $mode_xmm -}, - NoReg_GP => { state => "pinned", - op_flags => "c|NB|NI", + op_flags => [ "constlike", "dump_noblock" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "gp_NOREG:I" ] }, units => [], emit => "", @@ -1244,30 +1057,33 @@ NoReg_GP => { mode => $mode_gp }, -NoReg_VFP => { +NoReg_FP => { state => "pinned", - op_flags => "c|NB|NI", - reg_req => { out => [ "vfp_NOREG:I" ] }, + op_flags => [ "constlike", "dump_noblock" ], + irn_flags => [ "not_scheduled" ], + reg_req => { out => [ "fp_NOREG:I" ] }, units => [], emit => "", - mode => "mode_E", + mode => $mode_fp87, latency => 0, attr_type => "ia32_x87_attr_t", }, NoReg_XMM => { state => "pinned", - op_flags => "c|NB|NI", + op_flags => [ "constlike", "dump_noblock" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "xmm_NOREG:I" ] }, units => [], emit => "", latency => 0, - mode => "mode_E" + mode => $mode_xmm, }, ChangeCW => { state => "pinned", - op_flags => "c", + op_flags => [ "constlike" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "fpcw:I" ] }, mode => $mode_fpcw, latency => 3, @@ -1276,30 +1092,30 @@ ChangeCW => { }, FldCW => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] }, ins => [ "base", "index", "mem" ], latency => 5, - emit => ". fldcw %AM", + emit => "fldcw %AM", mode => $mode_fpcw, units => [ "GP" ], modified_flags => $fpcw_flags }, FnstCW => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "fpcw" ], latency => 5, - emit => ". fnstcw %AM", + emit => "fnstcw %AM", mode => "mode_M", units => [ "GP" ], }, FnstCWNOP => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "pinned", reg_req => { in => [ "fp_cw" ], out => [ "none" ] }, ins => [ "fpcw" ], @@ -1312,7 +1128,7 @@ Cltd => { # we should not rematrialize this node. It has very strict constraints. reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] }, ins => [ "val", "clobbered" ], - emit => '. cltd', + emit => 'cltd', latency => 1, mode => $mode_gp, units => [ "GP" ], @@ -1324,46 +1140,46 @@ Cltd => { # lateny of 0 for load is correct Load => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], - out => [ "gp", "none", "none", "none" ] }, + out => [ "gp", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "unused", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_regular", "X_except" ], latency => 0, - emit => ". mov%EX%.l %AM, %D0", + emit => "mov%#Ml %AM, %D0", units => [ "GP" ], }, Store => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M", "X_exc" ], - emit => '. mov%M %SI3, %AM', + outs => [ "M", "X_regular", "X_except" ], + emit => 'mov%M %#S3, %AM', latency => 2, units => [ "GP" ], - mode => "mode_M", }, Store8Bit => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], + out => ["none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M", "X_exc" ], - emit => '. mov%M %SB3, %AM', + outs => [ "M", "X_regular", "X_except" ], + emit => 'mov%M %#S3, %AM', latency => 2, units => [ "GP" ], - mode => "mode_M", }, Lea => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, ins => [ "base", "index" ], - emit => '. leal %AM, %D0', + emit => 'leal %AM, %D0', latency => 2, units => [ "GP" ], mode => $mode_gp, @@ -1376,19 +1192,30 @@ Push => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] }, ins => [ "base", "index", "mem", "val", "stack" ], - emit => '. push%M %unop3', + emit => 'push%M %AS3', outs => [ "stack", "M" ], am => "source,unary", latency => 2, units => [ "GP" ], }, +PushEax => { + state => "exc_pinned", + reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] }, + ins => [ "stack" ], + outs => [ "stack" ], + emit => 'pushl %%eax', + latency => 2, + units => [ "GP" ], + mode => $mode_gp, +}, + Pop => { state => "exc_pinned", reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] }, ins => [ "mem", "stack" ], outs => [ "res", "M", "unused", "stack" ], - emit => '. pop%M %D0', + emit => 'pop%M %D0', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], }, @@ -1398,24 +1225,35 @@ PopEbp => { reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] }, ins => [ "mem", "stack" ], outs => [ "res", "M", "unused", "stack" ], - emit => '. pop%M %D0', + emit => 'pop%M %D0', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], }, +CopyEbpEsp => { + state => "exc_pinned", + reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] }, + ins => [ "ebp" ], + outs => [ "esp" ], + emit => 'movl %S0, %D0', + latency => 1, + units => [ "GP" ], + mode => $mode_gp, +}, + PopMem => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] }, ins => [ "base", "index", "mem", "stack" ], outs => [ "unused0", "M", "unused1", "stack" ], - emit => '. pop%M %AM', + emit => 'pop%M %AM', latency => 3, # Pop is more expensive than Push on Athlon units => [ "GP" ], }, Enter => { reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] }, - emit => '. enter', + emit => 'enter', outs => [ "frame", "stack", "M" ], latency => 15, units => [ "GP" ], @@ -1423,10 +1261,11 @@ Enter => { Leave => { reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] }, - emit => '. leave', + emit => 'leave', outs => [ "frame", "stack" ], latency => 3, units => [ "GP" ], + state => "exc_pinned", }, AddSP => { @@ -1434,7 +1273,7 @@ AddSP => { reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] }, ins => [ "base", "index", "mem", "stack", "size" ], am => "source,binary", - emit => '. addl %binop', + emit => 'addl %B', latency => 1, outs => [ "stack", "M" ], units => [ "GP" ], @@ -1446,8 +1285,8 @@ SubSP => { reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] }, ins => [ "base", "index", "mem", "stack", "size" ], am => "source,binary", - emit => ". subl %binop\n". - ". movl %%esp, %D1", + emit => "subl %B\n". + "movl %%esp, %D1", latency => 2, outs => [ "stack", "addr", "M" ], units => [ "GP" ], @@ -1455,17 +1294,19 @@ SubSP => { }, RepPrefix => { - op_flags => "K", + op_flags => [ "keep" ], state => "pinned", mode => "mode_M", - emit => ". rep", + emit => "rep", latency => 0, }, LdTls => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, units => [ "GP" ], + emit => "movl %%gs:0, %D0", + mode => $mode_gp, latency => 1, }, @@ -1473,11 +1314,11 @@ LdTls => { # BT supports source address mode, but this is unused yet # Bt => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] }, ins => [ "left", "right" ], - emit => '. bt%M %S1, %S0', + emit => 'bt%M %S1, %S0', units => [ "GP" ], latency => 1, mode => $mode_flags, @@ -1485,14 +1326,14 @@ Bt => { }, Bsf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, ins => [ "base", "index", "mem", "operand" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. bsf%M %unop3, %D0', + emit => 'bsf%M %AS3, %D0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -1500,14 +1341,14 @@ Bsf => { }, Bsr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, ins => [ "base", "index", "mem", "operand" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. bsr%M %unop3, %D0', + emit => 'bsr%M %AS3, %D0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -1518,14 +1359,14 @@ Bsr => { # SSE4.2 or SSE4a popcnt instruction # Popcnt => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, ins => [ "base", "index", "mem", "operand" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. popcnt%M %unop3, %D0', + emit => 'popcnt%M %AS3, %D0', units => [ "GP" ], latency => 1, mode => $mode_gp, @@ -1533,13 +1374,15 @@ Popcnt => { }, Call => { + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ], - out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ] + out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ] }, ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ], - outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ], + outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ], + emit => "call %*AS3", attr_type => "ia32_call_attr_t", attr => "unsigned pop, ir_type *call_tp", am => "source,unary", @@ -1568,10 +1411,11 @@ ClimbFrame => { # bswap # Bswap => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, - emit => '. bswap%M %S0', + outs => [ "res" ], + emit => 'bswap%M %S0', ins => [ "val" ], units => [ "GP" ], latency => 1, @@ -1582,10 +1426,10 @@ Bswap => { # bswap16, use xchg here # Bswap16 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "eax ebx ecx edx" ], out => [ "in_r1" ] }, - emit => '. xchg %SB0, %SH0', + emit => 'xchg %S0', ins => [ "val" ], units => [ "GP" ], latency => 1, @@ -1600,7 +1444,7 @@ Breakpoint => { reg_req => { in => [ "none" ], out => [ "none" ] }, ins => [ "mem" ], latency => 0, - emit => ". int3", + emit => "int3", units => [ "GP" ], mode => mode_M, }, @@ -1613,7 +1457,7 @@ UD2 => { reg_req => { in => [ "none" ], out => [ "none" ] }, ins => [ "mem" ], latency => 0, - emit => ". .value 0x0b0f", + emit => "ud2", units => [ "GP" ], mode => mode_M, }, @@ -1622,11 +1466,11 @@ UD2 => { # outport # Outport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, ins => [ "port", "value", "mem" ], - emit => '. out%M %SS0, %SI1', + emit => 'out%M %^S0, %#S1', units => [ "GP" ], latency => 1, mode => mode_M, @@ -1637,12 +1481,12 @@ Outport => { # inport # Inport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, ins => [ "port", "mem" ], outs => [ "res", "M" ], - emit => '. in%M %DS0, %SS0', + emit => 'in%M %#D0, %^S0', units => [ "GP" ], latency => 1, mode => mode_T, @@ -1653,46 +1497,46 @@ Inport => { # Intel style prefetching # Prefetch0 => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetcht0 %AM", + emit => "prefetcht0 %AM", units => [ "GP" ], }, Prefetch1 => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetcht1 %AM", + emit => "prefetcht1 %AM", units => [ "GP" ], }, Prefetch2 => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetcht2 %AM", + emit => "prefetcht2 %AM", units => [ "GP" ], }, PrefetchNTA => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetchnta %AM", + emit => "prefetchnta %AM", units => [ "GP" ], }, @@ -1700,41 +1544,50 @@ PrefetchNTA => { # 3DNow! prefetch instructions # Prefetch => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetch %AM", + emit => "prefetch %AM", units => [ "GP" ], }, PrefetchW => { - op_flags => "L|F", + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetchw %AM", + emit => "prefetchw %AM", units => [ "GP" ], }, # produces a 0/+0.0 xZero => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, - emit => '. xorp%XSD %D0, %D0', + emit => 'xorp%FX %D0, %D0', latency => 3, units => [ "SSE" ], mode => $mode_xmm }, +xUnknown => { + op_flags => [ "constlike" ], + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "xmm" ] }, + emit => '', + latency => 0, + mode => $mode_xmm +}, + xPzero => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, - emit => '. pxor %D0, %D0', + emit => 'pxor %D0, %D0', latency => 3, units => [ "SSE" ], mode => $mode_xmm @@ -1742,9 +1595,9 @@ xPzero => { # produces all 1 bits xAllOnes => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, - emit => '. pcmpeqb %D0, %D0', + emit => 'pcmpeqb %D0, %D0', latency => 3, units => [ "SSE" ], mode => $mode_xmm @@ -1752,9 +1605,9 @@ xAllOnes => { # integer shift left, dword xPslld => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, - emit => '. pslld %SI1, %D0', + emit => 'pslld %#S1, %D0', latency => 3, units => [ "SSE" ], mode => $mode_xmm @@ -1762,9 +1615,9 @@ xPslld => { # integer shift left, qword xPsllq => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, - emit => '. psllq %SI1, %D0', + emit => 'psllq %#S1, %D0', latency => 3, units => [ "SSE" ], mode => $mode_xmm @@ -1772,9 +1625,9 @@ xPsllq => { # integer shift right, dword xPsrld => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] }, - emit => '. psrld %SI1, %D0', + emit => 'psrld %#S1, %D0', latency => 1, units => [ "SSE" ], mode => $mode_xmm @@ -1782,164 +1635,164 @@ xPsrld => { # mov from integer to SSE register xMovd => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "xmm" ] }, - emit => '. movd %S0, %D0', + emit => 'movd %S0, %D0', latency => 1, units => [ "SSE" ], mode => $mode_xmm }, xAdd => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. add%XXM %binop', + emit => 'adds%FX %B', latency => 4, units => [ "SSE" ], mode => $mode_xmm }, xMul => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. mul%XXM %binop', + emit => 'muls%FX %B', latency => 4, units => [ "SSE" ], mode => $mode_xmm }, xMax => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. max%XXM %binop', + emit => 'maxs%FX %B', latency => 2, units => [ "SSE" ], mode => $mode_xmm }, xMin => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. min%XXM %binop', + emit => 'mins%FX %B', latency => 2, units => [ "SSE" ], mode => $mode_xmm }, xAnd => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. andp%XSD %binop', + emit => 'andp%FX %B', latency => 3, units => [ "SSE" ], mode => $mode_xmm }, xOr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. orp%XSD %binop', + emit => 'orp%FX %B', latency => 3, units => [ "SSE" ], mode => $mode_xmm }, xXor => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. xorp%XSD %binop', + emit => 'xorp%FX %B', latency => 3, units => [ "SSE" ], mode => $mode_xmm }, xAndNot => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. andnp%XSD %binop', + emit => 'andnp%FX %B', latency => 3, units => [ "SSE" ], mode => $mode_xmm }, xSub => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4", "flags", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. sub%XXM %binop', + emit => 'subs%FX %B', latency => 4, units => [ "SSE" ], mode => $mode_xmm }, xDiv => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "dividend", "divisor" ], outs => [ "res", "flags", "M" ], am => "source,binary", - emit => '. div%XXM %binop', + emit => 'divs%FX %B', latency => 16, units => [ "SSE" ], }, Ucomi => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "eflags" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "flags" ], am => "source,binary", - attr => "int ins_permuted", + attr => "bool ins_permuted", init_attr => "attr->data.ins_permuted = ins_permuted;", - emit => ' .ucomi%XXM %binop', + emit => 'ucomis%FX %B', latency => 3, units => [ "SSE" ], mode => $mode_flags, @@ -1947,13 +1800,13 @@ Ucomi => { }, xLoad => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], - out => [ "xmm", "none", "none", "none" ] }, + out => [ "xmm", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "unused", "M", "X_exc" ], - emit => '. mov%XXM %AM, %D0', + outs => [ "res", "unused", "M", "X_regular", "X_except" ], + emit => 'movs%FX %AM, %D0', attr => "ir_mode *load_mode", init_attr => "attr->ls_mode = load_mode;", latency => 0, @@ -1961,48 +1814,46 @@ xLoad => { }, xStore => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M", "X_exc" ], - emit => '. mov%XXM %S3, %AM', + outs => [ "M", "X_regular", "X_except" ], + emit => 'movs%FX %S3, %AM', latency => 0, units => [ "SSE" ], - mode => "mode_M", }, xStoreSimple => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M" ], - emit => '. mov%XXM %S3, %AM', + outs => [ "M", "X_regular", "X_except" ], + emit => 'movs%FX %S3, %AM', latency => 0, units => [ "SSE" ], - mode => "mode_M", }, CvtSI2SS => { - op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], am => "source,unary", - emit => '. cvtsi2ss %unop3, %D0', + emit => 'cvtsi2ss %AS3, %D0', latency => 2, units => [ "SSE" ], mode => $mode_xmm }, CvtSI2SD => { - op_flags => "L|F", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], am => "source,unary", - emit => '. cvtsi2sd %unop3, %D0', + emit => 'cvtsi2sd %AS3, %D0', latency => 2, units => [ "SSE" ], mode => $mode_xmm @@ -2010,42 +1861,44 @@ CvtSI2SD => { l_LLtoFloat => { - op_flags => "L|F", - cmp_attr => "return 1;", ins => [ "val_high", "val_low" ], - reg_req => { in => [ "none", "none" ], out => [ "none" ] } + attr_type => "", + dump_func => "NULL", }, l_FloattoLL => { - op_flags => "L|F", - cmp_attr => "return 1;", ins => [ "val" ], outs => [ "res_high", "res_low" ], - reg_req => { in => [ "none" ], out => [ "none", "none" ] } + attr_type => "", + dump_func => "NULL", }, CopyB => { - op_flags => "F|H", + op_flags => [ "uses_memory", "fragile" ], state => "pinned", - reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] }, - outs => [ "DST", "SRC", "CNT", "M" ], + reg_req => { in => [ "edi", "esi", "ecx", "none" ], + out => [ "edi", "esi", "ecx", "none", "none", "none" ] }, + ins => [ "dest", "source", "count", "mem" ], + outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ], attr_type => "ia32_copyb_attr_t", attr => "unsigned size", units => [ "GP" ], - latency => 3, + latency => 3, # we don't care about this flag, so no need to mark this node # modified_flags => [ "DF" ] }, CopyB_i => { - op_flags => "F|H", + op_flags => [ "uses_memory", "fragile" ], state => "pinned", - reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] }, - outs => [ "DST", "SRC", "M" ], + reg_req => { in => [ "edi", "esi", "none" ], + out => [ "edi", "esi", "none", "none", "none" ] }, + ins => [ "dest", "source", "mem" ], + outs => [ "dest", "source", "M", "X_regular", "X_except" ], attr_type => "ia32_copyb_attr_t", attr => "unsigned size", units => [ "GP" ], - latency => 3, + latency => 3, # we don't care about this flag, so no need to mark this node # modified_flags => [ "DF" ] }, @@ -2055,18 +1908,20 @@ Cwtl => { reg_req => { in => [ "eax" ], out => [ "eax" ] }, ins => [ "val" ], outs => [ "res" ], - emit => '. cwtl', + emit => 'cwtl', units => [ "GP" ], latency => 1, mode => $mode_gp, }, Conv_I2I => { + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], - out => [ "gp", "none", "none" ] }, + out => [ "gp", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "res", "flags", "M" ], + outs => [ "res", "flags", "M", "X_regular", "X_except" ], + emit => "mov%#Ml %#AS3, %D0", am => "source,unary", units => [ "GP" ], latency => 1, @@ -2076,11 +1931,13 @@ Conv_I2I => { }, Conv_I2I8Bit => { + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], - out => [ "gp", "none", "none" ] }, + out => [ "gp", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "res", "flags", "M" ], + outs => [ "res", "flags", "M", "X_regular", "X_except" ], + emit => "mov%#Ml %#AS3, %D0", am => "source,unary", units => [ "GP" ], latency => 1, @@ -2122,97 +1979,105 @@ Conv_FP2FP => { # rematerialisation disabled for all float nodes for now, because the fpcw # handler runs before spilling and we might end up with wrong fpcw then -vfadd => { -# irn_flags => "R", +fadd => { +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], - out => [ "vfp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ], + out => [ "fp", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right", "fpcw" ], outs => [ "res", "dummy", "M" ], + emit => 'fadd%FP%FM %AF', am => "source,binary", latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfmul => { -# irn_flags => "R", +fmul => { +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], - out => [ "vfp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ], + out => [ "fp", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right", "fpcw" ], outs => [ "res", "dummy", "M" ], + emit => 'fmul%FP%FM %AF', am => "source,binary", latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfsub => { -# irn_flags => "R", +fsub => { +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], - out => [ "vfp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ], + out => [ "fp", "none", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ], outs => [ "res", "dummy", "M" ], + emit => 'fsub%FR%FP%FM %AF', am => "source,binary", latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfdiv => { +fdiv => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], - out => [ "vfp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ], + out => [ "fp", "none", "none" ] }, ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ], outs => [ "res", "dummy", "M" ], + emit => 'fdiv%FR%FP%FM %AF', am => "source,binary", latency => 20, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", }, -vfprem => { - reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] }, +fprem => { + reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] }, ins => [ "left", "right", "fpcw" ], + emit => 'fprem1', latency => 20, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfabs => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, +fabs => { + irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp"], out => [ "fp" ] }, ins => [ "value" ], + emit => 'fabs', latency => 2, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfchs => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, +fchs => { + irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp"], out => [ "fp" ] }, + emit => 'fchs', ins => [ "value" ], latency => 2, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfld => { - irn_flags => "R", - op_flags => "L|F", +fld => { + irn_flags => [ "rematerializable" ], + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], - out => [ "vfp", "none", "none", "none" ] }, + out => [ "fp", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "unused", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_regular", "X_except" ], + emit => 'fld%FM %AM', attr => "ir_mode *load_mode", init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, @@ -2220,133 +2085,165 @@ vfld => { attr_type => "ia32_x87_attr_t", }, -vfst => { - irn_flags => "R", - op_flags => "L|F", +fst => { + irn_flags => [ "rematerializable" ], + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ], - out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp" ], + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M", "X_exc" ], + outs => [ "M", "X_regular", "X_except" ], + emit => 'fst%FP%FM %AM', 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", }, -vfild => { +fild => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], - out => [ "vfp", "none", "none" ] }, + out => [ "fp", "none", "none" ] }, outs => [ "res", "unused", "M" ], ins => [ "base", "index", "mem" ], + emit => 'fild%FM %AM', latency => 4, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", }, -vfist => { +fist => { + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], out => [ "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ], + out => [ "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val", "fpcw" ], - outs => [ "M" ], + outs => [ "dummy", "M", "X_regular", "X_except" ], + emit => 'fist%FP%FM %AM', latency => 4, units => [ "VFP" ], - mode => "mode_M", attr_type => "ia32_x87_attr_t", }, # SSE3 fisttp instruction -vfisttp => { +fisttp => { + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]}, + reg_req => { in => [ "gp", "gp", "none", "fp" ], + out => [ "in_r4", "none", "none", "none" ]}, ins => [ "base", "index", "mem", "val" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_regular", "X_except" ], + emit => 'fisttp%FM %AM', latency => 4, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", }, -vfldz => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldz => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, outs => [ "res" ], + emit => 'fldz', latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfld1 => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fld1 => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, outs => [ "res" ], + emit => 'fld1', latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfldpi => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldpi => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, outs => [ "res" ], + emit => 'fldpi', latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfldln2 => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldln2 => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, outs => [ "res" ], + emit => 'fldln2', latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfldlg2 => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldlg2 => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, + emit => 'fldlg2', outs => [ "res" ], latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfldl2t => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldl2t => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, + emit => 'fldll2t', outs => [ "res" ], latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, attr_type => "ia32_x87_attr_t", }, -vfldl2e => { - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, +fldl2e => { + irn_flags => [ "rematerializable" ], + reg_req => { out => [ "fp" ] }, + emit => 'fldl2e', outs => [ "res" ], latency => 4, units => [ "VFP" ], - mode => "mode_E", + mode => $mode_fp87, + attr_type => "ia32_x87_attr_t", +}, + +FucomFnstsw => { +# we can't allow to rematerialize this node so we don't +# accidently produce Phi(Fucom, Fucom(ins_permuted)) +# irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] }, + ins => [ "left", "right" ], + outs => [ "flags" ], + emit => "fucom%FP %F0\n". + "fnstsw %%ax", + attr => "bool ins_permuted", + init_attr => "attr->attr.data.ins_permuted = ins_permuted;", + latency => 3, + units => [ "VFP" ], attr_type => "ia32_x87_attr_t", + mode => $mode_gp }, -vFucomFnstsw => { +FucomppFnstsw => { # we can't allow to rematerialize this node so we don't # accidently produce Phi(Fucom, Fucom(ins_permuted)) -# irn_flags => "R", - reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] }, +# irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] }, ins => [ "left", "right" ], outs => [ "flags" ], - attr => "int ins_permuted", + emit => "fucompp\n". + "fnstsw %%ax", + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2354,12 +2251,13 @@ vFucomFnstsw => { mode => $mode_gp }, -vFucomi => { - irn_flags => "R", - reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] }, +Fucomi => { + irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] }, ins => [ "left", "right" ], outs => [ "flags" ], - attr => "int ins_permuted", + emit => 'fucom%FPi %F0', + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2367,12 +2265,14 @@ vFucomi => { mode => $mode_gp }, -vFtstFnstsw => { -# irn_flags => "R", - reg_req => { in => [ "vfp" ], out => [ "eax" ] }, +FtstFnstsw => { +# irn_flags => [ "rematerializable" ], + reg_req => { in => [ "fp" ], out => [ "eax" ] }, ins => [ "left" ], outs => [ "flags" ], - attr => "int ins_permuted", + emit => "ftst\n". + "fnstsw %%ax", + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2381,420 +2281,112 @@ vFtstFnstsw => { }, Sahf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "eax" ], out => [ "eflags" ] }, ins => [ "val" ], outs => [ "flags" ], - emit => '. sahf', + emit => 'sahf', latency => 1, units => [ "GP" ], mode => $mode_flags, }, -fadd => { - state => "exc_pinned", - emit => '. fadd%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -faddp => { - state => "exc_pinned", - emit => '. faddp%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fmul => { - state => "exc_pinned", - emit => '. fmul%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fmulp => { - state => "exc_pinned", - emit => '. fmulp%XM %x87_binop',, - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fsub => { - state => "exc_pinned", - emit => '. fsub%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -# Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp -# are swapped, we work this around in the emitter... - -fsubp => { - state => "exc_pinned", -# see note about gas bugs - emit => '. fsubrp%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fsubr => { - state => "exc_pinned", - irn_flags => "R", - emit => '. fsubr%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fsubrp => { - state => "exc_pinned", - irn_flags => "R", -# see note about gas bugs before fsubp - emit => '. fsubp%XM %x87_binop', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fprem => { - emit => '. fprem1', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -# this node is just here, to keep the simulator running -# we can omit this when a fprem simulation function exists -fpremp => { - emit => '. fprem1\n'. - '. fstp %X0', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fdiv => { - state => "exc_pinned", - emit => '. fdiv%XM %x87_binop', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fdivp => { - state => "exc_pinned", -# see note about gas bugs before fsubp - emit => '. fdivrp%XM %x87_binop', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fdivr => { - state => "exc_pinned", - emit => '. fdivr%XM %x87_binop', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fdivrp => { - state => "exc_pinned", -# see note about gas bugs before fsubp - emit => '. fdivp%XM %x87_binop', - latency => 20, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fabs => { - emit => '. fabs', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fchs => { - op_flags => "R|K", - emit => '. fchs', - latency => 4, - attr_type => "ia32_x87_attr_t", - constructors => {}, -}, - -fld => { - op_flags => "R|L|F", - state => "exc_pinned", - emit => '. fld%XM %AM', - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fst => { - op_flags => "R|L|F", - state => "exc_pinned", - emit => '. fst%XM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fstp => { - op_flags => "R|L|F", - state => "exc_pinned", - emit => '. fstp%XM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fild => { - state => "exc_pinned", - emit => '. fild%XM %AM', - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fist => { - state => "exc_pinned", - emit => '. fist%XM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fistp => { - state => "exc_pinned", - emit => '. fistp%XM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -# SSE3 fisttp instruction -fisttp => { - state => "exc_pinned", - emit => '. fisttp%XM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fldz => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldz', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fld1 => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fld1', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fldpi => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldpi', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fldln2 => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldln2', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fldlg2 => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldlg2', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fldl2t => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldll2t', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -fldl2e => { - op_flags => "R|c|K", - irn_flags => "R", - reg_req => { out => [ "vfp" ] }, - emit => '. fldl2e', - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - # fxch, fpush, fpop # Note that it is NEVER allowed to do CSE on these nodes # Moreover, note the virtual register requierements! fxch => { - op_flags => "R|K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. fxch %X0', + emit => 'fxch %F0', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 1, }, fpush => { - op_flags => "R|K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. fld %X0', + emit => 'fld %F0', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 1, }, fpushCopy => { - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + reg_req => { in => [ "fp"], out => [ "fp" ] }, cmp_attr => "return 1;", - emit => '. fld %X0', + emit => 'fld %F0', attr_type => "ia32_x87_attr_t", latency => 1, }, fpop => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. fstp %X0', + emit => 'fstp %F0', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 1, }, ffreep => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. ffreep %X0', + emit => 'ffreep %F0', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 1, }, emms => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. emms', + emit => 'emms', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 3, }, femms => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", - emit => '. femms', + emit => 'femms', attr_type => "ia32_x87_attr_t", mode => "mode_ANY", latency => 3, }, -FucomFnstsw => { - reg_req => { }, - emit => ". fucom %X1\n". - ". fnstsw %%ax", - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -FucompFnstsw => { - reg_req => { }, - emit => ". fucomp %X1\n". - ". fnstsw %%ax", - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -FucomppFnstsw => { - reg_req => { }, - emit => ". fucompp\n". - ". fnstsw %%ax", - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -Fucomi => { - reg_req => { }, - emit => '. fucomi %X1', - attr_type => "ia32_x87_attr_t", - latency => 1, -}, - -Fucompi => { - reg_req => { }, - emit => '. fucompi %X1', - attr_type => "ia32_x87_attr_t", - latency => 1, -}, - -FtstFnstsw => { - reg_req => { }, - emit => ". ftst\n". - ". fnstsw %%ax", - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - # Spilling and reloading of SSE registers, hardcoded, not generated # xxLoad => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] }, - emit => '. movdqu %D0, %AM', - outs => [ "res", "M" ], + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "xmm", "none", "none", "none" ] }, + emit => 'movdqu %D0, %AM', + ins => [ "base", "index", "mem" ], + outs => [ "res", "M", "X_regular", "X_except" ], units => [ "SSE" ], latency => 1, }, xxStore => { - op_flags => "L|F", + op_flags => [ "uses_memory", "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - emit => '. movdqu %binop', + outs => [ "M", "X_regular", "X_except" ], + emit => 'movdqu %B', units => [ "SSE" ], - latency => 1, - mode => "mode_M", + latency => 1, }, ); # end of %nodes @@ -2817,7 +2409,7 @@ foreach my $op (keys(%nodes)) { die("Latency missing for op $op"); } } - $op_attr_init .= "attr->latency = ".$node->{latency} . ";"; + $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");"; $node->{op_attr_init} = $op_attr_init; }