X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=bc39460ea872b9259e98bf59a68561eb62d1b32d;hb=7461eb0c217fbba5ece21e61144e868045801e21;hp=8fde4cca6ea83a72e7681edf75873d799eeca674;hpb=e86f1bc36650e0978d66ffb5fcd347a525840655;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 8fde4cca6..bc39460ea 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -2,177 +2,77 @@ # $Id$ # This is the specification for the ia32 assembler Firm-operations -use File::Basename; - -$new_emit_syntax = 1; -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", -# 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", -# rd_constructor => "c source code which constructs an ir_node", -# 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 -# - # 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 +$normal = 0; # no special type +$ignore = 1; # ignore (do not assign this register) +$arbitrary = 2; # emitter can choose an arbitrary register of this class +$virtual = 4; # the register is a virtual one +$state = 8; # 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 + { name => "edx" }, + { name => "ecx" }, + { name => "eax" }, + { name => "ebx" }, + { name => "esi" }, + { name => "edi" }, + { name => "ebp" }, + { name => "esp", type => $ignore }, + { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes { mode => "mode_Iu" } ], mmx => [ - { name => "mm0", type => 4 }, - { name => "mm1", type => 4 }, - { name => "mm2", type => 4 }, - { name => "mm3", type => 4 }, - { name => "mm4", type => 4 }, - { name => "mm5", type => 4 }, - { name => "mm6", type => 4 }, - { name => "mm7", type => 4 }, + { name => "mm0", type => $ignore }, + { name => "mm1", type => $ignore }, + { name => "mm2", type => $ignore }, + { name => "mm3", type => $ignore }, + { name => "mm4", type => $ignore }, + { name => "mm5", type => $ignore }, + { name => "mm6", type => $ignore }, + { name => "mm7", type => $ignore }, { mode => "mode_E", 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 + { name => "xmm0" }, + { name => "xmm1" }, + { name => "xmm2" }, + { name => "xmm3" }, + { name => "xmm4" }, + { name => "xmm5" }, + { name => "xmm6" }, + { name => "xmm7" }, + { name => "xmm_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes { mode => "mode_E" } ], 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 + { name => "vf0" }, + { name => "vf1" }, + { name => "vf2" }, + { name => "vf3" }, + { name => "vf4" }, + { name => "vf5" }, + { name => "vf6" }, + { name => "vf7" }, + { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg 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 }, + { name => "st0", realname => "st", type => $ignore }, + { name => "st1", realname => "st(1)", type => $ignore }, + { name => "st2", realname => "st(2)", type => $ignore }, + { name => "st3", realname => "st(3)", type => $ignore }, + { name => "st4", realname => "st(4)", type => $ignore }, + { name => "st5", realname => "st(5)", type => $ignore }, + { name => "st6", realname => "st(6)", type => $ignore }, + { name => "st7", realname => "st(7)", type => $ignore }, { mode => "mode_E", flags => "manual_ra" } ], fp_cw => [ # the floating point control word - { name => "fpcw", type => 4|32 }, - { mode => "mode_fpcw", flags => "manual_ra|state" } + { name => "fpcw", type => $ignore | $state }, + { mode => "ia32_mode_fpcw", flags => "manual_ra|state" } ], flags => [ { name => "eflags", type => 0 }, @@ -222,29 +122,21 @@ $arch = "ia32"; 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);", ); -#--------------------------------------------------# -# _ # -# (_) # -# _ __ _____ __ _ _ __ ___ _ __ ___ # -# | '_ \ / _ \ \ /\ / / | | '__| / _ \| '_ \/ __| # -# | | | | __/\ V V / | | | | (_) | |_) \__ \ # -# |_| |_|\___| \_/\_/ |_|_| \___/| .__/|___/ # -# | | # -# |_| # -#--------------------------------------------------# + + $default_op_attr_type = "ia32_op_attr_t"; $default_attr_type = "ia32_attr_t"; $default_copy_attr = "ia32_copy_attr"; sub ia32_custom_init_attr { - my $node = shift; - my $name = shift; - my $res = ""; + my $constr = shift; + my $node = shift; + my $name = shift; + my $res = ""; if(defined($node->{modified_flags})) { $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"; @@ -273,36 +165,40 @@ $custom_init_attr_func = \&ia32_custom_init_attr; %init_attr = ( ia32_asm_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_ia32_x87_attributes(res);". "\tinit_ia32_asm_attributes(res);", ia32_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);", ia32_call_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_ia32_call_attributes(res, pop, call_tp);", ia32_condcode_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". - "\tinit_ia32_condcode_attributes(res, pnc);", + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_condcode_attributes(res, condition_code);", + ia32_switch_attr_t => + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_ia32_switch_attributes(res, default_pn);", ia32_copyb_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_ia32_copyb_attributes(res, size);", ia32_immediate_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, 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, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_ia32_x87_attributes(res);", ia32_climbframe_attr_t => - "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);\n". + "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, 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_switch_attr_t => "ia32_compare_switch_attr", ia32_copyb_attr_t => "ia32_compare_copyb_attr", ia32_immediate_attr_t => "ia32_compare_immediate_attr", ia32_x87_attr_t => "ia32_compare_x87_attr", @@ -315,7 +211,7 @@ $custom_init_attr_func = \&ia32_custom_init_attr; $mode_xmm = "mode_E"; $mode_gp = "mode_Iu"; $mode_flags = "mode_Iu"; -$mode_fpcw = "mode_fpcw"; +$mode_fpcw = "ia32_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", @@ -325,7 +221,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", @@ -348,8 +245,8 @@ Asm => { # "allocates" a free register ProduceVal => { - op_flags => "c", - irn_flags => "R", + op_flags => [ "constlike", "cse_neutral" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, emit => "", units => [ ], @@ -358,21 +255,8 @@ ProduceVal => { cmp_attr => "return 1;", }, -#-----------------------------------------------------------------# -# _ _ _ # -# (_) | | | | # -# _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ # -# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| # -# | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ # -# |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ # -# __/ | # -# |___/ # -#-----------------------------------------------------------------# - -# commutative operations - 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" ] }, @@ -387,7 +271,7 @@ 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" ], @@ -399,7 +283,7 @@ 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" ], @@ -425,7 +309,7 @@ Adc => { }, l_Add => { - op_flags => "C", + op_flags => [ "constlike" ], reg_req => { in => [ "none", "none" ], out => [ "none" ] }, ins => [ "left", "right" ], }, @@ -453,14 +337,16 @@ Mul => { l_Mul => { # we should not rematrialize this node. It produces 2 results and has # very strict constraints - op_flags => "C", + op_flags => [ "constlike" ], cmp_attr => "return 1;", + reg_req => { in => [ "none", "none" ], + out => [ "none", "none", "none", "none" ] }, + ins => [ "left", "right" ], outs => [ "res_low", "flags", "M", "res_high" ], - arity => 2 }, 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) @@ -476,7 +362,7 @@ IMul => { }, IMul1OP => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], out => [ "eax", "flags", "none", "edx" ] }, @@ -490,20 +376,21 @@ IMul1OP => { }, l_IMul => { - op_flags => "C", + op_flags => [ "constlike" ], cmp_attr => "return 1;", + reg_req => { in => [ "none", "none" ], + out => [ "none", "none", "none", "none" ] }, + ins => [ "left", "right" ], outs => [ "res_low", "flags", "M", "res_high" ], - arity => 2 }, 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" ], - op_modes => "commutative | am | immediate | mode_neutral", am => "source,binary", emit => '. and%M %binop', units => [ "GP" ], @@ -513,7 +400,7 @@ 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" ], @@ -525,7 +412,7 @@ 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" ], @@ -537,7 +424,7 @@ 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" ] }, @@ -552,7 +439,7 @@ 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" ], @@ -564,7 +451,7 @@ 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" ], @@ -576,7 +463,7 @@ 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" ] }, @@ -591,8 +478,8 @@ 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", @@ -603,7 +490,7 @@ 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" ], @@ -615,7 +502,7 @@ 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" ], @@ -626,10 +513,8 @@ XorMem8Bit => { modified_flags => $status_flags }, -# not commutative operations - Sub => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "flags", "none" ] }, @@ -644,7 +529,7 @@ 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" ], @@ -656,7 +541,7 @@ 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" ], @@ -670,7 +555,7 @@ 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", @@ -682,7 +567,8 @@ Sbb => { }, Sbb0 => { - irn_flags => "R", + # Spiller currently fails when rematerializing flag consumers + # irn_flags => [ "rematerializable" ], reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] }, outs => [ "res", "flags" ], emit => ". sbb%M %D0, %D0", @@ -703,12 +589,12 @@ l_Sbb => { }, IDiv => { - op_flags => "F|L", + op_flags => [ "fragile", "labeled" ], 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", latency => 25, @@ -717,12 +603,12 @@ IDiv => { }, Div => { - op_flags => "F|L", + op_flags => [ "fragile", "labeled" ], 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", latency => 25, @@ -731,7 +617,7 @@ Div => { }, Shl => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -744,7 +630,7 @@ 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" ], @@ -755,14 +641,8 @@ ShlMem => { modified_flags => $status_flags }, -l_ShlDep => { - cmp_attr => "return 1;", - ins => [ "val", "count", "dep" ], - arity => 3 -}, - 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" ], @@ -774,14 +654,8 @@ ShlD => { modified_flags => $status_flags }, -l_ShlD => { - cmp_attr => "return 1;", - ins => [ "val_high", "val_low", "count" ], - arity => 3, -}, - Shr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -794,7 +668,7 @@ 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" ], @@ -805,14 +679,8 @@ ShrMem => { modified_flags => $status_flags }, -l_ShrDep => { - cmp_attr => "return 1;", - ins => [ "val", "count", "dep" ], - arity => 3 -}, - 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" ], @@ -824,14 +692,8 @@ ShrD => { modified_flags => $status_flags }, -l_ShrD => { - cmp_attr => "return 1;", - arity => 3, - 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" ], @@ -844,7 +706,7 @@ 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" ], @@ -855,14 +717,8 @@ SarMem => { modified_flags => $status_flags }, -l_SarDep => { - cmp_attr => "return 1;", - ins => [ "val", "count", "dep" ], - arity => 3 -}, - Ror => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -875,7 +731,7 @@ 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" ], @@ -887,7 +743,7 @@ RorMem => { }, Rol => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -900,7 +756,7 @@ 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" ], @@ -911,10 +767,8 @@ RolMem => { modified_flags => $status_flags }, -# unary operations - Neg => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, emit => '. neg%M %S0', @@ -927,7 +781,7 @@ Neg => { }, NegMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -939,7 +793,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" ], @@ -949,7 +803,7 @@ Minus64Bit => { Inc => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], @@ -962,7 +816,7 @@ Inc => { }, IncMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -974,7 +828,7 @@ IncMem => { }, Dec => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], @@ -987,7 +841,7 @@ Dec => { }, DecMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -999,11 +853,11 @@ DecMem => { }, Not => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], - out => [ "in_r1", "flags" ] }, + out => [ "in_r1" ] }, ins => [ "val" ], - outs => [ "res", "flags" ], + outs => [ "res" ], emit => '. not%M %S0', units => [ "GP" ], latency => 1, @@ -1012,7 +866,7 @@ Not => { }, NotMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1024,8 +878,8 @@ NotMem => { }, Cmc => { - reg_req => { in => [ "flags" ], out => [ "flags" ] }, - emit => '.cmc', + reg_req => { in => [ "flags" ], out => [ "flags" ] }, + emit => '.cmc', units => [ "GP" ], latency => 1, mode => $mode_flags, @@ -1033,18 +887,16 @@ Cmc => { }, Stc => { - reg_req => { out => [ "flags" ] }, - emit => '.stc', + reg_req => { out => [ "flags" ] }, + emit => '.stc', units => [ "GP" ], latency => 1, mode => $mode_flags, modified_flags => $status_flags }, -# other operations - Cmp => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "flags", "none", "none" ] }, @@ -1052,9 +904,8 @@ Cmp => { 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", + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, @@ -1062,7 +913,7 @@ 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" ] }, @@ -1070,17 +921,30 @@ Cmp8Bit => { 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", + 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 %SH0, %SB0', + ins => [ "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" ] }, @@ -1088,9 +952,8 @@ Test => { 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", + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, @@ -1098,7 +961,7 @@ 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" ] }, @@ -1106,57 +969,59 @@ Test8Bit => { 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", + attr => "bool ins_permuted", + init_attr => "attr->data.ins_permuted = ins_permuted;", latency => 1, units => [ "GP" ], mode => $mode_flags, modified_flags => $status_flags }, -Set => { - #irn_flags => "R", +Setcc => { + #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, int ins_permuted", - init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n". - "\tset_ia32_ls_mode(res, mode_Bu);\n", - emit => '. set%CMP0 %DB0', + 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_irn_add_flags(res, arch_irn_flags_modify_flags);\n" + . "\t\t/* attr->latency = 3; */\n" + . "\t}\n", latency => 1, units => [ "GP" ], mode => $mode_gp, }, -SetMem => { - #irn_flags => "R", +SetccMem => { + #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, int ins_permuted", - init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n". - "\tset_ia32_ls_mode(res, mode_Bu);\n", + attr => "ia32_condition_code_t condition_code", + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", emit => '. set%CMP3 %AM', latency => 1, units => [ "GP" ], mode => 'mode_M', }, -CMov => { - #irn_flags => "R", +CMovcc => { + #irn_flags => [ "rematerializable" ], + state => "exc_pinned", # (note: leave the false,true order intact to make it compatible with other # ia32_binary ops) - state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ], out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ], outs => [ "res", "flags", "M" ], am => "source,binary", attr_type => "ia32_condcode_attr_t", - attr => "int ins_permuted, pn_Cmp pnc", - init_attr => "attr->attr.data.ins_permuted = ins_permuted;", + attr => "ia32_condition_code_t condition_code", latency => 1, units => [ "GP" ], mode => $mode_gp, @@ -1164,32 +1029,42 @@ CMov => { Jcc => { state => "pinned", - op_flags => "L|X|Y", + op_flags => [ "labeled", "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" ], - out => [ ] }, + op_flags => [ "labeled", "cfopcode", "forking" ], + reg_req => { in => [ "gp", "gp" ] }, + ins => [ "base", "index" ], mode => "mode_T", - attr_type => "ia32_condcode_attr_t", - attr => "long pnc", - latency => 3, + attr_type => "ia32_switch_attr_t", + attr => "long default_pn", + 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 => [ "simple_jump" ], + op_flags => [ "cfopcode" ], + reg_req => { out => [ "none" ] }, + latency => 1, + units => [ "BRANCH" ], + mode => "mode_X", }, IJmp => { state => "pinned", - op_flags => "X", + op_flags => [ "cfopcode", "unknown_jump" ], reg_req => { in => [ "gp", "gp", "none", "gp" ] }, ins => [ "base", "index", "mem", "target" ], am => "source,unary", @@ -1197,11 +1072,12 @@ IJmp => { 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" ] }, units => [ "GP" ], attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset", @@ -1210,8 +1086,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, @@ -1219,40 +1104,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", "dump_noinput" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "gp_NOREG:I" ] }, units => [], emit => "", @@ -1262,7 +1117,8 @@ NoReg_GP => { NoReg_VFP => { state => "pinned", - op_flags => "c|NB|NI", + op_flags => [ "constlike", "dump_noblock", "dump_noinput" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "vfp_NOREG:I" ] }, units => [], emit => "", @@ -1273,7 +1129,8 @@ NoReg_VFP => { NoReg_XMM => { state => "pinned", - op_flags => "c|NB|NI", + op_flags => [ "constlike", "dump_noblock", "dump_noinput" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "xmm_NOREG:I" ] }, units => [], emit => "", @@ -1283,7 +1140,8 @@ NoReg_XMM => { ChangeCW => { state => "pinned", - op_flags => "c", + op_flags => [ "constlike" ], + irn_flags => [ "not_scheduled" ], reg_req => { out => [ "fpcw:I" ] }, mode => $mode_fpcw, latency => 3, @@ -1292,7 +1150,7 @@ ChangeCW => { }, FldCW => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] }, ins => [ "base", "index", "mem" ], @@ -1304,7 +1162,7 @@ FldCW => { }, FnstCW => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "fpcw" ], @@ -1315,7 +1173,7 @@ FnstCW => { }, FnstCWNOP => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "pinned", reg_req => { in => [ "fp_cw" ], out => [ "none" ] }, ins => [ "fpcw" ], @@ -1340,43 +1198,43 @@ Cltd => { # lateny of 0 for load is correct Load => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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", units => [ "GP" ], }, Store => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "M", "X_regular", "X_except" ], emit => '. mov%M %SI3, %AM', latency => 2, units => [ "GP" ], - mode => "mode_M", }, Store8Bit => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "M", "X_regular", "X_except" ], emit => '. mov%M %SB3, %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', @@ -1399,6 +1257,17 @@ Push => { 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" ] }, @@ -1419,6 +1288,17 @@ PopEbp => { 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" ] }, @@ -1443,6 +1323,7 @@ Leave => { outs => [ "frame", "stack" ], latency => 3, units => [ "GP" ], + state => "exc_pinned", }, AddSP => { @@ -1471,7 +1352,7 @@ SubSP => { }, RepPrefix => { - op_flags => "K", + op_flags => [ "keep" ], state => "pinned", mode => "mode_M", emit => ". rep", @@ -1479,9 +1360,11 @@ RepPrefix => { }, LdTls => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, units => [ "GP" ], + emit => ". movl %%gs:0, %D0", + mode => $mode_gp, latency => 1, }, @@ -1489,7 +1372,7 @@ 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" ], @@ -1501,7 +1384,7 @@ Bt => { }, Bsf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, @@ -1516,7 +1399,7 @@ Bsf => { }, Bsr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, @@ -1534,7 +1417,7 @@ 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" ] }, @@ -1549,13 +1432,14 @@ Popcnt => { }, Call => { + op_flags => [ "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", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "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", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ], attr_type => "ia32_call_attr_t", attr => "unsigned pop, ir_type *call_tp", am => "source,unary", @@ -1584,7 +1468,7 @@ ClimbFrame => { # bswap # Bswap => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, emit => '. bswap%M %S0', @@ -1598,7 +1482,7 @@ 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', @@ -1638,7 +1522,7 @@ UD2 => { # outport # Outport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, ins => [ "port", "value", "mem" ], @@ -1653,7 +1537,7 @@ Outport => { # inport # Inport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, ins => [ "port", "mem" ], @@ -1669,7 +1553,7 @@ Inport => { # Intel style prefetching # Prefetch0 => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1680,7 +1564,7 @@ Prefetch0 => { }, Prefetch1 => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1691,7 +1575,7 @@ Prefetch1 => { }, Prefetch2 => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1702,7 +1586,7 @@ Prefetch2 => { }, PrefetchNTA => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1716,7 +1600,7 @@ PrefetchNTA => { # 3DNow! prefetch instructions # Prefetch => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1727,7 +1611,7 @@ Prefetch => { }, PrefetchW => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1737,18 +1621,9 @@ PrefetchW => { units => [ "GP" ], }, -#-----------------------------------------------------------------------------# -# _____ _____ ______ __ _ _ _ # -# / ____/ ____| ____| / _| | | | | | # -# | (___| (___ | |__ | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ # -# \___ \\___ \| __| | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| # -# ____) |___) | |____ | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ # -# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ # -#-----------------------------------------------------------------------------# - # produces a 0/+0.0 xZero => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, emit => '. xorp%XSD %D0, %D0', latency => 3, @@ -1756,8 +1631,17 @@ xZero => { 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', latency => 3, @@ -1767,7 +1651,7 @@ xPzero => { # produces all 1 bits xAllOnes => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, emit => '. pcmpeqb %D0, %D0', latency => 3, @@ -1777,7 +1661,7 @@ 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', latency => 3, @@ -1787,7 +1671,7 @@ 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', latency => 3, @@ -1797,7 +1681,7 @@ 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', latency => 1, @@ -1807,7 +1691,7 @@ xPsrld => { # mov from integer to SSE register xMovd => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "xmm" ] }, emit => '. movd %S0, %D0', latency => 1, @@ -1815,10 +1699,8 @@ xMovd => { mode => $mode_xmm }, -# commutative operations - 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" ] }, @@ -1832,7 +1714,7 @@ xAdd => { }, 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" ] }, @@ -1846,7 +1728,7 @@ xMul => { }, 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" ] }, @@ -1860,7 +1742,7 @@ xMax => { }, 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" ] }, @@ -1874,7 +1756,7 @@ xMin => { }, 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" ] }, @@ -1888,7 +1770,7 @@ xAnd => { }, 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" ] }, @@ -1902,7 +1784,7 @@ xOr => { }, 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" ] }, @@ -1915,10 +1797,8 @@ xXor => { mode => $mode_xmm }, -# not commutative operations - 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" ] }, @@ -1932,7 +1812,7 @@ xAndNot => { }, xSub => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4", "flags", "none" ] }, @@ -1946,7 +1826,7 @@ xSub => { }, 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" ] }, @@ -1958,17 +1838,15 @@ xDiv => { units => [ "SSE" ], }, -# other operations - 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', latency => 3, @@ -1977,15 +1855,13 @@ Ucomi => { modified_flags => 1, }, -# Load / Store - xLoad => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "res", "unused", "M", "X_regular", "X_except" ], emit => '. mov%XXM %AM, %D0', attr => "ir_mode *load_mode", init_attr => "attr->ls_mode = load_mode;", @@ -1994,30 +1870,31 @@ xLoad => { }, xStore => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "M", "X_regular", "X_except" ], emit => '. mov%XXM %S3, %AM', latency => 0, units => [ "SSE" ], - mode => "mode_M", }, xStoreSimple => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "M", "X_regular", "X_except" ], emit => '. mov%XXM %S3, %AM', latency => 0, units => [ "SSE" ], - mode => "mode_M", }, CvtSI2SS => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], @@ -2029,7 +1906,7 @@ CvtSI2SS => { }, CvtSI2SD => { - op_flags => "L|F", + op_flags => [ "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], @@ -2042,48 +1919,50 @@ CvtSI2SD => { l_LLtoFloat => { - op_flags => "L|F", + op_flags => [ "labeled" ], cmp_attr => "return 1;", ins => [ "val_high", "val_low" ], + reg_req => { in => [ "none", "none" ], out => [ "none" ] } }, l_FloattoLL => { - op_flags => "L|F", + op_flags => [ "labeled" ], cmp_attr => "return 1;", ins => [ "val" ], outs => [ "res_high", "res_low" ], + reg_req => { in => [ "none" ], out => [ "none", "none" ] } }, -# CopyB - CopyB => { - op_flags => "F|H", + op_flags => [ "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 => [ "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" ] }, -# Conversions - Cwtl => { state => "exc_pinned", reg_req => { in => [ "eax" ], out => [ "eax" ] }, @@ -2096,11 +1975,12 @@ Cwtl => { }, Conv_I2I => { + op_flags => [ "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" ], am => "source,unary", units => [ "GP" ], latency => 1, @@ -2110,11 +1990,12 @@ Conv_I2I => { }, Conv_I2I8Bit => { + op_flags => [ "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" ], am => "source,unary", units => [ "GP" ], latency => 1, @@ -2153,28 +2034,16 @@ Conv_FP2FP => { mode => $mode_xmm, }, -#----------------------------------------------------------# -# _ _ _ __ _ _ # -# (_) | | | | / _| | | | # -# __ ___ _ __| |_ _ _ __ _| | | |_| | ___ __ _| |_ # -# \ \ / / | '__| __| | | |/ _` | | | _| |/ _ \ / _` | __| # -# \ V /| | | | |_| |_| | (_| | | | | | | (_) | (_| | |_ # -# \_/ |_|_| \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| # -# | | # -# _ __ ___ __| | ___ ___ # -# | '_ \ / _ \ / _` |/ _ \/ __| # -# | | | | (_) | (_| | __/\__ \ # -# |_| |_|\___/ \__,_|\___||___/ # -#----------------------------------------------------------# - # 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", +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], + out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right", "fpcw" ], + outs => [ "res", "dummy", "M" ], am => "source,binary", latency => 4, units => [ "VFP" ], @@ -2183,10 +2052,12 @@ vfadd => { }, vfmul => { -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], + out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right", "fpcw" ], + outs => [ "res", "dummy", "M" ], am => "source,binary", latency => 4, units => [ "VFP" ], @@ -2195,10 +2066,12 @@ vfmul => { }, vfsub => { -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], + out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ], + outs => [ "res", "dummy", "M" ], am => "source,binary", latency => 4, units => [ "VFP" ], @@ -2208,10 +2081,11 @@ vfsub => { vfdiv => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], + out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ], + outs => [ "res", "dummy", "M" ], am => "source,binary", - outs => [ "res", "M" ], latency => 20, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", @@ -2227,7 +2101,7 @@ vfprem => { }, vfabs => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp"], out => [ "vfp" ] }, ins => [ "value" ], latency => 2, @@ -2237,7 +2111,7 @@ vfabs => { }, vfchs => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp"], out => [ "vfp" ] }, ins => [ "value" ], latency => 2, @@ -2246,16 +2120,14 @@ vfchs => { attr_type => "ia32_x87_attr_t", }, -# virtual Load and Store - vfld => { - irn_flags => "R", - op_flags => "L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], - out => [ "vfp", "none", "none", "none" ] }, + out => [ "vfp", "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "unused", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_regular", "X_except" ], attr => "ir_mode *load_mode", init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, @@ -2264,23 +2136,20 @@ vfld => { }, vfst => { - irn_flags => "R", - op_flags => "L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp" ], - out => [ "none", "none" ] }, + out => [ "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "M", "X_exc" ], + outs => [ "M", "X_regular", "X_except" ], attr => "ir_mode *store_mode", init_attr => "attr->attr.ls_mode = store_mode;", latency => 2, units => [ "VFP" ], - mode => "mode_M", attr_type => "ia32_x87_attr_t", }, -# Conversions - vfild => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], @@ -2293,31 +2162,32 @@ vfild => { }, vfist => { + op_flags => [ "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], + out => [ "none", "none", "none", "none" ] }, ins => [ "base", "index", "mem", "val", "fpcw" ], + outs => [ "dummy", "M", "X_regular", "X_except" ], latency => 4, units => [ "VFP" ], - mode => "mode_M", attr_type => "ia32_x87_attr_t", }, # SSE3 fisttp instruction vfisttp => { + op_flags => [ "fragile" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]}, + reg_req => { in => [ "gp", "gp", "none", "vfp" ], + out => [ "in_r4", "none", "none", "none" ]}, ins => [ "base", "index", "mem", "val" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_regular", "X_except" ], latency => 4, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", }, - -# constants - vfldz => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2327,7 +2197,7 @@ vfldz => { }, vfld1 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2337,7 +2207,7 @@ vfld1 => { }, vfldpi => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2347,7 +2217,7 @@ vfldpi => { }, vfldln2 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2357,7 +2227,7 @@ vfldln2 => { }, vfldlg2 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2367,7 +2237,7 @@ vfldlg2 => { }, vfldl2t => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2377,7 +2247,7 @@ vfldl2t => { }, vfldl2e => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2386,16 +2256,14 @@ vfldl2e => { attr_type => "ia32_x87_attr_t", }, -# other - vFucomFnstsw => { -# we can't allow to rematerialize this node so we don't have +# we can't allow to rematerialize this node so we don't # accidently produce Phi(Fucom, Fucom(ins_permuted)) -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] }, ins => [ "left", "right" ], outs => [ "flags" ], - attr => "int ins_permuted", + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2404,11 +2272,11 @@ vFucomFnstsw => { }, vFucomi => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] }, ins => [ "left", "right" ], outs => [ "flags" ], - attr => "int ins_permuted", + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2417,11 +2285,11 @@ vFucomi => { }, vFtstFnstsw => { -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp" ], out => [ "eax" ] }, ins => [ "left" ], outs => [ "flags" ], - attr => "int ins_permuted", + attr => "bool ins_permuted", init_attr => "attr->attr.data.ins_permuted = ins_permuted;", latency => 3, units => [ "VFP" ], @@ -2430,7 +2298,7 @@ vFtstFnstsw => { }, Sahf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "eax" ], out => [ "eflags" ] }, ins => [ "val" ], outs => [ "flags" ], @@ -2440,248 +2308,215 @@ Sahf => { mode => $mode_flags, }, -#------------------------------------------------------------------------# -# ___ _____ __ _ _ _ # -# __ _( _ )___ | / _| | ___ __ _| |_ _ __ ___ __| | ___ ___ # -# \ \/ / _ \ / / | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| # -# > < (_) |/ / | _| | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ # -# /_/\_\___//_/ |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ # -#------------------------------------------------------------------------# - -# Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp -# are swapped, we work this around in the emitter... - fadd => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fadd%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, faddp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. faddp%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fmul => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fmul%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fmulp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fmulp%XM %x87_binop',, latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fsub => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, 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", - rd_constructor => "NONE", - reg_req => { }, # see note about gas bugs emit => '. fsubrp%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fsubr => { state => "exc_pinned", - rd_constructor => "NONE", - irn_flags => "R", - reg_req => { }, + irn_flags => [ "rematerializable" ], emit => '. fsubr%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fsubrp => { state => "exc_pinned", - rd_constructor => "NONE", - irn_flags => "R", - reg_req => { }, -# see note about gas bugs + irn_flags => [ "rematerializable" ], +# see note about gas bugs before fsubp emit => '. fsubp%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fprem => { - rd_constructor => "NONE", - reg_req => { }, 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 => { - rd_constructor => "NONE", - reg_req => { }, emit => '. fprem1\n'. '. fstp %X0', latency => 20, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fdiv => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fdiv%XM %x87_binop', latency => 20, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fdivp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, -# see note about gas bugs +# 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", - rd_constructor => "NONE", - reg_req => { }, emit => '. fdivr%XM %x87_binop', latency => 20, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fdivrp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, -# see note about gas bugs +# see note about gas bugs before fsubp emit => '. fdivp%XM %x87_binop', latency => 20, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fabs => { - rd_constructor => "NONE", - reg_req => { }, emit => '. fabs', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, fchs => { - op_flags => "R|K", - rd_constructor => "NONE", - reg_req => { }, + op_flags => [ "keep" ], + irn_flags => [ "rematerializable" ], emit => '. fchs', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, -# x87 Load and Store - fld => { - rd_constructor => "NONE", - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "labeled" ], state => "exc_pinned", - reg_req => { }, emit => '. fld%XM %AM', attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, fst => { - rd_constructor => "NONE", - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "labeled" ], state => "exc_pinned", - reg_req => { }, emit => '. fst%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, fstp => { - rd_constructor => "NONE", - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "labeled" ], state => "exc_pinned", - reg_req => { }, emit => '. fstp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, -# Conversions - fild => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fild%XM %AM', attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, fist => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fist%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, fistp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fistp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, # SSE3 fisttp instruction fisttp => { state => "exc_pinned", - rd_constructor => "NONE", - reg_req => { }, emit => '. fisttp%XM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, + constructors => {}, }, -# constants - fldz => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldz', attr_type => "ia32_x87_attr_t", @@ -2689,8 +2524,8 @@ fldz => { }, fld1 => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fld1', attr_type => "ia32_x87_attr_t", @@ -2698,8 +2533,8 @@ fld1 => { }, fldpi => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldpi', attr_type => "ia32_x87_attr_t", @@ -2707,8 +2542,8 @@ fldpi => { }, fldln2 => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldln2', attr_type => "ia32_x87_attr_t", @@ -2716,8 +2551,8 @@ fldln2 => { }, fldlg2 => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldlg2', attr_type => "ia32_x87_attr_t", @@ -2725,8 +2560,8 @@ fldlg2 => { }, fldl2t => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldll2t', attr_type => "ia32_x87_attr_t", @@ -2734,8 +2569,8 @@ fldl2t => { }, fldl2e => { - op_flags => "R|c|K", - irn_flags => "R", + op_flags => [ "constlike", "keep" ], + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, emit => '. fldl2e', attr_type => "ia32_x87_attr_t", @@ -2747,8 +2582,8 @@ fldl2e => { # Moreover, note the virtual register requierements! fxch => { - op_flags => "R|K", - reg_req => { }, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fxch %X0', attr_type => "ia32_x87_attr_t", @@ -2757,8 +2592,8 @@ fxch => { }, fpush => { - op_flags => "R|K", - reg_req => {}, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fld %X0', attr_type => "ia32_x87_attr_t", @@ -2775,8 +2610,8 @@ fpushCopy => { }, fpop => { - op_flags => "K", - reg_req => { }, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fstp %X0', attr_type => "ia32_x87_attr_t", @@ -2785,8 +2620,8 @@ fpop => { }, ffreep => { - op_flags => "K", - reg_req => { }, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. ffreep %X0', attr_type => "ia32_x87_attr_t", @@ -2795,8 +2630,8 @@ ffreep => { }, emms => { - op_flags => "K", - reg_req => { }, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. emms', attr_type => "ia32_x87_attr_t", @@ -2805,8 +2640,8 @@ emms => { }, femms => { - op_flags => "K", - reg_req => { }, + op_flags => [ "keep" ], + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. femms', attr_type => "ia32_x87_attr_t", @@ -2814,8 +2649,6 @@ femms => { latency => 3, }, -# compare - FucomFnstsw => { reg_req => { }, emit => ". fucom %X1\n". @@ -2862,50 +2695,34 @@ FtstFnstsw => { latency => 2, }, - -# -------------------------------------------------------------------------------- # -# ____ ____ _____ _ _ # -# / ___/ ___|| ____| __ _____ ___| |_ ___ _ __ _ __ ___ __| | ___ ___ # -# \___ \___ \| _| \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __| # -# ___) |__) | |___ \ V / __/ (__| || (_) | | | | | | (_) | (_| | __/\__ \ # -# |____/____/|_____| \_/ \___|\___|\__\___/|_| |_| |_|\___/ \__,_|\___||___/ # -# # -# -------------------------------------------------------------------------------- # - - # Spilling and reloading of SSE registers, hardcoded, not generated # xxLoad => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "xmm", "none", "none", "none" ] }, emit => '. movdqu %D0, %AM', - outs => [ "res", "M" ], + ins => [ "base", "index", "mem" ], + outs => [ "res", "M", "X_regular", "X_except" ], units => [ "SSE" ], latency => 1, }, xxStore => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], 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" ], + outs => [ "M", "X_regular", "X_except" ], emit => '. movdqu %binop', units => [ "SSE" ], - latency => 1, - mode => "mode_M", + latency => 1, }, ); # end of %nodes -# Include the generated SIMD node specification written by the SIMD optimization -$my_script_name = dirname($myname) . "/../ia32/ia32_simd_spec.pl"; -unless ($return = do $my_script_name) { - warn "couldn't parse $my_script_name: $@" if $@; - warn "couldn't do $my_script_name: $!" unless defined $return; - warn "couldn't run $my_script_name" unless $return; -} - # Transform some attributes foreach my $op (keys(%nodes)) { my $node = $nodes{$op};