{ 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 },
{ 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);",
%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 = (
# 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",
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,
+#},
);