X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=e85f85bc72af285114a38f9817dc1eb65f2b749c;hb=0a86db8b16bcb48d0fdde8e1180f7a007ea2bf10;hp=9d88e8f45e441cf9fd3306ad89fa443ca6b0dd32;hpb=cee93a68b368d438c0425f9bb32f4d2f2a5846f1;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 9d88e8f45..e85f85bc7 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -2,175 +2,79 @@ # $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", -# 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 -# - # 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 +$caller_save = 1; # caller save (register must be saved by the caller of a function) +$callee_save = 2; # callee save (register must be saved by the called function) +$ignore = 4; # ignore (do not assign this register) +$arbitrary = 8; # emitter can choose an arbitrary register of this class +$virtual = 16; # the register is a virtual one +$state = 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 + { name => "edx", type => $caller_save }, + { name => "ecx", type => $caller_save }, + { name => "eax", type => $caller_save }, + { name => "ebx", type => $callee_save }, + { name => "esi", type => $callee_save }, + { name => "edi", type => $callee_save }, + { name => "ebp", type => $callee_save }, + { 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", type => $caller_save }, + { name => "xmm1", type => $caller_save }, + { name => "xmm2", type => $caller_save }, + { name => "xmm3", type => $caller_save }, + { name => "xmm4", type => $caller_save }, + { name => "xmm5", type => $caller_save }, + { name => "xmm6", type => $caller_save }, + { name => "xmm7", type => $caller_save }, + { 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", type => $caller_save }, + { name => "vf1", type => $caller_save }, + { name => "vf2", type => $caller_save }, + { name => "vf3", type => $caller_save }, + { name => "vf4", type => $caller_save }, + { name => "vf5", type => $caller_save }, + { name => "vf6", type => $caller_save }, + { name => "vf7", type => $caller_save }, + { 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 }, @@ -220,7 +124,6 @@ $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);", ); @@ -274,7 +177,10 @@ $custom_init_attr_func = \&ia32_custom_init_attr; "\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_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, exec_units, n_res);\n". "\tinit_ia32_copyb_attributes(res, size);", @@ -290,10 +196,11 @@ $custom_init_attr_func = \&ia32_custom_init_attr; ); %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", @@ -306,7 +213,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", @@ -316,7 +223,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 +247,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 => [ ], @@ -350,7 +258,7 @@ 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" ] }, @@ -365,7 +273,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" ], @@ -377,7 +285,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" ], @@ -403,7 +311,7 @@ Adc => { }, l_Add => { - op_flags => "C", + op_flags => [ "constlike" ], reg_req => { in => [ "none", "none" ], out => [ "none" ] }, ins => [ "left", "right" ], }, @@ -431,7 +339,7 @@ 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" ] }, @@ -440,7 +348,7 @@ l_Mul => { }, 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,7 +364,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" ] }, @@ -470,7 +378,7 @@ IMul1OP => { }, l_IMul => { - op_flags => "C", + op_flags => [ "constlike" ], cmp_attr => "return 1;", reg_req => { in => [ "none", "none" ], out => [ "none", "none", "none", "none" ] }, @@ -479,7 +387,7 @@ l_IMul => { }, 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" ] }, @@ -494,7 +402,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" ], @@ -506,7 +414,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" ], @@ -518,7 +426,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" ] }, @@ -533,7 +441,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" ], @@ -545,7 +453,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" ], @@ -557,7 +465,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" ] }, @@ -572,8 +480,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", @@ -584,7 +492,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" ], @@ -596,7 +504,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" ], @@ -608,7 +516,7 @@ XorMem8Bit => { }, Sub => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "flags", "none" ] }, @@ -623,7 +531,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" ], @@ -635,7 +543,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" ], @@ -661,7 +569,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", @@ -682,7 +591,7 @@ 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" ] }, @@ -696,7 +605,7 @@ 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" ] }, @@ -710,7 +619,7 @@ Div => { }, Shl => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -723,7 +632,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" ], @@ -741,7 +650,7 @@ l_ShlDep => { }, 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" ], @@ -760,7 +669,7 @@ l_ShlD => { }, Shr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -773,7 +682,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" ], @@ -791,7 +700,7 @@ l_ShrDep => { }, 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" ], @@ -810,7 +719,7 @@ l_ShrD => { }, Sar => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -823,7 +732,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" ], @@ -841,7 +750,7 @@ l_SarDep => { }, Ror => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -854,7 +763,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" ], @@ -866,7 +775,7 @@ RorMem => { }, Rol => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "ecx" ], out => [ "in_r1 !in_r2", "flags" ] }, ins => [ "val", "count" ], @@ -879,7 +788,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" ], @@ -891,7 +800,7 @@ RolMem => { }, Neg => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, emit => '. neg%M %S0', @@ -904,7 +813,7 @@ Neg => { }, NegMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -916,7 +825,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" ], @@ -926,7 +835,7 @@ Minus64Bit => { Inc => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], @@ -939,7 +848,7 @@ Inc => { }, IncMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -951,7 +860,7 @@ IncMem => { }, Dec => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1", "flags" ] }, ins => [ "val" ], @@ -964,7 +873,7 @@ Dec => { }, DecMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -976,11 +885,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, @@ -989,7 +898,7 @@ Not => { }, NotMem => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1019,7 +928,7 @@ Stc => { }, Cmp => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "flags", "none", "none" ] }, @@ -1027,9 +936,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, @@ -1037,7 +945,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" ] }, @@ -1045,17 +953,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" ] }, @@ -1063,9 +984,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, @@ -1073,7 +993,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" ] }, @@ -1081,58 +1001,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, @@ -1140,23 +1061,23 @@ 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", + op_flags => [ "labeled", "cfopcode", "forking" ], reg_req => { in => [ "gp" ] }, mode => "mode_T", - attr_type => "ia32_condcode_attr_t", - attr => "long pnc", + attr_type => "ia32_switch_attr_t", + attr => "long default_pn", latency => 3, units => [ "BRANCH" ], modified_flags => $status_flags, @@ -1165,8 +1086,8 @@ SwitchJmp => { Jmp => { state => "pinned", - irn_flags => "J", - op_flags => "X", + irn_flags => [ "simple_jump" ], + op_flags => [ "cfopcode" ], reg_req => { out => [ "none" ] }, latency => 1, units => [ "BRANCH" ], @@ -1175,7 +1096,7 @@ Jmp => { IJmp => { state => "pinned", - op_flags => "X", + op_flags => [ "cfopcode" ], reg_req => { in => [ "gp", "gp", "none", "gp" ] }, ins => [ "base", "index", "mem", "target" ], am => "source,unary", @@ -1187,8 +1108,8 @@ IJmp => { }, 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", @@ -1197,8 +1118,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, @@ -1206,40 +1136,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 => "", @@ -1249,7 +1149,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 => "", @@ -1260,7 +1161,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 => "", @@ -1270,7 +1172,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, @@ -1279,7 +1182,7 @@ ChangeCW => { }, FldCW => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] }, ins => [ "base", "index", "mem" ], @@ -1291,7 +1194,7 @@ FldCW => { }, FnstCW => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "pinned", reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "fpcw" ], @@ -1302,7 +1205,7 @@ FnstCW => { }, FnstCWNOP => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "pinned", reg_req => { in => [ "fp_cw" ], out => [ "none" ] }, ins => [ "fpcw" ], @@ -1327,7 +1230,7 @@ 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" ] }, @@ -1339,7 +1242,7 @@ Load => { }, Store => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], @@ -1351,7 +1254,7 @@ Store => { }, 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" ] }, ins => [ "base", "index", "mem", "val" ], @@ -1363,7 +1266,7 @@ Store8Bit => { }, Lea => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, ins => [ "base", "index" ], emit => '. leal %AM, %D0', @@ -1386,6 +1289,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" ] }, @@ -1458,7 +1372,7 @@ SubSP => { }, RepPrefix => { - op_flags => "K", + op_flags => [ "keep" ], state => "pinned", mode => "mode_M", emit => ". rep", @@ -1466,7 +1380,7 @@ RepPrefix => { }, LdTls => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "gp" ] }, units => [ "GP" ], latency => 1, @@ -1476,7 +1390,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" ], @@ -1488,7 +1402,7 @@ Bt => { }, Bsf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, @@ -1503,7 +1417,7 @@ Bsf => { }, Bsr => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "flags", "none" ] }, @@ -1521,7 +1435,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" ] }, @@ -1571,7 +1485,7 @@ ClimbFrame => { # bswap # Bswap => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, emit => '. bswap%M %S0', @@ -1585,7 +1499,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', @@ -1625,7 +1539,7 @@ UD2 => { # outport # Outport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, ins => [ "port", "value", "mem" ], @@ -1640,7 +1554,7 @@ Outport => { # inport # Inport => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], state => "pinned", reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, ins => [ "port", "mem" ], @@ -1656,7 +1570,7 @@ Inport => { # Intel style prefetching # Prefetch0 => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1667,7 +1581,7 @@ Prefetch0 => { }, Prefetch1 => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1678,7 +1592,7 @@ Prefetch1 => { }, Prefetch2 => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1689,7 +1603,7 @@ Prefetch2 => { }, PrefetchNTA => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1703,7 +1617,7 @@ PrefetchNTA => { # 3DNow! prefetch instructions # Prefetch => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1714,7 +1628,7 @@ Prefetch => { }, PrefetchW => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "base", "index", "mem" ], @@ -1726,7 +1640,7 @@ PrefetchW => { # produces a 0/+0.0 xZero => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, emit => '. xorp%XSD %D0, %D0', latency => 3, @@ -1734,8 +1648,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, @@ -1745,7 +1668,7 @@ xPzero => { # produces all 1 bits xAllOnes => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "xmm" ] }, emit => '. pcmpeqb %D0, %D0', latency => 3, @@ -1755,7 +1678,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, @@ -1765,7 +1688,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, @@ -1775,7 +1698,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, @@ -1785,7 +1708,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, @@ -1794,7 +1717,7 @@ xMovd => { }, 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" ] }, @@ -1808,7 +1731,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" ] }, @@ -1822,7 +1745,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" ] }, @@ -1836,7 +1759,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" ] }, @@ -1850,7 +1773,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" ] }, @@ -1864,7 +1787,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" ] }, @@ -1878,7 +1801,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" ] }, @@ -1892,7 +1815,7 @@ xXor => { }, 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" ] }, @@ -1906,7 +1829,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" ] }, @@ -1920,7 +1843,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" ] }, @@ -1933,14 +1856,14 @@ xDiv => { }, 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, @@ -1950,7 +1873,7 @@ Ucomi => { }, xLoad => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none", "none", "none" ] }, @@ -1964,7 +1887,7 @@ xLoad => { }, xStore => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], @@ -1976,7 +1899,7 @@ xStore => { }, xStoreSimple => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], @@ -1988,7 +1911,7 @@ xStoreSimple => { }, CvtSI2SS => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], @@ -2000,7 +1923,7 @@ CvtSI2SS => { }, CvtSI2SD => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] }, ins => [ "base", "index", "mem", "val" ], @@ -2013,14 +1936,14 @@ CvtSI2SD => { l_LLtoFloat => { - op_flags => "L|F", + op_flags => [ "fragile", "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 => [ "fragile", "labeled" ], cmp_attr => "return 1;", ins => [ "val" ], outs => [ "res_high", "res_low" ], @@ -2028,7 +1951,7 @@ l_FloattoLL => { }, 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" ], @@ -2041,7 +1964,7 @@ CopyB => { }, 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" ], @@ -2126,7 +2049,7 @@ Conv_FP2FP => { # 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", "none", "none" ] }, @@ -2140,7 +2063,7 @@ vfadd => { }, vfmul => { -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none", "none" ] }, @@ -2154,7 +2077,7 @@ vfmul => { }, vfsub => { -# irn_flags => "R", +# irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none", "none" ] }, @@ -2189,7 +2112,7 @@ vfprem => { }, vfabs => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp"], out => [ "vfp" ] }, ins => [ "value" ], latency => 2, @@ -2199,7 +2122,7 @@ vfabs => { }, vfchs => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "vfp"], out => [ "vfp" ] }, ins => [ "value" ], latency => 2, @@ -2209,8 +2132,8 @@ vfchs => { }, 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" ] }, @@ -2224,8 +2147,8 @@ 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" ] }, @@ -2273,7 +2196,7 @@ vfisttp => { }, vfldz => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2283,7 +2206,7 @@ vfldz => { }, vfld1 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2293,7 +2216,7 @@ vfld1 => { }, vfldpi => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2303,7 +2226,7 @@ vfldpi => { }, vfldln2 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2313,7 +2236,7 @@ vfldln2 => { }, vfldlg2 => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2323,7 +2246,7 @@ vfldlg2 => { }, vfldl2t => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2333,7 +2256,7 @@ vfldl2t => { }, vfldl2e => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { out => [ "vfp" ] }, outs => [ "res" ], latency => 4, @@ -2345,11 +2268,11 @@ vfldl2e => { vFucomFnstsw => { # 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" ], @@ -2358,11 +2281,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" ], @@ -2371,11 +2294,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" ], @@ -2384,7 +2307,7 @@ vFtstFnstsw => { }, Sahf => { - irn_flags => "R", + irn_flags => [ "rematerializable" ], reg_req => { in => [ "eax" ], out => [ "eflags" ] }, ins => [ "val" ], outs => [ "flags" ], @@ -2448,7 +2371,7 @@ fsubp => { fsubr => { state => "exc_pinned", - irn_flags => "R", + irn_flags => [ "rematerializable" ], emit => '. fsubr%XM %x87_binop', latency => 4, attr_type => "ia32_x87_attr_t", @@ -2457,7 +2380,7 @@ fsubr => { fsubrp => { state => "exc_pinned", - irn_flags => "R", + irn_flags => [ "rematerializable" ], # see note about gas bugs before fsubp emit => '. fsubp%XM %x87_binop', latency => 4, @@ -2524,7 +2447,8 @@ fabs => { }, fchs => { - op_flags => "R|K", + op_flags => [ "keep" ], + irn_flags => [ "rematerializable" ], emit => '. fchs', latency => 4, attr_type => "ia32_x87_attr_t", @@ -2532,7 +2456,8 @@ fchs => { }, fld => { - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", emit => '. fld%XM %AM', attr_type => "ia32_x87_attr_t", @@ -2541,7 +2466,8 @@ fld => { }, fst => { - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", emit => '. fst%XM %AM', mode => "mode_M", @@ -2551,7 +2477,8 @@ fst => { }, fstp => { - op_flags => "R|L|F", + irn_flags => [ "rematerializable" ], + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", emit => '. fstp%XM %AM', mode => "mode_M", @@ -2597,8 +2524,8 @@ fisttp => { }, 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", @@ -2606,8 +2533,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", @@ -2615,8 +2542,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", @@ -2624,8 +2551,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", @@ -2633,8 +2560,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", @@ -2642,8 +2569,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", @@ -2651,8 +2578,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", @@ -2664,7 +2591,7 @@ fldl2e => { # 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', @@ -2674,7 +2601,7 @@ fxch => { }, fpush => { - op_flags => "R|K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fld %X0', @@ -2692,7 +2619,7 @@ fpushCopy => { }, fpop => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fstp %X0', @@ -2702,7 +2629,7 @@ fpop => { }, ffreep => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. ffreep %X0', @@ -2712,7 +2639,7 @@ ffreep => { }, emms => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. emms', @@ -2722,7 +2649,7 @@ emms => { }, femms => { - op_flags => "K", + op_flags => [ "keep" ], reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. femms', @@ -2780,7 +2707,7 @@ FtstFnstsw => { # 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" ] }, emit => '. movdqu %D0, %AM', @@ -2790,7 +2717,7 @@ xxLoad => { }, xxStore => { - op_flags => "L|F", + op_flags => [ "fragile", "labeled" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "xmm" ] }, ins => [ "base", "index", "mem", "val" ],