Commit 87a6f0fa authored by Christian Würdig's avatar Christian Würdig
Browse files

changed ia32 attribute structure and switched to idents

parent 9eed6245
......@@ -288,7 +288,7 @@ char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
switch(get_ia32_op_type(n)) {
case ia32_Normal:
if (get_ia32_cnst(n)) {
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %s", n, get_ia32_cnst(n));
}
else {
......@@ -308,11 +308,11 @@ char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n, env));
break;
case ia32_AddrModeD:
if (get_ia32_cnst(n)) {
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s,%s%s",
ia32_emit_am(n, env),
get_ia32_sc(n) ? " OFFSET FLAT:" : " ", /* In case of a symconst we must add OFFSET to */
get_ia32_cnst(n)); /* tell the assembler to store it's address. */
is_ia32_ImmSymConst(n) ? " OFFSET FLAT:" : " ", /* In case of a symconst we must add OFFSET to */
get_ia32_cnst(n)); /* tell the assembler to store it's address. */
}
else {
const arch_register_t *in1 = get_in_reg(n, 2);
......@@ -657,20 +657,25 @@ void emit_ia32_CondJmp_i(const ir_node *irn, ia32_emit_env_t *env) {
* Emits code for conditional test and jump.
*/
static void TestJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
#define IA32_IS_IMMOP (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn))
FILE *F = env->out;
const char *op1 = arch_register_get_name(get_in_reg(irn, 0));
const char *op2 = get_ia32_cnst(irn);
const char *op2 = IA32_IS_IMMOP ? get_ia32_cnst(irn) : NULL;
char cmd_buf[SNPRINTF_BUF_LEN];
char cmnt_buf[SNPRINTF_BUF_LEN];
if (! op2)
op2 = arch_register_get_name(get_in_reg(irn, 1));
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "test %%%s,%s%s ", op1, get_ia32_cnst(irn) ? " " : " %", op2);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "test %%%s,%s%s ", op1, IA32_IS_IMMOP ? " " : " %", op2);
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
IA32_DO_EMIT(irn);
finish_CondJmp(F, irn, get_irn_mode(get_irn_n(irn, 0)));
#undef IA32_IS_IMMOP
}
/**
......
......@@ -44,32 +44,20 @@
extern int obstack_printf(struct obstack *obst, char *fmt, ...);
/***********************************************************************************
* _ _ _ __
* | | (_) | | / _|
* __| |_ _ _ __ ___ _ __ ___ _ __ _ _ __ | |_ ___ _ __| |_ __ _ ___ ___
* / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
* | (_| | |_| | | | | | | |_) | __/ | | | | | | || __/ | | || (_| | (_| __/
* \__,_|\__,_|_| |_| |_| .__/ \___|_| |_|_| |_|\__\___|_| |_| \__,_|\___\___|
* | |
* |_|
***********************************************************************************/
/**
* Returns the name of a SymConst.
* @param symc the SymConst
* @return name of the SymConst
* Returns the ident of a SymConst.
* @param symc The SymConst
* @return The ident of the SymConst
*/
const char *get_sc_name(ir_node *symc) {
if (get_irn_opcode(symc) != iro_SymConst)
return "NONE";
static ident *get_sc_ident(ir_node *symc) {
assert(get_irn_opcode(symc) == iro_SymConst && "need symconst to get ident");
switch (get_SymConst_kind(symc)) {
case symconst_addr_name:
return get_id_str(get_SymConst_name(symc));
return get_SymConst_name(symc);
case symconst_addr_ent:
return get_entity_ld_name(get_SymConst_entity(symc));
return get_entity_ld_ident(get_SymConst_entity(symc));
default:
assert(0 && "Unsupported SymConst");
......@@ -78,6 +66,19 @@ const char *get_sc_name(ir_node *symc) {
return NULL;
}
/***********************************************************************************
* _ _ _ __
* | | (_) | | / _|
* __| |_ _ _ __ ___ _ __ ___ _ __ _ _ __ | |_ ___ _ __| |_ __ _ ___ ___
* / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
* | (_| | |_| | | | | | | |_) | __/ | | | | | | || __/ | | || (_| | (_| __/
* \__,_|\__,_|_| |_| |_| .__/ \___|_| |_|_| |_|\__\___|_| |_| \__,_|\___\___|
* | |
* |_|
***********************************************************************************/
/**
* Returns a string containing the names of all registers within the limited bitset
*/
......@@ -183,12 +184,8 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
break;
case dump_node_nodeattr_txt:
if (get_ia32_cnst(n)) {
char *pref = "";
if (get_ia32_sc(n)) {
pref = "SymC ";
}
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
char *pref = is_ia32_ImmSymConst(n) ? "SymC" : "";
fprintf(F, "[%s%s]", pref, get_ia32_cnst(n));
}
......@@ -384,25 +381,15 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
* |___/
***************************************************************************************************/
static char *copy_str(const char *src) {
size_t l = strlen(src) + 1;
char *dst = xmalloc(l);
strncpy(dst, src, l);
dst[l - 1] = '\0';
return dst;
}
static char *set_cnst_from_tv(char *cnst, tarval *tv) {
int l = 64;
if (cnst) {
free(cnst);
}
/**
* Returns an ident for the given tarval tv.
*/
static ident *get_ident_for_tv(tarval *tv) {
char buf[1024];
cnst = xmalloc(l);
assert(tarval_snprintf(cnst, l, tv));
cnst[l - 1] = 0;
return cnst;
}
assert(tarval_snprintf(buf, sizeof(buf), tv));
return new_id_from_str(buf);
}
/**
* Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
......@@ -429,6 +416,22 @@ void set_ia32_op_type(ir_node *node, ia32_op_type_t tp) {
attr->data.tp = tp;
}
/**
* Gets the immediate op type of an ia32 node.
*/
ia32_immop_type_t get_ia32_immop_type(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return attr->data.imm_tp;
}
/**
* Sets the immediate op type of an ia32 node.
*/
void set_ia32_immop_type(ir_node *node, ia32_immop_type_t tp) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->data.imm_tp = tp;
}
/**
* Gets the supported addrmode of an ia32 node
*/
......@@ -489,7 +492,7 @@ char *get_ia32_am_offs(const ir_node *node) {
static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
ia32_attr_t *attr = get_ia32_attr(node);
if (! offset)
if (! offset || strlen(offset) < 1)
return;
/* offset could already have an explicit sign */
......@@ -521,15 +524,15 @@ static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
/**
* Add an offset for addrmode.
*/
void add_ia32_am_offs(ir_node *node, char *offset) {
extend_ia32_am_offs(node, offset, '+');
void add_ia32_am_offs(ir_node *node, const char *offset) {
extend_ia32_am_offs(node, (char *)offset, '+');
}
/**
* Sub an offset for addrmode.
*/
void sub_ia32_am_offs(ir_node *node, char *offset) {
extend_ia32_am_offs(node, offset, '-');
void sub_ia32_am_offs(ir_node *node, const char *offset) {
extend_ia32_am_offs(node, (char *)offset, '-');
}
/**
......@@ -553,7 +556,7 @@ void set_ia32_am_scale(ir_node *node, int scale) {
*/
tarval *get_ia32_Immop_tarval(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return attr->tv;
return attr->cnst_val.tv;
}
/**
......@@ -561,37 +564,33 @@ tarval *get_ia32_Immop_tarval(const ir_node *node) {
*/
void set_ia32_Immop_tarval(ir_node *node, tarval *tv) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->tv = tv;
attr->cnst = set_cnst_from_tv(attr->cnst, attr->tv);
attr->cnst_val.tv = tv;
attr->cnst = get_ident_for_tv(tv);
}
/**
* Return the sc attribute.
*/
const char *get_ia32_sc(const ir_node *node) {
ident *get_ia32_sc(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return attr->sc;
return attr->cnst_val.sc;
}
/**
* Sets the sc attribute.
*/
void set_ia32_sc(ir_node *node, const char *sc) {
void set_ia32_sc(ir_node *node, ident *sc) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->sc = copy_str(sc);
if (attr->cnst) {
free(attr->cnst);
}
attr->cnst = attr->sc;
attr->cnst_val.sc = sc;
attr->cnst = attr->cnst_val.sc;
}
/**
* Gets the string representation of the internal const (tv or symconst)
*/
char *get_ia32_cnst(const ir_node *node) {
const char *get_ia32_cnst(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return attr->cnst;
return get_id_str(attr->cnst);
}
/**
......@@ -599,7 +598,23 @@ char *get_ia32_cnst(const ir_node *node) {
*/
void set_ia32_cnst(ir_node *node, char *cnst) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->cnst = cnst;
attr->cnst = new_id_from_str(cnst);
}
/**
* Gets the ident representation of the internal const (tv or symconst)
*/
ident *get_ia32_id_cnst(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return attr->cnst;
}
/**
* Sets the ident representation of the internal const.
*/
void set_ia32_id_cnst(ir_node *node, ident *cnst) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->cnst = cnst;
}
/**
......@@ -895,43 +910,47 @@ void set_ia32_Immop_attr(ir_node *node, ir_node *cnst) {
ia32_attr_t *na = get_ia32_attr(node);
ia32_attr_t *ca = get_ia32_attr(cnst);
assert(is_ia32_Cnst(cnst) && "Need ia32_Const to set Immop attr");
na->tv = ca->tv;
if (ca->sc) {
na->sc = copy_str(ca->sc);
na->cnst = na->sc;
}
else {
na->cnst = set_cnst_from_tv(na->cnst, na->tv);
na->sc = NULL;
switch(get_ia32_Const_type(cnst)) {
case ia32_Const:
na->cnst_val.tv = ca->cnst_val.tv;
na->cnst = ca->cnst;
set_ia32_immop_type(node, ia32_ImmConst);
break;
case ia32_SymConst:
na->cnst_val.sc = ca->cnst_val.sc;
na->cnst = na->cnst_val.sc;
set_ia32_immop_type(node, ia32_ImmSymConst);
break;
default:
assert(0 && "Need ia32_Const to set Immop attr");
}
}
/**
* Copy the attributes from Immop to an Immop
*/
void copy_ia32_Immop_attr(ir_node *node, ir_node *src)
{
ia32_attr_t *na = get_ia32_attr(node);
ia32_attr_t *ca = get_ia32_attr(src);
void copy_ia32_Immop_attr(ir_node *dst, ir_node *src) {
ia32_attr_t *da = get_ia32_attr(dst);
ia32_attr_t *sa = get_ia32_attr(src);
assert(get_ia32_cnst(src) != NULL);
na->tv = ca->tv;
if (ca->sc) {
na->sc = copy_str(ca->sc);
na->cnst = na->sc;
}
else {
na->cnst = set_cnst_from_tv(na->cnst, na->tv);
na->sc = NULL;
switch(get_ia32_op_type(src)) {
case ia32_ImmConst:
da->cnst_val.tv = sa->cnst_val.tv;
da->cnst = sa->cnst;
set_ia32_immop_type(dst, ia32_ImmConst);
break;
case ia32_ImmSymConst:
da->cnst_val.sc = sa->cnst_val.sc;
da->cnst = sa->cnst;
set_ia32_immop_type(dst, ia32_ImmSymConst);
break;
default:
assert(0 && "Need Immop to copy Immop attr");
}
}
/**
* Copy the attributes from a Const to an ia32_Const
* Copy the attributes from a Firm Const to an ia32_Const
*/
void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst) {
ia32_attr_t *attr = get_ia32_attr(ia32_cnst);
......@@ -940,15 +959,14 @@ void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst) {
switch (get_irn_opcode(cnst)) {
case iro_Const:
attr->data.tp = ia32_Const;
attr->tv = get_Const_tarval(cnst);
attr->cnst = set_cnst_from_tv(attr->cnst, attr->tv);
attr->data.tp = ia32_Const;
attr->cnst_val.tv = get_Const_tarval(cnst);
attr->cnst = get_ident_for_tv(attr->cnst_val.tv);
break;
case iro_SymConst:
attr->data.tp = ia32_SymConst;
attr->tv = NULL;
attr->sc = copy_str(get_sc_name(cnst));
attr->cnst = attr->sc;
attr->data.tp = ia32_SymConst;
attr->cnst_val.sc = get_sc_ident(cnst);
attr->cnst = attr->cnst_val.sc;
break;
case iro_Unknown:
assert(0 && "Unknown Const NYI");
......@@ -976,6 +994,22 @@ void set_ia32_AddrMode(ir_node *node, char direction) {
}
}
/**
* Returns whether or not the node is an immediate operation with Const.
*/
int is_ia32_ImmConst(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return (attr->data.imm_tp == ia32_ImmConst);
}
/**
* Returns whether or not the node is an immediate operation with SymConst.
*/
int is_ia32_ImmSymConst(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
return (attr->data.imm_tp == ia32_ImmSymConst);
}
/**
* Returns whether or not the node is an AddrModeS node.
*/
......@@ -1094,10 +1128,7 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const ia32_regi
/* default compare operation to compare immediate ops */
int ia32_compare_immop_attr(ia32_attr_t *a, ia32_attr_t *b) {
if (a->data.tp == b->data.tp) {
if (! (a->cnst && b->cnst))
return 1;
return strcmp(a->cnst, b->cnst);
return a->cnst == b->cnst;
}
return 1;
......
......@@ -8,16 +8,8 @@
*/
#include "firm_config.h"
#include "ia32_nodes_attr.h"
/**
* Returns the name of a firm symconst.
*/
const char *get_sc_name(ir_node *symc);
/***************************************************************************************************
* _ _ _ __ _ _ _ _
* | | | | | | / / | | | | | | | |
......@@ -44,6 +36,16 @@ ia32_op_type_t get_ia32_op_type(const ir_node *node);
*/
void set_ia32_op_type(ir_node *node, ia32_op_type_t tp);
/**
* Gets the immediate op type of an ia32 node.
*/
ia32_immop_type_t get_ia32_immop_type(const ir_node *node);
/**
* Sets the immediate op type of an ia32 node.
*/
void set_ia32_immop_type(ir_node *node, ia32_immop_type_t tp);
/**
* Gets the supported addrmode of an ia32 node
*/
......@@ -72,12 +74,12 @@ char *get_ia32_am_offs(const ir_node *node);
/**
* Adds an offset for addrmode.
*/
void add_ia32_am_offs(ir_node *node, char *offset);
void add_ia32_am_offs(ir_node *node, const char *offset);
/**
* Subs an offset for addrmode.
*/
void sub_ia32_am_offs(ir_node *node, char *offset);
void sub_ia32_am_offs(ir_node *node, const char *offset);
/**
* Gets the addr mode const.
......@@ -102,23 +104,33 @@ void set_ia32_Immop_tarval(ir_node *node, tarval *tv);
/**
* Return the sc attribute.
*/
const char *get_ia32_sc(const ir_node *node);
ident *get_ia32_sc(const ir_node *node);
/**
* Sets the sc attribute.
*/
void set_ia32_sc(ir_node *node, const char *sc);
void set_ia32_sc(ir_node *node, ident *sc);
/**
* Gets the string representation of the internal const (tv or symconst)
*/
char *get_ia32_cnst(const ir_node *node);
const char *get_ia32_cnst(const ir_node *node);
/**
* Sets the string representation of the internal const.
*/
void set_ia32_cnst(ir_node *node, char *cnst);
/**
* Gets the ident representation of the internal const (tv or symconst)
*/
ident *get_ia32_id_cnst(const ir_node *node);
/**
* Sets the ident representation of the internal const.
*/
void set_ia32_id_cnst(ir_node *node, ident *cnst);
/**
* Sets the uses_frame flag.
*/
......@@ -335,6 +347,16 @@ void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst);
*/
void set_ia32_AddrMode(ir_node *node, char direction);
/**
* Returns whether or not the node is an immediate operation with Const.
*/
int is_ia32_ImmConst(const ir_node *node);
/**
* Returns whether or not the node is an immediate operation with SymConst.
*/
int is_ia32_ImmSymConst(const ir_node *node);
/**
* Returns whether or not the node is an AddrModeS node.
*/
......
......@@ -10,7 +10,21 @@
typedef enum { flavour_Div = 1, flavour_Mod, flavour_DivMod } ia32_op_flavour_t;
typedef enum { pn_EAX, pn_EDX } pn_ia32_Register;
typedef enum { ia32_Normal, ia32_Const, ia32_SymConst, ia32_AddrModeD, ia32_AddrModeS } ia32_op_type_t;
typedef enum {
ia32_Normal,
ia32_Const,
ia32_SymConst,
ia32_AddrModeD,
ia32_AddrModeS
} ia32_op_type_t;
typedef enum {
ia32_ImmNone,
ia32_ImmConst,
ia32_ImmSymConst
} ia32_immop_type_t;
typedef enum {
ia32_am_None = 0, /**<< no addrmode support */
ia32_am_Dest = 1, /**<< addrmode for destination only */
......@@ -55,6 +69,7 @@ typedef struct _ia32_register_req_t {
typedef struct _ia32_attr_t {
struct {
unsigned tp:3; /**< ia32 node type */
unsigned imm_tp:2; /**< ia32 immop type */
unsigned am_support:2; /**< indicates addrmode type supported by this node */
unsigned am_flavour:4; /**< the concrete addrmode characteristics */
......@@ -75,16 +90,19 @@ typedef struct _ia32_attr_t {
struct obstack *am_offs; /**< offsets for AddrMode */
tarval *tv; /**< tarval for immediate operations */
char *sc; /**< symconst name */
char *cnst; /**< points to the string representation of the constant value (either tv or sc) */
union {
tarval *tv; /**< tarval for immediate operations */
ident *sc; /**< the symconst ident */
} cnst_val;
ident *cnst; /**< points to the string representation of the constant value (either tv or sc) */
ir_mode *ls_mode; /**< the mode of the stored/loaded value */
ir_mode *res_mode; /**< the mode of the result */
ir_mode *ls_mode; /**< the mode of the stored/loaded value */
ir_mode *res_mode; /**< the mode of the result */
entity *frame_ent; /**< the frame entity attached to this node */
entity *frame_ent; /**< the frame entity attached to this node */
long pn_code; /**< projnum "types" (e.g. indicate compare operators and argument numbers) */
long pn_code; /**< projnum "types" (e.g. indicate compare operators and argument numbers) */
#ifndef NDEBUG
const char *orig_node; /**< holds the name of the original ir node for debugging purposes */
......
......@@ -262,15 +262,7 @@ void ia32_place_consts_set_modes(ir_node *irn, void *env) {
*/
static int ia32_cnst_compare(ir_node *n1, ir_node *n2) {
char *c1 = get_ia32_cnst(n1);
char *c2 = get_ia32_cnst(n2);
if (c1 && c2) /* both consts are set -> compare */
return strcmp(c1, c2) == 0;
else if (!c1 && !c2) /* both consts are not set -> true */
return 1;
return 0;
return get_ia32_id_cnst(n1) == get_ia32_id_cnst(n2);
}
/**
......@@ -584,7 +576,7 @@ static ir_node *fold_addr(be_abi_irg_t *babi, ir_node *irn, firm_dbg_module_t *m
ir_node *block = get_nodes_block(irn);
ir_node *res = irn;
char *offs = NULL;
char *offs_cnst = NULL;
const char *offs_cnst = NULL;
char *offs_lea = NULL;
int scale = 0;
int isadd = 0;
......@@ -636,7 +628,7 @@ static ir_node *fold_addr(be_abi_irg_t *babi, ir_node *irn, firm_dbg_module_t *m
am_flav = 0;
/* check if operand is either const */
if (get_ia32_cnst(irn)) {
if (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn)) {
DBG((mod, LEVEL_1, "\tfound op with imm"));
offs_cnst = get_ia32_cnst(irn);
......
......@@ -386,7 +386,7 @@ $additional_opcodes = 0;
4. sub %D1, %D1 /* optimized mov 0 to register */
}
else {
if (get_ia32_sc(n)) {
if (get_ia32_op_type(n) == ia32_SymConst) {
6. mov %D1, OFFSET FLAT:%C /* Move address of SymConst into register */