X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Famd64%2Famd64_spec.pl;h=fd7897158995831f8264a9e4252e702b843e15ad;hb=0754bb717d5761ad49a36f0e29829ffac413d92e;hp=64136095705a0ffabd87a44aca3cea254df7b880;hpb=af300963705d97b2f596e8cf2887813c25de6ad8;p=libfirm diff --git a/ir/be/amd64/amd64_spec.pl b/ir/be/amd64/amd64_spec.pl index 641360957..fd7897158 100644 --- a/ir/be/amd64/amd64_spec.pl +++ b/ir/be/amd64/amd64_spec.pl @@ -1,109 +1,47 @@ -# Creation: 2006/02/13 -# $Id: amd64_spec.pl 26673 2009-10-01 16:43:13Z matze $ - -# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...) - $arch = "amd64"; -# The node description is done as a perl hash initializer with the -# following structure: -# -# %nodes = ( -# -# => { -# arity => "0|1|2|3 ... |variable|dynamic|any", # optional -# state => "floats|pinned|mem_pinned|exc_pinned", # optional -# args => [ -# { type => "type 1", name => "name 1" }, -# { type => "type 2", name => "name 2" }, -# ... -# ], -# comment => "any comment for constructor", # optional -# reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] }, -# cmp_attr => "c source code for comparing node attributes", # optional -# 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", # optional for virtual nodes -# attr => "additional attribute arguments for constructor", # optional -# init_attr => "emit attribute initialization template", # optional -# rd_constructor => "c source code which constructs an ir_node", # optional -# hash_func => "name of the hash function for this operation", # optional, get the default hash function else -# latency => "latency of this operation (can be float)" # optional -# attr_type => "name of the attribute struct", # optional -# }, -# -# ... # (all nodes you need to describe) -# -# ); # close the %nodes initializer - -# 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 -# -# comment: OPTIONAL comment for the node constructor -# -# register types: -$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 => "rax", type => $caller_save }, - { name => "rcx", type => $caller_save }, - { name => "rdx", type => $caller_save }, - { name => "rsi", type => $caller_save }, - { name => "rdi", type => $caller_save }, - { name => "rbx", type => $callee_save }, - { name => "rbp", type => $callee_save }, - { name => "rsp", type => 4 }, # stackpointer? - { name => "r8", type => $caller_save }, - { name => "r9", type => $caller_save }, - { name => "r10", type => $caller_save }, - { name => "r11", type => $caller_save }, - { name => "r12", type => $callee_save }, - { name => "r13", type => $callee_save }, - { name => "r14", type => $callee_save }, - { name => "r15", type => $callee_save }, -# { name => "gp_NOREG", type => $ignore }, # we need a dummy register for NoReg nodes + { name => "rax", dwarf => 0 }, + { name => "rcx", dwarf => 2 }, + { name => "rdx", dwarf => 1 }, + { name => "rsi", dwarf => 4 }, + { name => "rdi", dwarf => 5 }, + { name => "rbx", dwarf => 3 }, + { name => "rbp", dwarf => 6 }, + { name => "rsp", dwarf => 7, type => "ignore" }, # stackpointer + { name => "r8", dwarf => 8 }, + { name => "r9", dwarf => 9 }, + { name => "r10", dwarf => 10 }, + { name => "r11", dwarf => 11 }, + { name => "r12", dwarf => 12 }, + { name => "r13", dwarf => 13 }, + { name => "r14", dwarf => 14 }, + { name => "r15", dwarf => 15 }, +# { name => "gp_NOREG", type => "ignore" }, # we need a dummy register for NoReg nodes { mode => "mode_Lu" } ], # fp => [ -# { 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 => "xmm8", type => $caller_save }, -# { name => "xmm9", type => $caller_save }, -# { name => "xmm10", type => $caller_save }, -# { name => "xmm11", type => $caller_save }, -# { name => "xmm12", type => $caller_save }, -# { name => "xmm13", type => $caller_save }, -# { name => "xmm14", type => $caller_save }, -# { name => "xmm15", type => $caller_save }, +# { name => "xmm0", dwarf => 17 }, +# { name => "xmm1", dwarf => 18 }, +# { name => "xmm2", dwarf => 19 }, +# { name => "xmm3", dwarf => 20 }, +# { name => "xmm4", dwarf => 21 }, +# { name => "xmm5", dwarf => 22 }, +# { name => "xmm6", dwarf => 23 }, +# { name => "xmm7", dwarf => 24 }, +# { name => "xmm8", dwarf => 25 }, +# { name => "xmm9", dwarf => 26 }, +# { name => "xmm10", dwarf => 27 }, +# { name => "xmm11", dwarf => 28 }, +# { name => "xmm12", dwarf => 29 }, +# { name => "xmm13", dwarf => 30 }, +# { name => "xmm14", dwarf => 31 }, +# { name => "xmm15", dwarf => 32 }, # { mode => "mode_D" } # ] flags => [ - { name => "eflags", type => 0 }, + { name => "eflags", dwarf => 49 }, { mode => "mode_Iu", flags => "manual_ra" } ], ); @@ -118,7 +56,7 @@ sub amd64_custom_init_attr { my $res = ""; if(defined($node->{modified_flags})) { - $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"; + $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"; } return $res; } @@ -126,31 +64,14 @@ $custom_init_attr_func = \&amd64_custom_init_attr; $default_copy_attr = "amd64_copy_attr"; -%emit_templates = ( - S1 => "${arch}_emit_source_register(node, 0);", - S2 => "${arch}_emit_source_register(node, 1);", - S3 => "${arch}_emit_source_register(node, 2);", - S4 => "${arch}_emit_source_register(node, 3);", - S5 => "${arch}_emit_source_register(node, 4);", - S6 => "${arch}_emit_source_register(node, 5);", - D1 => "${arch}_emit_dest_register(node, 0);", - D2 => "${arch}_emit_dest_register(node, 1);", - D3 => "${arch}_emit_dest_register(node, 2);", - D4 => "${arch}_emit_dest_register(node, 3);", - D5 => "${arch}_emit_dest_register(node, 4);", - D6 => "${arch}_emit_dest_register(node, 5);", - C => "${arch}_emit_immediate(node);", - O => "${arch}_emit_fp_offset(node);", -); - %init_attr = ( amd64_attr_t => - "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);", + "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);", amd64_SymConst_attr_t => - "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);" + "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);" . "\tinit_amd64_SymConst_attributes(res, entity);", amd64_condcode_attr_t => - "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);" + "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);" . "\tinit_amd64_condcode_attributes(res, pnc);", ); @@ -162,26 +83,27 @@ $default_copy_attr = "amd64_copy_attr"; %nodes = ( Push => { + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "gp", "rsp" ], out => [ "rsp:I|S", "none" ] }, ins => [ "base", "index", "mem", "val", "stack" ], - emit => '. push %S1', + emit => 'push %S0', outs => [ "stack", "M" ], am => "source,unary", - latency => 2, -# units => [ "GP" ], }, + Add => { op_flags => [ "commutative" ], irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - in => [ "left", "right" ], + ins => [ "left", "right" ], outs => [ "res" ], mode => $mode_gp, modified_flags => 1, }, + Mul => { # we should not rematrialize this node. It produces 2 results and has # very strict constraints @@ -189,40 +111,44 @@ Mul => { reg_req => { in => [ "rax", "gp" ], out => [ "rax rdx" ] }, ins => [ "left", "right" ], - emit => '. mul %S2', + emit => 'mul %S1', outs => [ "res" ], mode => $mode_gp, am => "source,binary", modified_flags => $status_flags }, + Sub => { irn_flags => [ "rematerializable" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - in => [ "left", "right" ], + ins => [ "left", "right" ], outs => [ "res" ], mode => $mode_gp, modified_flags => 1, }, + Neg => { irn_flags => [ "rematerializable" ], reg_req => { in => [ "gp" ], - out => [ "in_r1", "flags" ] }, - emit => '. neg %S1', + out => [ "in_r1" ] }, + emit => 'neg %S0', ins => [ "val" ], - outs => [ "res", "flags" ], + outs => [ "res" ], mode => $mode_gp, modified_flags => $status_flags }, + Immediate => { op_flags => [ "constlike" ], attr => "unsigned imm_value", init_attr => "attr->ext.imm_value = imm_value;", reg_req => { out => [ "gp" ] }, - emit => '. mov %C, %D1', + emit => 'mov %C, %D0', mode => $mode_gp, }, + SymConst => { op_flags => [ "constlike" ], irn_flags => [ "rematerializable" ], @@ -232,6 +158,7 @@ SymConst => { outs => [ "res" ], mode => $mode_gp, }, + Conv => { state => "exc_pinned", attr => "ir_mode *smaller_mode", @@ -241,12 +168,14 @@ Conv => { outs => [ "res" ], mode => $mode_gp, }, + Jmp => { state => "pinned", op_flags => [ "cfopcode" ], reg_req => { out => [ "none" ] }, mode => "mode_X", }, + Cmp => { irn_flags => [ "rematerializable" ], state => "exc_pinned", @@ -254,16 +183,17 @@ Cmp => { out => [ "flags" ] }, ins => [ "left", "right" ], outs => [ "eflags" ], - emit => '. cmp %S1, %S2', + emit => 'cmp %S0, %S1', attr => "int ins_permuted, int cmp_unsigned", init_attr => "attr->data.ins_permuted = ins_permuted;\n". "\tattr->data.cmp_unsigned = cmp_unsigned;\n", mode => $mode_flags, modified_flags => 1, }, + Jcc => { state => "pinned", - op_flags => [ "labeled", "cfopcode", "forking" ], + op_flags => [ "cfopcode", "forking" ], reg_req => { in => [ "eflags" ], out => [ "none", "none" ] }, ins => [ "eflags" ], outs => [ "false", "true" ], @@ -271,8 +201,9 @@ Jcc => { init_attr => "attr->ext.relation = relation;", mode => "mode_T", }, + Load => { - op_flags => [ "labeled", "fragile" ], + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] }, @@ -280,8 +211,9 @@ Load => { outs => [ "res", "M" ], attr => "ir_entity *entity", attr_type => "amd64_SymConst_attr_t", - emit => ". mov %O(%S1), %D1" + emit => "mov %O(%S0), %D0" }, + FrameAddr => { op_flags => [ "constlike" ], irn_flags => [ "rematerializable" ], @@ -291,8 +223,9 @@ FrameAddr => { attr_type => "amd64_SymConst_attr_t", mode => $mode_gp, }, + Store => { - op_flags => [ "labeled", "fragile" ], + op_flags => [ "uses_memory" ], state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, ins => [ "ptr", "val", "mem" ], @@ -300,16 +233,6 @@ Store => { attr => "ir_entity *entity", attr_type => "amd64_SymConst_attr_t", mode => "mode_M", - emit => ". mov %S2, %O(%S1)" + emit => "mov %S1, %O(%S0)" }, - -#NoReg_GP => { -# state => "pinned", -# op_flags => [ "constlike", "dump_noblcok", "dump_noinput" ], -# reg_req => { out => [ "gp_NOREG:I" ] }, -# units => [], -# emit => "", -# latency => 0, -# mode => $mode_gp, -#}, );