BINOP(and, 4)
BINOP(sub, 5)
BINOP(xor, 6)
+BINOP(cmp, 7)
#define BINOPMEM(op, ext) \
static void bemit_##op(const ir_node *node) \
}
}
-static void bemit_cmp(const ir_node *node)
-{
- unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
- ir_node *right;
-
- if (ls_size == 16)
- bemit8(0x66);
-
- right = get_irn_n(node, n_ia32_binary_right);
- if (is_ia32_Immediate(right)) {
- /* 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;
-
- if (attr->symconst != NULL) {
- size = 4;
- } else {
- /* check for sign extension */
- size = get_signed_imm_size(attr->offset);
- }
-
- switch (size) {
- case 1:
- bemit8(0x80 | OP_16_32_IMM8);
- /* cmp has this special mode */
- if (get_ia32_op_type(node) == ia32_Normal) {
- const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
- bemit_modru(reg, 7);
- } else {
- bemit_mod_am(7, node);
- }
- bemit8((unsigned char)attr->offset);
- return;
- case 2:
- case 4:
- /* check for eax variant: this variant is shorter for 32bit immediates only */
- if (get_ia32_op_type(node) == ia32_Normal) {
- const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
- if (reg->index == REG_GP_EAX) {
- bemit8(0x3D);
- } else {
- bemit8(0x81);
- bemit_modru(reg, 7);
- }
- } else {
- bemit8(0x81);
- bemit_mod_am(7, node);
- }
- if (ls_size == 16) {
- bemit16(attr->offset);
- } else {
- bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
- }
- return;
- }
- panic("invalid imm size?!?");
- } else {
- const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
- bemit8(0x3B);
- if (get_ia32_op_type(node) == ia32_Normal) {
- const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
- bemit_modrr(op2, out);
- } else {
- bemit_mod_am(reg_gp_map[out->index], node);
- }
- }
-}
-
-static void bemit_cmp8bit(const ir_node *node)
-{
- ir_node *right = get_irn_n(node, n_ia32_binary_right);
- if (is_ia32_Immediate(right)) {
- if (get_ia32_op_type(node) == ia32_Normal) {
- const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
- if (out->index == REG_GP_EAX) {
- bemit8(0x3C);
- } else {
- bemit8(0x80);
- bemit_modru(out, 7);
- }
- } else {
- bemit8(0x80);
- bemit_mod_am(7, node);
- }
- bemit8(get_ia32_immediate_attr_const(right)->offset);
- } else {
- const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
- bemit8(0x3A);
- if (get_ia32_op_type(node) == ia32_Normal) {
- const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
- bemit_modrr(out, in);
- } else {
- bemit_mod_am(reg_gp_map[out->index], node);
- }
- }
-}
-
static void bemit_test(ir_node const *const node)
{
unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
be_set_emitter(op_ia32_Cltd, bemit_cltd);
be_set_emitter(op_ia32_Cmc, bemit_cmc);
be_set_emitter(op_ia32_Cmp, bemit_cmp);
- be_set_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
be_set_emitter(op_ia32_Const, bemit_mov_const);
be_set_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
be_set_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
ir_node *const op = get_irn_n(node, n_ia32_Cmp_left);
int const ins_permuted = get_ia32_attr(node)->data.ins_permuted;
- ir_node *test;
- if (is_ia32_Cmp(node)) {
- test = new_bd_ia32_Test(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted);
- } else {
- 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));
+ ir_mode *const ls_mode = get_ia32_ls_mode(node);
+ ir_node *const test = get_mode_size_bits(ls_mode) == 8
+ ? new_bd_ia32_Test_8bit(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted)
+ : new_bd_ia32_Test (dbgi, block, noreg, noreg, nomem, op, op, ins_permuted);
+ set_ia32_ls_mode(test, ls_mode);
arch_register_t const *const reg = arch_get_irn_register_out(node, pn_ia32_Cmp_eflags);
arch_set_irn_register_out(test, pn_ia32_Test_eflags, reg);
/* pass 1 */
ir_clear_opcodes_generic_func();
register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp);
- register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp);
register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea);
if (ia32_cg_config.use_short_sex_eax)
register_peephole_optimisation(op_ia32_Conv_I2I, peephole_ia32_Conv_I2I);
Cmp => {
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",
modified_flags => $status_flags
},
-Cmp8Bit => {
- 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 => 'cmpb %B',
- attr => "bool ins_permuted",
- init_attr => "attr->data.ins_permuted = ins_permuted;",
- latency => 1,
- mode => $mode_flags,
- modified_flags => $status_flags
-},
-
XorHighLow => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
}
- if (get_mode_size_bits(cmp_mode) == 8) {
- new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
- addr->index, addr->mem, am.new_op1,
- am.new_op2, am.ins_permuted);
- } else {
- new_node = new_bd_ia32_Cmp(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_Cmp_8bit(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted)
+ : new_bd_ia32_Cmp (dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
}
set_am_attributes(new_node, &am);
set_ia32_ls_mode(new_node, cmp_mode);