Commit 9af128bc authored by Christoph Mallon's avatar Christoph Mallon
Browse files

ia32: Merge Test and Test8Bit.

parent 9c456297
......@@ -2046,17 +2046,8 @@ static void bemit_binop_with_imm(
/* Use in-reg, because some instructions (cmp, test) have no out-reg. */
const ir_node *op = get_irn_n(node, n_ia32_binary_right);
const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
unsigned size;
/* Some instructions (test) have no short form with 32bit value + 8bit
* immediate. */
if (attr->symconst != NULL || opcode & OP_IMM8) {
size = 4;
} else {
/* check for sign extension */
size = get_signed_imm_size(attr->offset);
}
unsigned const size = attr->symconst ? 4 : get_signed_imm_size(attr->offset);
switch (size) {
case 1:
bemit8(opcode | OP_16_32_IMM8);
......@@ -2235,7 +2226,6 @@ BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
BINOP(and, 0x23, 0x25, 0x81, 4)
BINOP(sub, 0x2B, 0x2D, 0x81, 5)
BINOP(xor, 0x33, 0x35, 0x81, 6)
BINOP(test, 0x85, 0xA9, 0xF7, 0)
#define BINOPMEM(op, ext) \
static void bemit_##op(const ir_node *node) \
......@@ -2617,31 +2607,45 @@ static void bemit_cmp8bit(const ir_node *node)
}
}
static void bemit_test8bit(const ir_node *node)
static void bemit_test(ir_node const *const node)
{
ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
if (size == 16)
bemit8(0x66);
unsigned const op = size == 8 ? OP_8 : OP_16_32;
ir_node *const right = get_irn_n(node, n_ia32_Test_right);
if (is_ia32_Immediate(right)) {
/* Emit the main opcode. */
if (get_ia32_op_type(node) == ia32_Normal) {
const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
if (out->index == REG_GP_EAX) {
bemit8(0xA8);
arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
/* Try to use the shorter al/ax/eax form. */
if (dst->index == REG_GP_EAX) {
bemit8(0xA8 | op);
} else {
bemit8(0xF6);
bemit_modru(out, 0);
bemit8(0xF6 | op);
bemit_modru(dst, 0);
}
} else {
bemit8(0xF6);
bemit8(0xF6 | op);
bemit_mod_am(0, node);
}
bemit8(get_ia32_immediate_attr_const(right)->offset);
/* Emit the immediate. */
ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
switch (size) {
case 8: bemit8(attr->offset); break;
case 16: bemit16(attr->offset); break;
case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
}
} else {
const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
bemit8(0x84);
bemit8(0x84 | op);
arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
if (get_ia32_op_type(node) == ia32_Normal) {
const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Test8Bit_right);
bemit_modrr(out, in);
arch_register_t const *const src = arch_get_irn_register(right);
bemit_modrr(src, dst);
} else {
bemit_mod_am(reg_gp_map[out->index], node);
bemit_mod_am(reg_gp_map[dst->index], node);
}
}
}
......@@ -3518,7 +3522,6 @@ static void ia32_register_binary_emitters(void)
be_set_emitter(op_ia32_SubSP, bemit_subsp);
be_set_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
be_set_emitter(op_ia32_Test, bemit_test);
be_set_emitter(op_ia32_Test8Bit, bemit_test8bit);
be_set_emitter(op_ia32_Xor, bemit_xor);
be_set_emitter(op_ia32_Xor0, bemit_xor0);
be_set_emitter(op_ia32_XorMem, bemit_xormem);
......
......@@ -165,7 +165,7 @@ static void peephole_ia32_Cmp(ir_node *const node)
if (is_ia32_Cmp(node)) {
test = new_bd_ia32_Test(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted);
} else {
test = new_bd_ia32_Test8Bit(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted);
test = new_bd_ia32_Test_8bit(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted);
}
set_ia32_ls_mode(test, get_ia32_ls_mode(node));
......@@ -194,9 +194,6 @@ static void peephole_ia32_Test(ir_node *node)
ir_node *left = get_irn_n(node, n_ia32_Test_left);
ir_node *right = get_irn_n(node, n_ia32_Test_right);
assert((int)n_ia32_Test_left == (int)n_ia32_Test8Bit_left
&& (int)n_ia32_Test_right == (int)n_ia32_Test8Bit_right);
if (left == right) { /* we need a test for 0 */
ir_node *block = get_nodes_block(node);
int pn = pn_ia32_res;
......@@ -1261,11 +1258,10 @@ void ia32_peephole_optimization(ir_graph *irg)
/* pass 2 */
ir_clear_opcodes_generic_func();
register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test);
register_peephole_optimisation(op_ia32_Test8Bit, peephole_ia32_Test);
register_peephole_optimisation(op_be_Return, peephole_ia32_Return);
register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test);
register_peephole_optimisation(op_be_Return, peephole_ia32_Return);
be_peephole_opt(irg);
}
......
......@@ -147,6 +147,17 @@ $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
"FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
my %binop_flags_constructors = (
"" => {
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
out => [ "flags", "none", "none" ] },
},
"8bit" => {
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ],
out => [ "flags", "none", "none" ] },
}
);
%nodes = (
Immediate => {
......@@ -822,8 +833,7 @@ XorHighLow => {
Test => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
out => [ "flags", "none", "none" ] },
constructors => \%binop_flags_constructors,
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "eflags", "unused", "M" ],
am => "source,binary",
......@@ -835,22 +845,6 @@ Test => {
modified_flags => $status_flags
},
Test8Bit => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
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", "unused", "M" ],
am => "source,binary",
emit => 'testb %B',
attr => "bool ins_permuted",
init_attr => "attr->data.ins_permuted = ins_permuted;",
latency => 1,
mode => $mode_flags,
modified_flags => $status_flags
},
Setcc => {
#irn_flags => [ "rematerializable" ],
reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
......
......@@ -3037,16 +3037,9 @@ static ir_node *gen_Cmp(ir_node *node)
cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
}
if (get_mode_size_bits(cmp_mode) == 8) {
new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
addr->index, addr->mem,
am.new_op1, am.new_op2,
am.ins_permuted);
} else {
new_node = new_bd_ia32_Test(dbgi, new_block, addr->base,
addr->index, addr->mem, am.new_op1,
am.new_op2, am.ins_permuted);
}
new_node = get_mode_size_bits(cmp_mode) == 8
? new_bd_ia32_Test_8bit(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted)
: new_bd_ia32_Test (dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
} else {
/* Cmp(left, right) */
match_arguments(&am, block, left, right, NULL,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment