Commit ea20f330 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

amd64: Split AMD64_OP_ADDR_REG into AMD64_OP_ADDR_REG(sic) and AMD64_OP_REG_ADDR.

Now we can distinguish from reg to mem (AMD64_OP_ADDR_REG) and from mem to reg (AMD64_OP_REG_ADDR) operations.
parent 4fd88f77
......@@ -326,7 +326,7 @@ static void amd64_emit_am(const ir_node *const node, bool indirect_star)
emit_register_mode(reg0, addr_attr->insn_mode);
return;
}
case AMD64_OP_ADDR_REG: {
case AMD64_OP_REG_ADDR: {
const amd64_binop_addr_attr_t *const binop_attr
= (const amd64_binop_addr_attr_t*)attr;
amd64_emit_addr(node, &attr->addr);
......@@ -341,6 +341,14 @@ static void amd64_emit_am(const ir_node *const node, bool indirect_star)
case AMD64_OP_ADDR:
amd64_emit_addr(node, &attr->addr);
return;
case AMD64_OP_ADDR_REG: {
amd64_binop_addr_attr_t const *const binop_attr = (amd64_binop_addr_attr_t const*)attr;
arch_register_t const *const reg = arch_get_irn_register_in(node, binop_attr->u.reg_input);
emit_register_mode(reg, binop_attr->base.insn_mode);
be_emit_cstring(", ");
amd64_emit_addr(node, &attr->addr);
return;
}
case AMD64_OP_UNOP_REG:
if (indirect_star)
be_emit_char('*');
......
......@@ -98,7 +98,7 @@ static void transform_sub_to_neg_add(ir_node *node,
amd64_binop_addr_attr_t xor_attr;
memset(&xor_attr, 0, sizeof(xor_attr));
xor_attr.base.insn_mode = INSN_MODE_64;
xor_attr.base.base.op_mode = AMD64_OP_ADDR_REG;
xor_attr.base.base.op_mode = AMD64_OP_REG_ADDR;
xor_attr.base.addr.base_input = NO_INPUT;
xor_attr.base.addr.index_input = NO_INPUT;
xor_attr.base.addr.immediate.entity = sign_bit_const;
......@@ -234,7 +234,7 @@ swap:;
}
panic("couldn't swap inputs of %+F", node);
} else {
assert(attr->op_mode == AMD64_OP_ADDR_REG);
assert(attr->op_mode == AMD64_OP_REG_ADDR);
/* extract load into an own instruction */
ir_node *res = amd64_turn_back_am(node);
arch_set_irn_register(res, out_reg);
......
......@@ -40,6 +40,7 @@ static const char *get_op_mode_string(amd64_op_mode_t mode)
case AMD64_OP_NONE: return "none";
case AMD64_OP_RAX_ADDR: return "rax_addr";
case AMD64_OP_RAX_REG: return "rax_reg";
case AMD64_OP_REG_ADDR: return "reg+addr";
case AMD64_OP_REG_IMM: return "reg+imm";
case AMD64_OP_REG_REG: return "reg+reg";
case AMD64_OP_REG: return "reg";
......@@ -88,16 +89,24 @@ static void amd64_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
case dump_node_info_txt:
be_dump_reqs_and_registers(F, n);
const amd64_attr_t *attr = get_amd64_attr_const(n);
fprintf(F, "mode = %s\n", get_op_mode_string(attr->op_mode));
amd64_op_mode_t op_mode = attr->op_mode;
if (op_mode == AMD64_OP_ADDR_REG) {
amd64_op_mode_t const op_mode = attr->op_mode;
fprintf(F, "mode = %s\n", get_op_mode_string(op_mode));
switch (op_mode) {
case AMD64_OP_ADDR_REG:
case AMD64_OP_REG_ADDR: {
const amd64_binop_addr_attr_t *binop_attr = get_amd64_binop_addr_attr_const(n);
fprintf(F, "reg input: %d\n", binop_attr->u.reg_input);
} else if (op_mode == AMD64_OP_IMM64) {
break;
}
case AMD64_OP_IMM64: {
const amd64_imm64_t *const imm
= &get_amd64_movimm_attr_const(n)->immediate;
ir_fprintf(F, "imm64 entity: %+F\n", imm->entity);
fprintf(F, "imm64 offset: 0x%" PRIX64 "\n", (uint64_t)imm->offset);
break;
}
default:
break;
}
if (amd64_has_addr_attr(n)) {
const amd64_addr_attr_t *addr_attr = get_amd64_addr_attr_const(n);
......
......@@ -30,6 +30,7 @@ static inline bool amd64_has_binop_attr(const ir_node *node)
const amd64_attr_t *attr = get_amd64_attr_const(node);
return attr->op_mode == AMD64_OP_REG_REG
|| attr->op_mode == AMD64_OP_REG_IMM
|| attr->op_mode == AMD64_OP_REG_ADDR
|| attr->op_mode == AMD64_OP_ADDR_REG
|| attr->op_mode == AMD64_OP_ADDR_IMM;
}
......
......@@ -44,6 +44,7 @@ typedef enum {
AMD64_OP_NONE,
AMD64_OP_ADDR,
AMD64_OP_REG,
AMD64_OP_REG_ADDR,
AMD64_OP_REG_REG,
AMD64_OP_REG_IMM,
AMD64_OP_IMM32,
......@@ -83,7 +84,7 @@ typedef struct {
typedef struct {
except_attr exc; /**< the exception attribute. MUST be the first one. */
ENUMBF(amd64_op_mode_t) op_mode : 4;
amd64_op_mode_t op_mode;
} amd64_attr_t;
typedef struct {
......
......@@ -714,7 +714,7 @@ static void match_binop(amd64_args_t *args, ir_node *block,
addr->mem_input = mem_input;
args->mem_proj = get_Proj_for_pn(load, pn_Load_M);
args->attr.base.base.op_mode = AMD64_OP_ADDR_REG;
args->attr.base.base.op_mode = AMD64_OP_REG_ADDR;
} else {
/* simply transform the arguments */
args->in[args->arity++] = be_transform_node(op1);
......@@ -854,7 +854,7 @@ static ir_node *gen_binop_xmm(ir_node *node, ir_node *op0, ir_node *op1,
addr->mem_input = mem_input;
args.mem_proj = get_Proj_for_pn(load, pn_Load_M);
args.attr.base.base.op_mode = AMD64_OP_ADDR_REG;
args.attr.base.base.op_mode = AMD64_OP_REG_ADDR;
} else {
args.in[args.arity++] = be_transform_node(op0);
args.in[args.arity++] = be_transform_node(op1);
......
Markdown is supported
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