Commit 4ac67b23 authored by Matthias Braun's avatar Matthias Braun
Browse files

amd64: Cleanup, base more decisions on op_mode

parent 5972dc5c
...@@ -394,6 +394,7 @@ emit_reg_in0:; ...@@ -394,6 +394,7 @@ emit_reg_in0:;
case AMD64_OP_NONE: case AMD64_OP_NONE:
case AMD64_OP_SHIFT_REG: case AMD64_OP_SHIFT_REG:
case AMD64_OP_SHIFT_IMM: case AMD64_OP_SHIFT_IMM:
case AMD64_OP_CC:
break; break;
} }
panic("invalid op_mode"); panic("invalid op_mode");
...@@ -559,7 +560,6 @@ end_of_mods: ...@@ -559,7 +560,6 @@ end_of_mods:
// Format string is backwards compatible to IA32 backend. // Format string is backwards compatible to IA32 backend.
// Fetch cc from node attributes // Fetch cc from node attributes
++fmt; ++fmt;
assert(amd64_has_cc_attr(node));
cc = get_amd64_cc_attr_const(node)->cc; cc = get_amd64_cc_attr_const(node)->cc;
} else { } else {
panic("unknown modifier"); panic("unknown modifier");
......
...@@ -34,10 +34,12 @@ amd64_insn_mode_t get_amd64_insn_mode(const ir_node *node) ...@@ -34,10 +34,12 @@ amd64_insn_mode_t get_amd64_insn_mode(const ir_node *node)
const amd64_movimm_attr_t *const attr const amd64_movimm_attr_t *const attr
= get_amd64_movimm_attr_const(node); = get_amd64_movimm_attr_const(node);
return attr->insn_mode; return attr->insn_mode;
} else if (amd64_has_addr_attr(node)) { }
amd64_op_mode_t const op_mode = get_amd64_attr_const(node)->op_mode;
if (amd64_has_addr_attr(op_mode)) {
amd64_addr_attr_t const *const attr = get_amd64_addr_attr_const(node); amd64_addr_attr_t const *const attr = get_amd64_addr_attr_const(node);
return attr->insn_mode; return attr->insn_mode;
} else if (amd64_has_cc_attr(node)) { } else if (op_mode == AMD64_OP_CC) {
amd64_cc_attr_t const *const attr = get_amd64_cc_attr_const(node); amd64_cc_attr_t const *const attr = get_amd64_cc_attr_const(node);
return attr->insn_mode; return attr->insn_mode;
} else { } else {
...@@ -78,9 +80,9 @@ int get_insn_mode_bits(amd64_insn_mode_t insn_mode) ...@@ -78,9 +80,9 @@ int get_insn_mode_bits(amd64_insn_mode_t insn_mode)
} }
} }
static const char *get_op_mode_string(amd64_op_mode_t mode) static const char *get_op_mode_string(amd64_op_mode_t const op_mode)
{ {
switch (mode) { switch (op_mode) {
case AMD64_OP_ADDR_IMM: return "addr+imm"; case AMD64_OP_ADDR_IMM: return "addr+imm";
case AMD64_OP_ADDR_REG: return "addr+reg"; case AMD64_OP_ADDR_REG: return "addr+reg";
case AMD64_OP_ADDR: return "addr"; case AMD64_OP_ADDR: return "addr";
...@@ -95,6 +97,7 @@ static const char *get_op_mode_string(amd64_op_mode_t mode) ...@@ -95,6 +97,7 @@ static const char *get_op_mode_string(amd64_op_mode_t mode)
case AMD64_OP_SHIFT_REG: return "shift_reg"; case AMD64_OP_SHIFT_REG: return "shift_reg";
case AMD64_OP_X87: return "x87"; case AMD64_OP_X87: return "x87";
case AMD64_OP_X87_ADDR_REG: return "x87+addr+reg"; case AMD64_OP_X87_ADDR_REG: return "x87+addr+reg";
case AMD64_OP_CC: return "cc";
} }
return "invalid op_mode"; return "invalid op_mode";
} }
...@@ -154,7 +157,7 @@ static void amd64_dump_node(FILE *F, const ir_node *n, dump_reason_t reason) ...@@ -154,7 +157,7 @@ static void amd64_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
default: default:
break; break;
} }
if (amd64_has_addr_attr(n)) { if (amd64_has_addr_attr(op_mode)) {
const amd64_addr_attr_t *addr_attr = get_amd64_addr_attr_const(n); const amd64_addr_attr_t *addr_attr = get_amd64_addr_attr_const(n);
fprintf(F, "size = %s\n", get_insn_mode_string(addr_attr->insn_mode)); fprintf(F, "size = %s\n", get_insn_mode_string(addr_attr->insn_mode));
x86_addr_variant_t const variant = addr_attr->addr.variant; x86_addr_variant_t const variant = addr_attr->addr.variant;
......
...@@ -25,69 +25,88 @@ static inline const amd64_attr_t *get_amd64_attr_const(const ir_node *node) ...@@ -25,69 +25,88 @@ static inline const amd64_attr_t *get_amd64_attr_const(const ir_node *node)
return (const amd64_attr_t*)get_irn_generic_attr_const(node); return (const amd64_attr_t*)get_irn_generic_attr_const(node);
} }
static inline bool amd64_has_binop_attr(const ir_node *node) static inline bool amd64_has_binop_attr(amd64_op_mode_t const op_mode)
{ {
const amd64_attr_t *attr = get_amd64_attr_const(node); switch (op_mode) {
return attr->op_mode == AMD64_OP_REG_REG case AMD64_OP_REG_REG:
|| attr->op_mode == AMD64_OP_REG_IMM case AMD64_OP_REG_IMM:
|| attr->op_mode == AMD64_OP_REG_ADDR case AMD64_OP_REG_ADDR:
|| attr->op_mode == AMD64_OP_ADDR_REG case AMD64_OP_ADDR_REG:
|| attr->op_mode == AMD64_OP_ADDR_IMM case AMD64_OP_ADDR_IMM:
|| attr->op_mode == AMD64_OP_X87_ADDR_REG; case AMD64_OP_X87_ADDR_REG:
} return true;
default:
static inline bool amd64_has_addr_attr(const ir_node *node) return false;
{ }
const amd64_attr_t *attr = get_amd64_attr_const(node); }
return amd64_has_binop_attr(node)
|| attr->op_mode == AMD64_OP_ADDR static inline bool amd64_has_addr_attr(amd64_op_mode_t const op_mode)
|| attr->op_mode == AMD64_OP_REG {
|| attr->op_mode == AMD64_OP_IMM32; switch (op_mode) {
case AMD64_OP_ADDR:
case AMD64_OP_REG:
case AMD64_OP_IMM32:
return true;
default:
return amd64_has_binop_attr(op_mode);
}
}
static inline bool amd64_loads(const ir_node *node)
{
amd64_op_mode_t op_mode = get_amd64_attr_const(node)->op_mode;
switch (op_mode) {
case AMD64_OP_ADDR:
return !is_amd64_lea(node);
case AMD64_OP_REG_ADDR:
return true;
/* Note: AMD64_OP_ADDR_REG, AMD64_OP_X87_ADDR_REG are stores */
default:
return false;
}
} }
static inline amd64_addr_attr_t *get_amd64_addr_attr(ir_node *node) static inline amd64_addr_attr_t *get_amd64_addr_attr(ir_node *node)
{ {
assert(amd64_has_addr_attr(node)); assert(amd64_has_addr_attr(get_amd64_attr_const(node)->op_mode));
return (amd64_addr_attr_t*)get_irn_generic_attr(node); return (amd64_addr_attr_t*)get_irn_generic_attr(node);
} }
static inline const amd64_addr_attr_t *get_amd64_addr_attr_const( static inline const amd64_addr_attr_t *get_amd64_addr_attr_const(
const ir_node *node) const ir_node *node)
{ {
assert(amd64_has_addr_attr(node)); assert(amd64_has_addr_attr(get_amd64_attr_const(node)->op_mode));
return (const amd64_addr_attr_t*)get_irn_generic_attr_const(node); return (const amd64_addr_attr_t*)get_irn_generic_attr_const(node);
} }
static inline amd64_binop_addr_attr_t *get_amd64_binop_addr_attr(ir_node *node) static inline amd64_binop_addr_attr_t *get_amd64_binop_addr_attr(ir_node *node)
{ {
assert(amd64_has_binop_attr(node)); assert(amd64_has_binop_attr(get_amd64_attr_const(node)->op_mode));
return (amd64_binop_addr_attr_t*)get_irn_generic_attr(node); return (amd64_binop_addr_attr_t*)get_irn_generic_attr(node);
} }
static inline const amd64_binop_addr_attr_t *get_amd64_binop_addr_attr_const( static inline const amd64_binop_addr_attr_t *get_amd64_binop_addr_attr_const(
const ir_node *node) const ir_node *node)
{ {
assert(amd64_has_binop_attr(node)); assert(amd64_has_binop_attr(get_amd64_attr_const(node)->op_mode));
return (const amd64_binop_addr_attr_t*)get_irn_generic_attr_const(node); return (const amd64_binop_addr_attr_t*)get_irn_generic_attr_const(node);
} }
static inline bool amd64_has_shift_attr(const ir_node *node) static inline bool amd64_has_shift_attr(amd64_op_mode_t const op_mode)
{ {
const amd64_attr_t *attr = get_amd64_attr_const(node); return op_mode == AMD64_OP_SHIFT_REG || op_mode == AMD64_OP_SHIFT_IMM;
return attr->op_mode == AMD64_OP_SHIFT_REG
|| attr->op_mode == AMD64_OP_SHIFT_IMM;
} }
static inline const amd64_shift_attr_t *get_amd64_shift_attr_const( static inline const amd64_shift_attr_t *get_amd64_shift_attr_const(
const ir_node *node) const ir_node *node)
{ {
assert(amd64_has_shift_attr(node)); assert(amd64_has_shift_attr(get_amd64_attr_const(node)->op_mode));
return (const amd64_shift_attr_t*)get_irn_generic_attr_const(node); return (const amd64_shift_attr_t*)get_irn_generic_attr_const(node);
} }
static inline amd64_shift_attr_t *get_amd64_shift_attr(ir_node *node) static inline amd64_shift_attr_t *get_amd64_shift_attr(ir_node *node)
{ {
assert(amd64_has_shift_attr(node)); assert(amd64_has_shift_attr(get_amd64_attr_const(node)->op_mode));
return (amd64_shift_attr_t*)get_irn_generic_attr(node); return (amd64_shift_attr_t*)get_irn_generic_attr(node);
} }
...@@ -104,21 +123,16 @@ static inline amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr(ir_node *node) ...@@ -104,21 +123,16 @@ static inline amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr(ir_node *node)
return (amd64_switch_jmp_attr_t*)get_irn_generic_attr(node); return (amd64_switch_jmp_attr_t*)get_irn_generic_attr(node);
} }
static inline bool amd64_has_cc_attr(const ir_node *node)
{
return is_amd64_jcc(node) || is_amd64_setcc(node);
}
static inline const amd64_cc_attr_t *get_amd64_cc_attr_const( static inline const amd64_cc_attr_t *get_amd64_cc_attr_const(
const ir_node *node) const ir_node *node)
{ {
assert(amd64_has_cc_attr(node)); assert(get_amd64_attr_const(node)->op_mode == AMD64_OP_CC);
return (const amd64_cc_attr_t*)get_irn_generic_attr_const(node); return (const amd64_cc_attr_t*)get_irn_generic_attr_const(node);
} }
static inline amd64_cc_attr_t *get_amd64_cc_attr(ir_node *node) static inline amd64_cc_attr_t *get_amd64_cc_attr(ir_node *node)
{ {
assert(amd64_has_cc_attr(node)); assert(get_amd64_attr_const(node)->op_mode == AMD64_OP_CC);
return (amd64_cc_attr_t*)get_irn_generic_attr(node); return (amd64_cc_attr_t*)get_irn_generic_attr(node);
} }
......
...@@ -59,6 +59,7 @@ typedef enum { ...@@ -59,6 +59,7 @@ typedef enum {
AMD64_OP_SHIFT_IMM, AMD64_OP_SHIFT_IMM,
AMD64_OP_X87, AMD64_OP_X87,
AMD64_OP_X87_ADDR_REG, AMD64_OP_X87_ADDR_REG,
AMD64_OP_CC,
} amd64_op_mode_t; } amd64_op_mode_t;
typedef struct { typedef struct {
......
...@@ -81,7 +81,7 @@ $mode_x87 = "x86_mode_E"; ...@@ -81,7 +81,7 @@ $mode_x87 = "x86_mode_E";
."\tattr->base.addr = *addr;\n" ."\tattr->base.addr = *addr;\n"
."\tinit_amd64_switch_attributes(res, table, table_entity);", ."\tinit_amd64_switch_attributes(res, table, table_entity);",
amd64_cc_attr_t => amd64_cc_attr_t =>
"init_amd64_attributes(res, irn_flags, in_reqs, n_res, AMD64_OP_NONE);\n" "init_amd64_attributes(res, irn_flags, in_reqs, n_res, AMD64_OP_CC);\n"
."\tinit_amd64_cc_attributes(res, cc, insn_mode);", ."\tinit_amd64_cc_attributes(res, cc, insn_mode);",
amd64_movimm_attr_t => amd64_movimm_attr_t =>
"init_amd64_attributes(res, irn_flags, in_reqs, n_res, AMD64_OP_IMM64);\n" "init_amd64_attributes(res, irn_flags, in_reqs, n_res, AMD64_OP_IMM64);\n"
......
...@@ -48,7 +48,7 @@ static ir_entity *amd64_get_frame_entity(const ir_node *node) ...@@ -48,7 +48,7 @@ static ir_entity *amd64_get_frame_entity(const ir_node *node)
{ {
if (!is_amd64_irn(node)) if (!is_amd64_irn(node))
return NULL; return NULL;
if (!amd64_has_addr_attr(node)) if (!amd64_has_addr_attr(get_amd64_attr_const(node)->op_mode))
return NULL; return NULL;
const amd64_addr_attr_t *attr = get_amd64_addr_attr_const(node); const amd64_addr_attr_t *attr = get_amd64_addr_attr_const(node);
if (attr->addr.immediate.kind != X86_IMM_FRAMEOFFSET) if (attr->addr.immediate.kind != X86_IMM_FRAMEOFFSET)
...@@ -449,23 +449,18 @@ static void amd64_set_frame_entity(ir_node *node, ir_entity *entity, ...@@ -449,23 +449,18 @@ static void amd64_set_frame_entity(ir_node *node, ir_entity *entity,
attr->addr.immediate.entity = entity; attr->addr.immediate.entity = entity;
} }
static bool is_frame_load(const ir_node *node)
{
return is_amd64_mov_gp(node) || is_amd64_movs(node)
|| is_amd64_movs_xmm(node) || is_amd64_movdqu(node)
|| is_amd64_fld(node);
}
/** /**
* Collects nodes that need frame entities assigned. * Collects nodes that need frame entities assigned.
*/ */
static void amd64_collect_frame_entity_nodes(ir_node *node, void *data) static void amd64_collect_frame_entity_nodes(ir_node *node, void *data)
{ {
be_fec_env_t *env = (be_fec_env_t*)data; if (!is_amd64_irn(node))
return;
/* Disable coalescing for "returns twice" calls: In case of setjmp/longjmp /* Disable coalescing for "returns twice" calls: In case of setjmp/longjmp
* our control flow graph isn't completely correct: There are no backedges * our control flow graph isn't completely correct: There are no backedges
* from longjmp to the setjmp => coalescing would produce wrong results. */ * from longjmp to the setjmp => coalescing would produce wrong results. */
be_fec_env_t *const env = (be_fec_env_t*)data;
if (is_amd64_call(node)) { if (is_amd64_call(node)) {
const amd64_call_addr_attr_t *attrs = get_amd64_call_addr_attr_const(node); const amd64_call_addr_attr_t *attrs = get_amd64_call_addr_attr_const(node);
const ir_type *type = attrs->call_tp; const ir_type *type = attrs->call_tp;
...@@ -476,7 +471,7 @@ static void amd64_collect_frame_entity_nodes(ir_node *node, void *data) ...@@ -476,7 +471,7 @@ static void amd64_collect_frame_entity_nodes(ir_node *node, void *data)
} }
/* we are only interested to report Load nodes */ /* we are only interested to report Load nodes */
if (!is_frame_load(node)) if (!amd64_loads(node))
return; return;
const amd64_addr_attr_t *attr = get_amd64_addr_attr_const(node); const amd64_addr_attr_t *attr = get_amd64_addr_attr_const(node);
......
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