Remove ia32_Sub64Bit. Replace it by Sub and Sbb.
[libfirm] / ir / be / ia32 / ia32_spec.pl
index f67bcb1..dc0c49d 100644 (file)
@@ -110,10 +110,10 @@ $arch = "ia32";
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
        gp => [
-               { name => "eax", type => 1 },
                { name => "edx", type => 1 },
-               { name => "ebx", type => 2 },
                { name => "ecx", type => 1 },
+               { name => "eax", type => 1 },
+               { name => "ebx", type => 2 },
                { name => "esi", type => 2 },
                { name => "edi", type => 2 },
                { name => "ebp", type => 2 },
@@ -193,50 +193,49 @@ $arch = "ia32";
 ); # vliw
 
 %emit_templates = (
-       S0 => "${arch}_emit_source_register(env, node, 0);",
-       S1 => "${arch}_emit_source_register(env, node, 1);",
-       S2 => "${arch}_emit_source_register(env, node, 2);",
-       S3 => "${arch}_emit_source_register(env, node, 3);",
-       S4 => "${arch}_emit_source_register(env, node, 4);",
-       S5 => "${arch}_emit_source_register(env, node, 5);",
-       SB1 => "${arch}_emit_8bit_source_register(env, node, 1);",
-       SB2 => "${arch}_emit_8bit_source_register(env, node, 2);",
-       SB3 => "${arch}_emit_8bit_source_register(env, node, 3);",
-       SW0 => "${arch}_emit_16bit_source_register(env, node, 0);",
-       SI0 => "${arch}_emit_source_register_or_immediate(env, node, 0);",
-       SI1 => "${arch}_emit_source_register_or_immediate(env, node, 1);",
-       SI2 => "${arch}_emit_source_register_or_immediate(env, node, 2);",
-       SI3 => "${arch}_emit_source_register_or_immediate(env, node, 3);",
-       D0 => "${arch}_emit_dest_register(env, node, 0);",
-       D1 => "${arch}_emit_dest_register(env, node, 1);",
-       D2 => "${arch}_emit_dest_register(env, node, 2);",
-       D3 => "${arch}_emit_dest_register(env, node, 3);",
-       D4 => "${arch}_emit_dest_register(env, node, 4);",
-       D5 => "${arch}_emit_dest_register(env, node, 5);",
-       DB0 => "${arch}_emit_8bit_dest_register(env, node, 0);",
-       X0 => "${arch}_emit_x87_name(env, node, 0);",
-       X1 => "${arch}_emit_x87_name(env, node, 1);",
-       X2 => "${arch}_emit_x87_name(env, node, 2);",
-       SE => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));",
+       S0 => "${arch}_emit_source_register(node, 0);",
+       S1 => "${arch}_emit_source_register(node, 1);",
+       S2 => "${arch}_emit_source_register(node, 2);",
+       S3 => "${arch}_emit_source_register(node, 3);",
+       S4 => "${arch}_emit_source_register(node, 4);",
+       S5 => "${arch}_emit_source_register(node, 5);",
+       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);",
+       SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
+       SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
+       SI2 => "${arch}_emit_source_register_or_immediate(node, 2);",
+       SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
+       D0 => "${arch}_emit_dest_register(node, 0);",
+       D1 => "${arch}_emit_dest_register(node, 1);",
+       D2 => "${arch}_emit_dest_register(node, 2);",
+       D3 => "${arch}_emit_dest_register(node, 3);",
+       D4 => "${arch}_emit_dest_register(node, 4);",
+       D5 => "${arch}_emit_dest_register(node, 5);",
+       DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
+       X0 => "${arch}_emit_x87_register(node, 0);",
+       X1 => "${arch}_emit_x87_register(node, 1);",
+       X2 => "${arch}_emit_x87_register(node, 2);",
+       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(env, node);",
-       M  => "${arch}_emit_mode_suffix(env, node);",
-       XM => "${arch}_emit_x87_mode_suffix(env, node);",
-       XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
-       XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);",
-       AM => "${arch}_emit_am(env, node);",
-       unop0 => "${arch}_emit_unop(env, node, 0);",
-       unop1 => "${arch}_emit_unop(env, node, 1);",
-       unop2 => "${arch}_emit_unop(env, node, 2);",
-       unop3 => "${arch}_emit_unop(env, node, 3);",
-       unop4 => "${arch}_emit_unop(env, node, 4);",
-       unop5 => "${arch}_emit_unop(env, node, 5);",
-       DAM0  => "${arch}_emit_am_or_dest_register(env, node, 0);",
-       DAM1  => "${arch}_emit_am_or_dest_register(env, node, 1);",
-       binop => "${arch}_emit_binop(env, node, 1);",
-       binop_nores => "${arch}_emit_binop(env, node, 0);",
-       x87_binop => "${arch}_emit_x87_binop(env, node);",
-       CMP0  => "${arch}_emit_cmp_suffix_node(env, node, 0);",
+                  ia32_emit_mode_suffix(node);",
+       M  => "${arch}_emit_mode_suffix(node);",
+       XM => "${arch}_emit_x87_mode_suffix(node);",
+       XXM => "${arch}_emit_xmm_mode_suffix(node);",
+       XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
+       AM => "${arch}_emit_am(node);",
+       unop0 => "${arch}_emit_unop(node, 0);",
+       unop1 => "${arch}_emit_unop(node, 1);",
+       unop2 => "${arch}_emit_unop(node, 2);",
+       unop3 => "${arch}_emit_unop(node, 3);",
+       unop4 => "${arch}_emit_unop(node, 4);",
+       unop5 => "${arch}_emit_unop(node, 5);",
+       DAM0  => "${arch}_emit_am_or_dest_register(node, 0);",
+       DAM1  => "${arch}_emit_am_or_dest_register(node, 1);",
+       binop => "${arch}_emit_binop(node, 1);",
+       binop_nores => "${arch}_emit_binop(node, 0);",
+       x87_binop => "${arch}_emit_x87_binop(node);",
+       CMP0  => "${arch}_emit_cmp_suffix_node(node, 0);",
 );
 
 #--------------------------------------------------#
@@ -365,7 +364,7 @@ ProduceVal => {
 
 Add => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "none", "flags" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "none", "flags" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. add%M %binop',
        am        => "full,binary",
@@ -395,7 +394,7 @@ AddMem8Bit => {
 },
 
 Adc => {
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
        emit      => '. adc%M %binop',
        am        => "full,binary",
@@ -415,21 +414,6 @@ l_Adc => {
        ins       => [ "left", "right", "eflags" ],
 },
 
-Add64Bit => {
-       irn_flags => "R",
-       arity     => 4,
-       reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "!in", "!in" ] },
-       emit      => '
-. movl %S0, %D0
-. movl %S1, %D1
-. addl %SI2, %D0
-. adcl %SI3, %D1
-',
-       outs      => [ "low_res", "high_res" ],
-       units     => [ "GP" ],
-       modified_flags => $status_flags
-},
-
 Mul => {
        # we should not rematrialize this node. It produces 2 results and has
        # very strict constrains
@@ -454,7 +438,7 @@ l_Mul => {
 
 IMul => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. imul%M %binop',
        am        => "source,binary",
@@ -487,7 +471,7 @@ l_IMul => {
 
 And => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        am        => "full,binary",
        emit      => '. and%M %binop',
@@ -518,7 +502,7 @@ AndMem8Bit => {
 
 Or => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        am        => "full,binary",
        emit      => '. or%M %binop',
@@ -549,7 +533,7 @@ OrMem8Bit => {
 
 Xor => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        am        => "full,binary",
        emit      => '. xor%M %binop',
@@ -582,7 +566,7 @@ XorMem8Bit => {
 
 Sub => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "none", "flags" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        am        => "full,binary",
        emit      => '. sub%M %binop',
@@ -612,8 +596,8 @@ SubMem8Bit => {
 },
 
 Sbb => {
-       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 !in_r5" ] },
-       ins       => [ "base", "index", "mem", "left", "right" ],
+       reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4 !in_r5" ] },
+       ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
        am        => "full,binary",
        emit      => '. sbb%M %binop',
        units     => [ "GP" ],
@@ -621,19 +605,14 @@ Sbb => {
        modified_flags => $status_flags
 },
 
-Sub64Bit => {
-       irn_flags => "R",
-       arity     => 4,
-       reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "!in", "!in" ] },
-       emit      => '
-. movl %S0, %D0
-. movl %S1, %D1
-. subl %SI2, %D0
-. sbbl %SI3, %D1
-',
-       outs      => [ "low_res", "high_res" ],
-       units     => [ "GP" ],
-       modified_flags => $status_flags
+l_Sub => {
+       reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
+       ins       => [ "left", "right" ],
+},
+
+l_Sbb => {
+       reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
+       ins       => [ "left", "right", "eflags" ],
 },
 
 IDiv => {
@@ -1021,7 +1000,7 @@ Set => {
        ins       => [ "eflags" ],
        am        => "dest,unary",
        attr      => "pn_Cmp pnc",
-       init_attr => "attr->pn_code = pnc;",
+       init_attr => "attr->pn_code = pnc;\nset_ia32_ls_mode(res, mode_Bu);\n",
        emit      => '. set%CMP0 %DB0',
        latency   => 1,
        units     => [ "GP" ],
@@ -1182,8 +1161,7 @@ FnstCW => {
 },
 
 Cltd => {
-       # we should not rematrialize this node. It produces 2 results and has
-       # very strict constrains
+       # we should not rematrialize this node. It has very strict constraints.
        reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
        ins       => [ "val", "globbered" ],
        emit      => '. cltd',
@@ -1356,7 +1334,7 @@ xZero => {
 
 xAdd => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. add%XXM %binop',
        latency   => 4,
@@ -1366,7 +1344,7 @@ xAdd => {
 
 xMul => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. mul%XXM %binop',
        latency   => 4,
@@ -1376,7 +1354,7 @@ xMul => {
 
 xMax => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. max%XXM %binop',
        latency   => 2,
@@ -1386,7 +1364,7 @@ xMax => {
 
 xMin => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. min%XXM %binop',
        latency   => 2,
@@ -1396,7 +1374,7 @@ xMin => {
 
 xAnd => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. andp%XSD %binop',
        latency   => 3,
@@ -1406,7 +1384,7 @@ xAnd => {
 
 xOr => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. orp%XSD %binop',
        units     => [ "SSE" ],
@@ -1415,7 +1393,7 @@ xOr => {
 
 xXor => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
        ins       => [ "base", "index", "mem", "left", "right" ],
        emit      => '. xorp%XSD %binop',
        latency   => 3,
@@ -1568,7 +1546,7 @@ CopyB_i => {
 
 Conv_I2I => {
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "in_r4", "none" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "none" ] },
        ins       => [ "base", "index", "mem", "val" ],
        units     => [ "GP" ],
        attr      => "ir_mode *smaller_mode",
@@ -1578,7 +1556,7 @@ Conv_I2I => {
 
 Conv_I2I8Bit => {
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "in_r4", "none" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "gp", "none" ] },
        ins       => [ "base", "index", "mem", "val" ],
        units     => [ "GP" ],
        attr      => "ir_mode *smaller_mode",