Commit e37bf8de authored by Michael Beck's avatar Michael Beck
Browse files

Refactored attributes:

 - remove pn_code from general ones
 - add attribute types for condcode and copyb
 - more more attributes into constructors

[r16250]
parent 6e70214f
......@@ -633,7 +633,7 @@ static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
cost += 150;
}
else if (is_ia32_CopyB_i(irn)) {
int size = get_ia32_pncode(irn);
int size = get_ia32_copyb_size(irn);
cost = 20 + (int)ceil((4/3) * size);
if (ARCH_INTEL(ops->cg->arch))
cost += 150;
......
......@@ -723,7 +723,7 @@ void ia32_emit_cmp_suffix_node(const ir_node *node,
{
const ia32_attr_t *attr = get_ia32_attr_const(node);
pn_Cmp pnc = get_ia32_pncode(node);
pn_Cmp pnc = get_ia32_condcode(node);
pnc = determine_final_pnc(node, flags_pos, pnc);
if(attr->data.ins_permuted) {
......@@ -807,7 +807,7 @@ static void emit_ia32_Jcc(const ir_node *node)
const ir_node *proj_false;
const ir_node *block;
const ir_node *next_block;
pn_Cmp pnc = get_ia32_pncode(node);
pn_Cmp pnc = get_ia32_condcode(node);
pnc = determine_final_pnc(node, 0, pnc);
......@@ -896,7 +896,7 @@ static void emit_ia32_CMov(const ir_node *node)
const ia32_attr_t *attr = get_ia32_attr_const(node);
int ins_permuted = attr->data.ins_permuted;
const arch_register_t *out = arch_get_irn_register(arch_env, node);
pn_Cmp pnc = get_ia32_pncode(node);
pn_Cmp pnc = get_ia32_condcode(node);
const arch_register_t *in_true;
const arch_register_t *in_false;
......@@ -1032,7 +1032,7 @@ void emit_ia32_SwitchJmp(const ir_node *node) {
tbl.max_value = pnc > tbl.max_value ? pnc : tbl.max_value;
/* check for default proj */
if (pnc == get_ia32_pncode(node)) {
if (pnc == get_ia32_condcode(node)) {
assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
tbl.defProj = proj;
}
......@@ -1133,7 +1133,7 @@ static void emit_ia32_Immediate(const ir_node *node)
if(attr->symconst != NULL) {
ident *id = get_entity_ld_ident(attr->symconst);
if(attr->attr.data.am_sc_sign)
if(attr->sc_sign)
be_emit_char('-');
be_emit_ident(id);
}
......@@ -1321,11 +1321,11 @@ static void emit_ia32_Asm(const ir_node *node)
/**
* Emit movsb/w instructions to make mov count divideable by 4
*/
static void emit_CopyB_prolog(int rem) {
static void emit_CopyB_prolog(unsigned size) {
be_emit_cstring("\tcld");
be_emit_finish_line_gas(NULL);
switch(rem) {
switch (size) {
case 1:
be_emit_cstring("\tmovsb");
be_emit_finish_line_gas(NULL);
......@@ -1348,9 +1348,9 @@ static void emit_CopyB_prolog(int rem) {
*/
static void emit_ia32_CopyB(const ir_node *node)
{
int rem = get_ia32_pncode(node);
unsigned size = get_ia32_copyb_size(node);
emit_CopyB_prolog(rem);
emit_CopyB_prolog(size);
be_emit_cstring("\trep movsd");
be_emit_finish_line_gas(node);
......@@ -1361,7 +1361,7 @@ static void emit_ia32_CopyB(const ir_node *node)
*/
static void emit_ia32_CopyB_i(const ir_node *node)
{
int size = get_ia32_pncode(node);
unsigned size = get_ia32_copyb_size(node);
emit_CopyB_prolog(size & 0x3);
......
......@@ -139,7 +139,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
fputc(' ', F);
if(attr->symconst) {
if(attr->attr.data.am_sc_sign) {
if(attr->sc_sign) {
fputc('-', F);
}
fputs(get_entity_name(attr->symconst), F);
......@@ -151,8 +151,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
fprintf(F, "%ld", attr->offset);
}
}
{
else {
const ia32_attr_t *attr = get_ia32_attr_const(n);
if(attr->am_sc != NULL || attr->am_offs != 0)
......@@ -278,11 +277,14 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
fprintf(F, "AM scale = %d\n", get_ia32_am_scale(n));
/* dump pn code */
if(is_ia32_SwitchJmp(n) || is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
fprintf(F, "pn_code = %ld\n", get_ia32_pncode(n));
} else {
fprintf(F, "pn_code = %ld (%s)\n", get_ia32_pncode(n),
get_pnc_string(get_ia32_pncode(n)));
if (is_ia32_SwitchJmp(n)) {
fprintf(F, "pn_code = %ld\n", get_ia32_condcode(n));
} else if (is_ia32_CMov(n) || is_ia32_Set(n) || is_ia32_Jcc(n)) {
pn_Cmp pnc = get_ia32_condcode(n);
fprintf(F, "pn_code = %ld (%s)\n", pnc, get_pnc_string(pnc));
}
else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
fprintf(F, "size = %ld\n", get_ia32_copyb_size(n));
}
/* dump n_res */
......@@ -406,11 +408,43 @@ const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node) {
const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
{
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_immediate_attr_t *immediate_attr
= CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
return immediate_attr;
assert(is_ia32_Immediate(node) || is_ia32_Const(node));
return imm_attr;
}
ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
assert(is_ia32_SwitchJmp(node) || is_ia32_CMov(node) || is_ia32_Set(node) || is_ia32_Jcc(node));
return cc_attr;
}
const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node) {
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
assert(is_ia32_SwitchJmp(node) || is_ia32_CMov(node) || is_ia32_Set(node) || is_ia32_Jcc(node));
return cc_attr;
}
ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
assert(is_ia32_CopyB(node) || is_ia32_CopyB_i(node));
return copyb_attr;
}
const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node) {
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
assert(is_ia32_CopyB(node) || is_ia32_CopyB_i(node));
return copyb_attr;
}
/**
......@@ -765,21 +799,30 @@ int get_ia32_n_res(const ir_node *node) {
}
/**
* Returns the projnum code.
* Returns the condition code of a node.
*/
long get_ia32_pncode(const ir_node *node)
long get_ia32_condcode(const ir_node *node)
{
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
return attr->pn_code;
}
/**
* Sets the projnum code
* Sets the condition code of a node
*/
void set_ia32_pncode(ir_node *node, long code)
void set_ia32_condcode(ir_node *node, long code)
{
ia32_attr_t *attr = get_ia32_attr(node);
attr->pn_code = code;
ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
attr->pn_code = code;
}
/**
* Returns the condition code of a node.
*/
unsigned get_ia32_copyb_size(const ir_node *node)
{
const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
return attr->size;
}
/**
......@@ -1004,11 +1047,31 @@ init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
ia32_immediate_attr_t *attr = get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
#endif
attr->symconst = symconst;
attr->sc_sign = symconst_sign;
attr->offset = offset;
}
void
init_ia32_copyb_attributes(ir_node *res, unsigned size) {
ia32_copyb_attr_t *attr = get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t;
#endif
attr->symconst = symconst;
attr->attr.data.am_sc_sign = symconst_sign;
attr->offset = offset;
attr->size = size;
}
void
init_ia32_condcode_attributes(ir_node *res, long pnc) {
ia32_condcode_attr_t *attr = get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t;
#endif
attr->pn_code = pnc;
}
ir_node *get_ia32_result_proj(const ir_node *node)
......@@ -1057,9 +1120,6 @@ int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b) {
|| a->frame_ent != b->frame_ent)
return 1;
if(a->pn_code != b->pn_code)
return 1;
if (a->data.tp != b->data.tp)
return 1;
......@@ -1073,6 +1133,7 @@ int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b) {
return 0;
}
/** Compare nodes attributes for all "normal" nodes. */
static
int ia32_compare_nodes_attr(ir_node *a, ir_node *b)
{
......@@ -1082,12 +1143,46 @@ int ia32_compare_nodes_attr(ir_node *a, ir_node *b)
return ia32_compare_attr(attr_a, attr_b);
}
/** Compare node attributes for nodes with condition code. */
static
int ia32_compare_x87_attr(ir_node *a, ir_node *b)
int ia32_compare_condcode_attr(ir_node *a, ir_node *b)
{
return ia32_compare_nodes_attr(a, b);
const ia32_condcode_attr_t *attr_a;
const ia32_condcode_attr_t *attr_b;
if (ia32_compare_nodes_attr(a, b))
return 1;
attr_a = get_ia32_condcode_attr_const(a);
attr_b = get_ia32_condcode_attr_const(b);
if(attr_a->pn_code != attr_b->pn_code)
return 1;
return 0;
}
/** Compare node attributes for CopyB nodes. */
static
int ia32_compare_copyb_attr(ir_node *a, ir_node *b)
{
const ia32_copyb_attr_t *attr_a;
const ia32_copyb_attr_t *attr_b;
if (ia32_compare_nodes_attr(a, b))
return 1;
attr_a = get_ia32_copyb_attr_const(a);
attr_b = get_ia32_copyb_attr_const(b);
if(attr_a->size != attr_b->size)
return 1;
return 0;
}
/** Compare ASM node attributes. */
static
int ia32_compare_asm_attr(ir_node *a, ir_node *b)
{
......@@ -1106,6 +1201,7 @@ int ia32_compare_asm_attr(ir_node *a, ir_node *b)
return 0;
}
/** Compare node attributes for Immediates. */
static
int ia32_compare_immediate_attr(ir_node *a, ir_node *b)
{
......@@ -1113,13 +1209,21 @@ int ia32_compare_immediate_attr(ir_node *a, ir_node *b)
const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
if(attr_a->symconst != attr_b->symconst ||
attr_a->attr.data.am_sc_sign != attr_b->attr.data.am_sc_sign ||
attr_a->sc_sign != attr_b->sc_sign ||
attr_a->offset != attr_b->offset)
return 1;
return 0;
}
/** Compare node attributes for x87 nodes. */
static
int ia32_compare_x87_attr(ir_node *a, ir_node *b)
{
return ia32_compare_nodes_attr(a, b);
}
/* copies the ia32 attributes */
static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node)
{
......
......@@ -77,6 +77,18 @@ const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node);
const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node);
/**
* Gets the condcode attributes of a node.
*/
ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node);
const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node);
/**
* Gets the CopyB node attributes.
*/
ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node);
const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node);
/**
* Gets the type of an ia32 node.
*/
......@@ -293,14 +305,19 @@ const arch_register_t *get_ia32_out_reg(const ir_node *node, int pos);
int get_ia32_n_res(const ir_node *node);
/**
* Returns the projnum code.
* Returns the condition code of a node.
*/
long get_ia32_condcode(const ir_node *node);
/**
* Sets the condition code of a node
*/
long get_ia32_pncode(const ir_node *node);
void set_ia32_condcode(ir_node *node, long code);
/**
* Sets the projnum code
* Returns the condition code of a node.
*/
void set_ia32_pncode(ir_node *node, long code);
unsigned get_ia32_copyb_size(const ir_node *node);
/**
* Gets the instruction latency.
......@@ -421,6 +438,8 @@ void init_ia32_x87_attributes(ir_node *node);
void init_ia32_asm_attributes(ir_node *node);
void init_ia32_immediate_attributes(ir_node *node, ir_entity *symconst,
int symconst_sign, long offset);
void init_ia32_copyb_attributes(ir_node *res, unsigned size);
void init_ia32_condcode_attributes(ir_node *res, long pnc);
/* Include the generated headers */
#include "gen_ia32_new_nodes.h"
......
......@@ -74,9 +74,14 @@ typedef enum {
IA32_ATTR_ia32_x87_attr_t = 1 << 1,
IA32_ATTR_ia32_asm_attr_t = 1 << 2,
IA32_ATTR_ia32_immediate_attr_t = 1 << 3,
IA32_ATTR_ia32_condcode_attr_t = 1 << 4,
IA32_ATTR_ia32_copyb_attr_t = 1 << 5
} ia32_attr_type_t;
#endif
/**
* The generic ia32 attributes. Every node has them.
*/
typedef struct ia32_attr_t ia32_attr_t;
struct ia32_attr_t {
except_attr exc; /**< the exception attribute. MUST be the first one. */
......@@ -111,34 +116,57 @@ struct ia32_attr_t {
ir_entity *frame_ent; /**< the frame entity attached to this node */
long pn_code; /**< projnum "types" (e.g. indicate compare operators and argument numbers for switches) */
unsigned latency; /**< the latency of the instruction in clock cycles */
#ifndef NDEBUG
const char *orig_node; /**< holds the name of the original ir node */
unsigned attr_type; /**< bitfield indicating the attribute type */
#endif
const be_execution_unit_t ***exec_units; /**< list of units this operation can be executed on */
const arch_register_req_t **in_req; /**< register requirements for arguments */
const arch_register_req_t **out_req; /**< register requirements for results */
const arch_register_t **slots; /**< register slots for assigned registers */
#ifndef NDEBUG
const char *orig_node; /**< holds the name of the original ir node */
unsigned attr_type; /**< bitfield indicating the attribute type */
#endif
};
COMPILETIME_ASSERT(sizeof(struct ia32_attr_data_bitfield) <= 4, attr_bitfield);
/**
* The attributes for nodes with condition code.
*/
typedef struct ia32_condcode_attr_t ia32_condcode_attr_t;
struct ia32_condcode_attr_t {
ia32_attr_t attr; /**< generic attribute */
long pn_code; /**< projnum "types" (e.g. indicate compare operators */
};
/**
* The attributes for CopyB code.
*/
typedef struct ia32_copyb_attr_t ia32_copyb_attr_t;
struct ia32_copyb_attr_t {
ia32_attr_t attr; /**< generic attribute */
unsigned size; /**< size of copied block */
};
/**
* The attributes for immediates.
*/
typedef struct ia32_immediate_attr_t ia32_immediate_attr_t;
struct ia32_immediate_attr_t {
ia32_attr_t attr;
ir_entity *symconst;
long offset;
ia32_attr_t attr; /**< generic attribute */
ir_entity *symconst; /**< An entity if any. */
long offset; /**< An offset if any. */
unsigned sc_sign:1; /**< The sign bit of the symconst. */
};
/**
* The attributes for x87 nodes.
*/
typedef struct ia32_x87_attr_t ia32_x87_attr_t;
struct ia32_x87_attr_t {
ia32_attr_t attr;
ia32_attr_t attr; /**< the generic attribute */
const arch_register_t *x87[3]; /**< register slots for x87 register */
};
......@@ -153,6 +181,9 @@ struct ia32_asm_reg_t {
const ir_mode *mode;
};
/**
* The attributes for ASM nodes.
*/
typedef struct ia32_asm_attr_t ia32_asm_attr_t;
struct ia32_asm_attr_t {
ia32_x87_attr_t x87_attr;
......@@ -164,6 +195,8 @@ struct ia32_asm_attr_t {
* the structs (we use them to simulate OO-inheritance) */
union allow_casts_attr_t_ {
ia32_attr_t attr;
ia32_condcode_attr_t cc_attr;
ia32_copyb_attr_t cpy_attr;
ia32_x87_attr_t x87_attr;
ia32_asm_attr_t asm_attr;
ia32_immediate_attr_t immediate_attr;
......
......@@ -289,7 +289,13 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
"\tinit_ia32_asm_attributes(res);",
ia32_immediate_attr_t =>
"\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
"\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);"
"\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);",
ia32_copyb_attr_t =>
"\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
"\tinit_ia32_copyb_attributes(res, size);",
ia32_condcode_attr_t =>
"\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
"\tinit_ia32_condcode_attributes(res, pnc);",
);
%compare_attr = (
......@@ -297,6 +303,8 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
ia32_x87_attr_t => "ia32_compare_x87_attr",
ia32_asm_attr_t => "ia32_compare_asm_attr",
ia32_immediate_attr_t => "ia32_compare_immediate_attr",
ia32_copyb_attr_t => "ia32_compare_copyb_attr",
ia32_condcode_attr_t => "ia32_compare_condcode_attr",
);
%operands = (
......@@ -1000,9 +1008,9 @@ Set => {
#irn_flags => "R",
reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
ins => [ "eflags" ],
attr_type => "ia32_condcode_attr_t",
attr => "pn_Cmp pnc, int ins_permuted",
init_attr => "attr->pn_code = pnc;\n".
"attr->data.ins_permuted = ins_permuted;\n".
init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n".
"\tset_ia32_ls_mode(res, mode_Bu);\n",
emit => '. set%CMP0 %DB0',
latency => 1,
......@@ -1018,9 +1026,9 @@ CMov => {
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
am => "source,binary",
attr => "int ins_permuted, pn_Cmp pn_code",
init_attr => "attr->pn_code = pn_code;\n".
"attr->data.ins_permuted = ins_permuted;",
attr_type => "ia32_condcode_attr_t",
attr => "int ins_permuted, pn_Cmp pnc",
init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
latency => 1,
units => [ "GP" ],
mode => $mode_gp,
......@@ -1032,8 +1040,8 @@ Jcc => {
reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
ins => [ "eflags" ],
outs => [ "false", "true" ],
attr_type => "ia32_condcode_attr_t",
attr => "pn_Cmp pnc",
init_attr => "attr->pn_code = pnc;",
latency => 2,
units => [ "BRANCH" ],
},
......@@ -1042,10 +1050,12 @@ SwitchJmp => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp" ], out => [ "none" ] },
mode => "mode_T",
attr_type => "ia32_condcode_attr_t",
attr => "pn_Cmp pnc",
latency => 3,
units => [ "BRANCH" ],
mode => "mode_T",
modified_flags => $status_flags
modified_flags => $status_flags,
},
IJmp => {
......@@ -1548,21 +1558,25 @@ l_SSEtoX87 => {
# CopyB
CopyB => {
op_flags => "F|H",
state => "pinned",
reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
outs => [ "DST", "SRC", "CNT", "M" ],
units => [ "GP" ],
op_flags => "F|H",
state => "pinned",
reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
outs => [ "DST", "SRC", "CNT", "M" ],
attr_type => "ia32_copyb_attr_t",
attr => "unsigned size",
units => [ "GP" ],
# we don't care about this flag, so no need to mark this node
# modified_flags => [ "DF" ]
},
CopyB_i => {
op_flags => "F|H",
state => "pinned",
reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
outs => [ "DST", "SRC", "M" ],
units => [ "GP" ],
op_flags => "F|H",
state => "pinned",
reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
outs => [ "DST", "SRC", "M" ],
attr_type => "ia32_copyb_attr_t",
attr => "unsigned size",
units => [ "GP" ],
# we don't care about this flag, so no need to mark this node
# modified_flags => [ "DF" ]
},
......
......@@ -2118,8 +2118,7 @@ static ir_node *create_Switch(ir_node *node)
SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
}
res = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel);
set_ia32_pncode(res, get_Cond_defaultProj(node));
res = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, get_Cond_defaultProj(node));
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
......@@ -2212,16 +2211,13 @@ static ir_node *gen_CopyB(ir_node *node) {
res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);