X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Famd64%2Famd64_spec.pl;h=8d81010ed5e5dc088ca17a424b1c4a3b68f32803;hb=ec6929684fd32404d7ba0f0df5498d2230f3abc0;hp=5862e9629b5179acbae73c534b898a5a1092d8c0;hpb=6f5e548d48567ee01f0d0cc33d5bd0addda48ca1;p=libfirm diff --git a/ir/be/amd64/amd64_spec.pl b/ir/be/amd64/amd64_spec.pl index 5862e9629..8d81010ed 100644 --- a/ir/be/amd64/amd64_spec.pl +++ b/ir/be/amd64/amd64_spec.pl @@ -101,9 +101,9 @@ $arch = "amd64"; { name => "rax", type => 1 }, { name => "rcx", type => 1 }, { name => "rdx", type => 1 }, + { name => "rsi", type => 1 }, + { name => "rdi", type => 1 }, { name => "rbx", type => 2 }, - { name => "rsi", type => 2 }, - { name => "rdi", type => 2 }, { name => "rbp", type => 2 }, { name => "rsp", type => 4 }, # stackpointer? { name => "r8", type => 1 }, @@ -114,29 +114,50 @@ $arch = "amd64"; { name => "r13", type => 2 }, { name => "r14", type => 2 }, { name => "r15", type => 2 }, - { mode => "mode_Iu" } +# { name => "gp_NOREG", type => 4 }, # we need a dummy register for NoReg nodes + { mode => "mode_Lu" } + ], +# fp => [ +# { 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 => "xmm8", type => 1 }, +# { name => "xmm9", type => 1 }, +# { name => "xmm10", type => 1 }, +# { name => "xmm11", type => 1 }, +# { name => "xmm12", type => 1 }, +# { name => "xmm13", type => 1 }, +# { name => "xmm14", type => 1 }, +# { name => "xmm15", type => 1 }, +# { mode => "mode_D" } +# ] + flags => [ + { name => "eflags", type => 0 }, + { mode => "mode_Iu", flags => "manual_ra" } ], - fp => [ - { 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 => "xmm8", type => 1 }, - { name => "xmm9", type => 1 }, - { name => "xmm10", type => 1 }, - { name => "xmm11", type => 1 }, - { name => "xmm12", type => 1 }, - { name => "xmm13", type => 1 }, - { name => "xmm14", type => 1 }, - { name => "xmm15", type => 1 }, - { mode => "mode_D" } - ] ); +$mode_gp = "mode_Lu"; +$mode_flags = "mode_Iu"; + +sub amd64_custom_init_attr { + 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"; + } + return $res; +} +$custom_init_attr_func = \&amd64_custom_init_attr; + %emit_templates = ( S1 => "${arch}_emit_source_register(node, 0);", S2 => "${arch}_emit_source_register(node, 1);", @@ -156,18 +177,18 @@ $arch = "amd64"; %init_attr = ( amd64_attr_t => "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);", - amd64_immediate_attr_t => - "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);" - . "\tinit_amd64_immediate_attributes(res, imm_value);", amd64_SymConst_attr_t => "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, 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_condcode_attributes(res, pnc);", ); %compare_attr = ( amd64_attr_t => "cmp_amd64_attr", - amd64_immediate_attr_t => "cmp_amd64_attr_immediate", amd64_SymConst_attr_t => "cmp_amd64_attr_SymConst", + amd64_condcode_attr_t => "cmp_amd64_attr_condcode", ); %nodes = ( @@ -182,23 +203,46 @@ Push => { # units => [ "GP" ], }, Add => { + op_flags => "C", + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp" ], + out => [ "gp" ] }, + in => [ "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 + state => "exc_pinned", + reg_req => { in => [ "rax", "gp" ], + out => [ "rax rdx" ] }, + ins => [ "left", "right" ], + emit => '. mul %S2', + outs => [ "res" ], + mode => $mode_gp, + am => "source,binary", + modified_flags => $status_flags +}, +Sub => { irn_flags => "R", state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, in => [ "left", "right" ], - emit => ". mov %S2, %D1\n" - . ". add %S1, %D1\n", outs => [ "res" ], - mode => "mode_Iu", + mode => $mode_gp, + modified_flags => 1, }, Immediate => { op_flags => "c", attr => "unsigned imm_value", - attr_type => "amd64_immediate_attr_t", + init_attr => "attr->ext.imm_value = imm_value;", reg_req => { out => [ "gp" ] }, - emit => '. movq %C, %D1', - mode => "mode_Iu", + emit => '. mov %C, %D1', + mode => $mode_gp, }, SymConst => { op_flags => "c", @@ -206,6 +250,82 @@ SymConst => { attr => "ir_entity *entity", attr_type => "amd64_SymConst_attr_t", reg_req => { out => [ "gp" ] }, - mode => 'mode_Iu', + mode => $mode_gp, +}, +Conv => { + state => "exc_pinned", + attr => "ir_mode *smaller_mode", + init_attr => "attr->ls_mode = smaller_mode;", + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + ins => [ "val" ], + outs => [ "res" ], + mode => $mode_gp, +}, +Jmp => { + state => "pinned", + op_flags => "X", + reg_req => { out => [ "none" ] }, + mode => "mode_X", +}, +Cmp => { + irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp" ], + out => [ "flags" ] }, + ins => [ "left", "right" ], + outs => [ "eflags" ], + emit => '. cmp %S1, %S2', + 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 => "L|X|Y", + reg_req => { in => [ "eflags" ], out => [ "none", "none" ] }, + ins => [ "eflags" ], + outs => [ "false", "true" ], + attr => "pn_Cmp pnc", + init_attr => "attr->ext.pnc = pnc;", + mode => "mode_T", +}, +Load => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "gp", "none" ], + out => [ "gp", "none" ] }, + ins => [ "ptr", "mem" ], + outs => [ "res", "M" ], + emit => ". mov (%S1), %D1" }, +FrameAddr => { + op_flags => "c", + irn_flags => "R", + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + ins => [ "base" ], + attr => "ir_entity *entity", + attr_type => "amd64_SymConst_attr_t", + mode => $mode_gp, +}, +Store => { + op_flags => "L|F", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] }, + ins => [ "ptr", "val", "mem" ], + outs => [ "M" ], + mode => "mode_M", + emit => ". mov %S2, (%S1)" +}, + +#NoReg_GP => { +# state => "pinned", +# op_flags => "c|NB|NI", +# reg_req => { out => [ "gp_NOREG:I" ] }, +# units => [], +# emit => "", +# latency => 0, +# mode => $mode_gp, +#}, );