X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=a49559d035db91642954e250cbcca48f8a852916;hb=b53fa7e898ba0e520d452a7f78c82cb36bdb8351;hp=a4c7a72911e2d8d522fdb8e34f6686734ebd078d;hpb=c11262873a64779c78b8eee6118a1b0659d0f043;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index a4c7a7291..a49559d03 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -4,7 +4,6 @@ use File::Basename; -$new_emit_syntax = 1; my $myname = $0; # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...) @@ -34,7 +33,6 @@ $arch = "ia32"; # 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", @@ -103,7 +101,7 @@ $arch = "ia32"; # 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 assign this register) +# 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 @@ -197,19 +195,22 @@ $arch = "ia32"; S1 => "${arch}_emit_source_register(node, 1);", S2 => "${arch}_emit_source_register(node, 2);", S3 => "${arch}_emit_source_register(node, 3);", + SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);", SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);", SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);", SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);", + SH0 => "${arch}_emit_8bit_high_source_register(node, 0);", + SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);", + SI0 => "${arch}_emit_source_register_or_immediate(node, 0);", SI1 => "${arch}_emit_source_register_or_immediate(node, 1);", SI3 => "${arch}_emit_source_register_or_immediate(node, 3);", D0 => "${arch}_emit_dest_register(node, 0);", D1 => "${arch}_emit_dest_register(node, 1);", + DS0 => "${arch}_emit_dest_register_size(node, 0);", DB0 => "${arch}_emit_8bit_dest_register(node, 0);", X0 => "${arch}_emit_x87_register(node, 0);", X1 => "${arch}_emit_x87_register(node, 1);", - SE => "${arch}_emit_extend_suffix(get_ia32_ls_mode(node));", - ME => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n - ia32_emit_mode_suffix(node);", + EX => "${arch}_emit_extend_suffix(node);", M => "${arch}_emit_mode_suffix(node);", XM => "${arch}_emit_x87_mode_suffix(node);", XXM => "${arch}_emit_xmm_mode_suffix(node);", @@ -223,25 +224,18 @@ $arch = "ia32"; 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"; @@ -270,28 +264,28 @@ $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_attributes(res, flags, in_reqs, exec_units, n_res);\n". "\tinit_ia32_condcode_attributes(res, pnc);", 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_immediate_attributes(res, symconst, symconst_sign, offset);", + "\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);", ); @@ -324,7 +318,7 @@ Immediate => { state => "pinned", op_flags => "c", reg_req => { out => [ "gp_NOREG:I" ] }, - attr => "ir_entity *symconst, int symconst_sign, long offset", + attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset", attr_type => "ia32_immediate_attr_t", hash_func => "ia32_hash_Immediate", latency => 0, @@ -355,19 +349,6 @@ ProduceVal => { cmp_attr => "return 1;", }, -#-----------------------------------------------------------------# -# _ _ _ # -# (_) | | | | # -# _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ # -# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| # -# | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ # -# |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ # -# __/ | # -# |___/ # -#-----------------------------------------------------------------# - -# commutative operations - Add => { irn_flags => "R", state => "exc_pinned", @@ -437,10 +418,10 @@ Mul => { # very strict constraints state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], - out => [ "eax", "flags", "edx", "none" ] }, + out => [ "eax", "flags", "none", "edx" ] }, ins => [ "base", "index", "mem", "left", "right" ], emit => '. mul%M %unop4', - outs => [ "res_low", "flags", "res_high", "M" ], + outs => [ "res_low", "flags", "M", "res_high" ], am => "source,binary", latency => 10, units => [ "GP" ], @@ -452,8 +433,10 @@ l_Mul => { # very strict constraints op_flags => "C", cmp_attr => "return 1;", - outs => [ "EAX", "flags", "EDX", "M" ], - arity => 2 + reg_req => { in => [ "none", "none" ], + out => [ "none", "none", "none", "none" ] }, + ins => [ "left", "right" ], + outs => [ "res_low", "flags", "M", "res_high" ], }, IMul => { @@ -476,10 +459,10 @@ IMul1OP => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ], - out => [ "eax", "flags", "edx", "none" ] }, + out => [ "eax", "flags", "none", "edx" ] }, ins => [ "base", "index", "mem", "left", "right" ], emit => '. imul%M %unop4', - outs => [ "res_low", "flags", "res_high", "M" ], + outs => [ "res_low", "flags", "M", "res_high" ], am => "source,binary", latency => 5, units => [ "GP" ], @@ -489,8 +472,10 @@ IMul1OP => { l_IMul => { op_flags => "C", cmp_attr => "return 1;", - outs => [ "res_low", "res_high", "M" ], - arity => 2 + reg_req => { in => [ "none", "none" ], + out => [ "none", "none", "none", "none" ] }, + ins => [ "left", "right" ], + outs => [ "res_low", "flags", "M", "res_high" ], }, And => { @@ -500,7 +485,6 @@ And => { 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" ], @@ -623,8 +607,6 @@ XorMem8Bit => { modified_flags => $status_flags }, -# not commutative operations - Sub => { irn_flags => "R", state => "exc_pinned", @@ -754,8 +736,8 @@ ShlMem => { l_ShlDep => { cmp_attr => "return 1;", + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "val", "count", "dep" ], - arity => 3 }, ShlD => { @@ -773,8 +755,8 @@ ShlD => { l_ShlD => { cmp_attr => "return 1;", + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "val_high", "val_low", "count" ], - arity => 3, }, Shr => { @@ -804,8 +786,8 @@ ShrMem => { l_ShrDep => { cmp_attr => "return 1;", + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "val", "count", "dep" ], - arity => 3 }, ShrD => { @@ -823,7 +805,7 @@ ShrD => { l_ShrD => { cmp_attr => "return 1;", - arity => 3, + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, ins => [ "val_high", "val_low", "count" ], }, @@ -855,7 +837,7 @@ SarMem => { l_SarDep => { cmp_attr => "return 1;", ins => [ "val", "count", "dep" ], - arity => 3 + reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] }, }, Ror => { @@ -908,8 +890,6 @@ RolMem => { modified_flags => $status_flags }, -# unary operations - Neg => { irn_flags => "R", reg_req => { in => [ "gp" ], @@ -1021,8 +1001,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, @@ -1030,16 +1010,14 @@ 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", state => "exc_pinned", @@ -1061,9 +1039,10 @@ Cmp => { Cmp8Bit => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , + out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], - outs => [ "eflags" ], + outs => [ "eflags", "unused", "M" ], am => "source,binary", emit => '. cmpb %binop', attr => "int ins_permuted, int cmp_unsigned", @@ -1078,9 +1057,10 @@ Cmp8Bit => { Test => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , + out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], - outs => [ "eflags" ], + outs => [ "eflags", "unused", "M" ], am => "source,binary", emit => '. test%M %binop', attr => "int ins_permuted, int cmp_unsigned", @@ -1095,9 +1075,10 @@ Test => { Test8Bit => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , + out => [ "flags", "none", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], - outs => [ "eflags" ], + outs => [ "eflags", "unused", "M" ], am => "source,binary", emit => '. testb %binop', attr => "int ins_permuted, int cmp_unsigned", @@ -1109,42 +1090,42 @@ Test8Bit => { modified_flags => $status_flags }, -Set => { +Setcc => { #irn_flags => "R", 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 => "pn_Cmp pnc", + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", latency => 1, units => [ "GP" ], mode => $mode_gp, }, -SetMem => { +SetccMem => { #irn_flags => "R", 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 => "pn_Cmp pnc", + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", emit => '. set%CMP3 %AM', latency => 1, units => [ "GP" ], mode => 'mode_M', }, -CMov => { +CMovcc => { #irn_flags => "R", # (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" ] }, + 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", @@ -1169,13 +1150,24 @@ Jcc => { SwitchJmp => { state => "pinned", op_flags => "L|X|Y", - reg_req => { in => [ "gp" ], out => [ "none" ] }, + reg_req => { in => [ "gp" ] }, mode => "mode_T", attr_type => "ia32_condcode_attr_t", attr => "long pnc", latency => 3, units => [ "BRANCH" ], modified_flags => $status_flags, + init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements +}, + +Jmp => { + state => "pinned", + irn_flags => "J", + op_flags => "X", + reg_req => { out => [ "none" ] }, + latency => 1, + units => [ "BRANCH" ], + mode => "mode_X", }, IJmp => { @@ -1188,6 +1180,7 @@ IJmp => { latency => 1, units => [ "BRANCH" ], mode => "mode_X", + init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements }, Const => { @@ -1195,7 +1188,7 @@ Const => { irn_flags => "R", reg_req => { out => [ "gp" ] }, units => [ "GP" ], - attr => "ir_entity *symconst, int symconst_sign, long offset", + attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset", attr_type => "ia32_immediate_attr_t", latency => 1, mode => $mode_gp, @@ -1333,11 +1326,12 @@ Cltd => { Load => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "gp", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_exc" ], latency => 0, - emit => ". mov%SE%ME%.l %AM, %D0", + emit => ". mov%EX%.l %AM, %D0", units => [ "GP" ], }, @@ -1475,6 +1469,9 @@ LdTls => { latency => 1, }, +# +# BT supports source address mode, but this is unused yet +# Bt => { irn_flags => "R", state => "exc_pinned", @@ -1487,6 +1484,54 @@ Bt => { modified_flags => $status_flags # only CF is set, but the other flags are undefined }, +Bsf => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. bsf%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + +Bsr => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. bsr%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + +# +# SSE4.2 or SSE4a popcnt instruction +# +Popcnt => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "flags", "none" ] }, + ins => [ "base", "index", "mem", "operand" ], + outs => [ "res", "flags", "M" ], + am => "source,binary", + emit => '. popcnt%M %unop3, %D0', + units => [ "GP" ], + latency => 1, + mode => $mode_gp, + modified_flags => $status_flags +}, + Call => { state => "exc_pinned", reg_req => { @@ -1519,6 +1564,91 @@ ClimbFrame => { mode => $mode_gp }, +# +# bswap +# +Bswap => { + irn_flags => "R", + reg_req => { in => [ "gp" ], + out => [ "in_r1" ] }, + emit => '. bswap%M %S0', + ins => [ "val" ], + units => [ "GP" ], + latency => 1, + mode => $mode_gp, +}, + +# +# bswap16, use xchg here +# +Bswap16 => { + irn_flags => "R", + reg_req => { in => [ "eax ebx ecx edx" ], + out => [ "in_r1" ] }, + emit => '. xchg %SB0, %SH0', + ins => [ "val" ], + units => [ "GP" ], + latency => 1, + mode => $mode_gp, +}, + +# +# BreakPoint +# +Breakpoint => { + state => "pinned", + reg_req => { in => [ "none" ], out => [ "none" ] }, + ins => [ "mem" ], + latency => 0, + emit => ". int3", + units => [ "GP" ], + mode => mode_M, +}, + +# +# Undefined Instruction on ALL x86 CPU's +# +UD2 => { + state => "pinned", + reg_req => { in => [ "none" ], out => [ "none" ] }, + ins => [ "mem" ], + latency => 0, + emit => ". .value 0x0b0f", + units => [ "GP" ], + mode => mode_M, +}, + +# +# outport +# +Outport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] }, + ins => [ "port", "value", "mem" ], + emit => '. out%M %SS0, %SI1', + units => [ "GP" ], + latency => 1, + mode => mode_M, + modified_flags => $status_flags +}, + +# +# inport +# +Inport => { + irn_flags => "R", + state => "pinned", + reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] }, + ins => [ "port", "mem" ], + outs => [ "res", "M" ], + emit => '. in%M %DS0, %SS0', + units => [ "GP" ], + latency => 1, + mode => mode_T, + modified_flags => $status_flags +}, + # # Intel style prefetching # @@ -1529,7 +1659,7 @@ Prefetch0 => { ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetch0 %AM", + emit => ". prefetcht0 %AM", units => [ "GP" ], }, @@ -1540,7 +1670,7 @@ Prefetch1 => { ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetch1 %AM", + emit => ". prefetcht1 %AM", units => [ "GP" ], }, @@ -1551,7 +1681,7 @@ Prefetch2 => { ins => [ "base", "index", "mem" ], outs => [ "M" ], latency => 0, - emit => ". prefetch2 %AM", + emit => ". prefetcht2 %AM", units => [ "GP" ], }, @@ -1591,15 +1721,6 @@ PrefetchW => { units => [ "GP" ], }, -#-----------------------------------------------------------------------------# -# _____ _____ ______ __ _ _ _ # -# / ____/ ____| ____| / _| | | | | | # -# | (___| (___ | |__ | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ # -# \___ \\___ \| __| | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| # -# ____) |___) | |____ | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ # -# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ # -#-----------------------------------------------------------------------------# - # produces a 0/+0.0 xZero => { irn_flags => "R", @@ -1669,13 +1790,13 @@ xMovd => { mode => $mode_xmm }, -# commutative operations - xAdd => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. add%XXM %binop', latency => 4, @@ -1686,8 +1807,10 @@ xAdd => { xMul => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. mul%XXM %binop', latency => 4, @@ -1698,8 +1821,10 @@ xMul => { xMax => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. max%XXM %binop', latency => 2, @@ -1710,8 +1835,10 @@ xMax => { xMin => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. min%XXM %binop', latency => 2, @@ -1722,8 +1849,10 @@ xMin => { xAnd => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. andp%XSD %binop', latency => 3, @@ -1734,8 +1863,10 @@ xAnd => { xOr => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. orp%XSD %binop', latency => 3, @@ -1746,8 +1877,10 @@ xOr => { xXor => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. xorp%XSD %binop', latency => 3, @@ -1755,13 +1888,13 @@ xXor => { mode => $mode_xmm }, -# not commutative operations - xAndNot => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 !in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "left", "right" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. andnp%XSD %binop', latency => 3, @@ -1772,8 +1905,10 @@ xAndNot => { xSub => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4", "flags", "none" ] }, ins => [ "base", "index", "mem", "minuend", "subtrahend" ], + outs => [ "res", "flags", "M" ], am => "source,binary", emit => '. sub%XXM %binop', latency => 4, @@ -1784,21 +1919,21 @@ xSub => { xDiv => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "in_r4 !in_r5", "flags", "none" ] }, ins => [ "base", "index", "mem", "dividend", "divisor" ], + outs => [ "res", "flags", "M" ], am => "source,binary", - outs => [ "res", "M" ], emit => '. div%XXM %binop', latency => 16, units => [ "SSE" ], }, -# other operations - Ucomi => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "eflags" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], + out => [ "eflags" ] }, ins => [ "base", "index", "mem", "left", "right" ], outs => [ "flags" ], am => "source,binary", @@ -1811,14 +1946,13 @@ Ucomi => { modified_flags => 1, }, -# Load / Store - xLoad => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "xmm", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_exc" ], emit => '. mov%XXM %AM, %D0', attr => "ir_mode *load_mode", init_attr => "attr->ls_mode = load_mode;", @@ -1841,8 +1975,9 @@ xStore => { xStoreSimple => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M" ], emit => '. mov%XXM %S3, %AM', latency => 0, units => [ "SSE" ], @@ -1878,6 +2013,7 @@ l_LLtoFloat => { op_flags => "L|F", cmp_attr => "return 1;", ins => [ "val_high", "val_low" ], + reg_req => { in => [ "none", "none" ], out => [ "none" ] } }, l_FloattoLL => { @@ -1885,10 +2021,9 @@ l_FloattoLL => { cmp_attr => "return 1;", ins => [ "val" ], outs => [ "res_high", "res_low" ], + reg_req => { in => [ "none" ], out => [ "none", "none" ] } }, -# CopyB - CopyB => { op_flags => "F|H", state => "pinned", @@ -1915,8 +2050,6 @@ CopyB_i => { # modified_flags => [ "DF" ] }, -# Conversions - Cwtl => { state => "exc_pinned", reg_req => { in => [ "eax" ], out => [ "eax" ] }, @@ -1930,9 +2063,10 @@ Cwtl => { Conv_I2I => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp" ], + out => [ "gp", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], - outs => [ "res", "M" ], + outs => [ "res", "flags", "M" ], am => "source,unary", units => [ "GP" ], latency => 1, @@ -1943,8 +2077,10 @@ Conv_I2I => { Conv_I2I8Bit => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "gp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], + out => [ "gp", "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "res", "flags", "M" ], am => "source,unary", units => [ "GP" ], latency => 1, @@ -1983,28 +2119,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", 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" ], @@ -2015,8 +2139,10 @@ vfadd => { vfmul => { # irn_flags => "R", 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" ], @@ -2027,8 +2153,10 @@ vfmul => { vfsub => { # irn_flags => "R", 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" ], @@ -2038,10 +2166,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", @@ -2076,15 +2205,14 @@ vfchs => { attr_type => "ia32_x87_attr_t", }, -# virtual Load and Store - vfld => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "vfp", "none", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M", "X_exc" ], + outs => [ "res", "unused", "M", "X_exc" ], attr => "ir_mode *load_mode", init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, @@ -2096,7 +2224,8 @@ vfst => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "none", "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp" ], + out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], outs => [ "M", "X_exc" ], attr => "ir_mode *store_mode", @@ -2107,12 +2236,11 @@ vfst => { attr_type => "ia32_x87_attr_t", }, -# Conversions - vfild => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, - outs => [ "res", "M" ], + reg_req => { in => [ "gp", "gp", "none" ], + out => [ "vfp", "none", "none" ] }, + outs => [ "res", "unused", "M" ], ins => [ "base", "index", "mem" ], latency => 4, units => [ "VFP" ], @@ -2121,8 +2249,9 @@ vfild => { vfist => { state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], out => [ "none" ] }, ins => [ "base", "index", "mem", "val", "fpcw" ], + outs => [ "M" ], latency => 4, units => [ "VFP" ], mode => "mode_M", @@ -2140,9 +2269,6 @@ vfisttp => { attr_type => "ia32_x87_attr_t", }, - -# constants - vfldz => { irn_flags => "R", reg_req => { out => [ "vfp" ] }, @@ -2213,10 +2339,8 @@ 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", reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] }, @@ -2267,245 +2391,208 @@ 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 => { }, 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 +# 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 => { }, emit => '. fchs', latency => 4, attr_type => "ia32_x87_attr_t", + constructors => {}, }, -# x87 Load and Store - fld => { - rd_constructor => "NONE", op_flags => "R|L|F", 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", 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", 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 firsttp instruction +# 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", @@ -2575,7 +2662,7 @@ fldl2e => { fxch => { op_flags => "R|K", - reg_req => { }, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fxch %X0', attr_type => "ia32_x87_attr_t", @@ -2585,7 +2672,7 @@ fxch => { fpush => { op_flags => "R|K", - reg_req => {}, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fld %X0', attr_type => "ia32_x87_attr_t", @@ -2603,7 +2690,7 @@ fpushCopy => { fpop => { op_flags => "K", - reg_req => { }, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. fstp %X0', attr_type => "ia32_x87_attr_t", @@ -2613,7 +2700,7 @@ fpop => { ffreep => { op_flags => "K", - reg_req => { }, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. ffreep %X0', attr_type => "ia32_x87_attr_t", @@ -2623,7 +2710,7 @@ ffreep => { emms => { op_flags => "K", - reg_req => { }, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. emms', attr_type => "ia32_x87_attr_t", @@ -2633,7 +2720,7 @@ emms => { femms => { op_flags => "K", - reg_req => { }, + reg_req => { out => [ "none" ] }, cmp_attr => "return 1;", emit => '. femms', attr_type => "ia32_x87_attr_t", @@ -2641,8 +2728,6 @@ femms => { latency => 3, }, -# compare - FucomFnstsw => { reg_req => { }, emit => ". fucom %X1\n". @@ -2689,17 +2774,6 @@ FtstFnstsw => { latency => 2, }, - -# -------------------------------------------------------------------------------- # -# ____ ____ _____ _ _ # -# / ___/ ___|| ____| __ _____ ___| |_ ___ _ __ _ __ ___ __| | ___ ___ # -# \___ \___ \| _| \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __| # -# ___) |__) | |___ \ V / __/ (__| || (_) | | | | | | (_) | (_| | __/\__ \ # -# |____/____/|_____| \_/ \___|\___|\__\___/|_| |_| |_|\___/ \__,_|\___||___/ # -# # -# -------------------------------------------------------------------------------- # - - # Spilling and reloading of SSE registers, hardcoded, not generated # xxLoad => { @@ -2725,14 +2799,6 @@ xxStore => { ); # 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};