Commit 89a44765 authored by Matthias Braun's avatar Matthias Braun
Browse files

finish support for custom backend node attributes, separate x87 attributes...

finish support for custom backend node attributes, separate x87 attributes from normal ia32 attributes to test this

[r14328]
parent 7f81d2a2
......@@ -250,7 +250,7 @@ void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos)
void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos)
{
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
assert(pos < 3);
be_emit_char(env, '%');
......@@ -472,10 +472,10 @@ void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node) {
// should not happen...
assert(0);
} else {
const ia32_attr_t *attr = get_ia32_attr_const(node);
const arch_register_t *in1 = attr->x87[0];
const arch_register_t *in2 = attr->x87[1];
const arch_register_t *out = attr->x87[2];
const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
const arch_register_t *in1 = x87_attr->x87[0];
const arch_register_t *in2 = x87_attr->x87[1];
const arch_register_t *out = x87_attr->x87[2];
const arch_register_t *in;
in = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
......@@ -870,21 +870,21 @@ void emit_ia32_xCondJmp(ia32_emit_env_t *env, const ir_node *node) {
*/
static
void emit_ia32_x87CondJmp(ia32_emit_env_t *env, const ir_node *node) {
const ia32_attr_t *attr = get_ia32_attr_const(node);
const char *reg = attr->x87[1]->name;
long pnc = get_ia32_pncode(node);
const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
const char *reg = x87_attr->x87[1]->name;
long pnc = get_ia32_pncode(node);
switch (get_ia32_irn_opcode(node)) {
case iro_ia32_fcomrJmp:
pnc = get_inversed_pnc(pnc);
reg = attr->x87[0]->name;
reg = x87_attr->x87[0]->name;
case iro_ia32_fcomJmp:
default:
be_emit_cstring(env, "\tfucom ");
break;
case iro_ia32_fcomrpJmp:
pnc = get_inversed_pnc(pnc);
reg = attr->x87[0]->name;
reg = x87_attr->x87[0]->name;
case iro_ia32_fcompJmp:
be_emit_cstring(env, "\tfucomp ");
break;
......
......@@ -55,14 +55,6 @@
#include "gen_ia32_regalloc_if.h"
#include "gen_ia32_machine.h"
/**
* returns true if a node has x87 registers
*/
int ia32_has_x87_register(const ir_node *n) {
assert(is_ia32_irn(n) && "Need ia32 node.");
return is_irn_machine_user(n, 0);
}
/***********************************************************************************
* _ _ _ __
* | | (_) | | / _|
......@@ -199,11 +191,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
for (i = 0; i < n_res; i++) {
const arch_register_t *reg;
/* retrieve "real" x87 register */
if (ia32_has_x87_register(n))
reg = get_ia32_attr(n)->x87[i + 2];
else
reg = slots[i];
reg = slots[i];
fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
}
......@@ -428,6 +416,18 @@ const ia32_attr_t *get_ia32_attr_const(const ir_node *node) {
return (const ia32_attr_t*) get_irn_generic_attr_const(node);
}
ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
return x87_attr;
}
const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node) {
const ia32_attr_t *attr = get_ia32_attr_const(node);
const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
return x87_attr;
}
/**
* Gets the type of an ia32 node.
*/
......@@ -1163,7 +1163,10 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
set_ia32_out_req_all(node, out_reqs);
set_ia32_latency(node, latency);
attr->exec_units = execution_units;
attr->exec_units = execution_units;
#ifndef NDEBUG
attr->attr_type |= IA32_ATTR_ia32_attr_t;
#endif
attr->out_flags = NEW_ARR_D(int, obst, n_res);
memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0]));
......@@ -1172,6 +1175,15 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
memset(attr->slots, 0, n_res * sizeof(attr->slots[0]));
}
void
init_ia32_x87_attributes(ir_node *res)
{
#ifndef NDEBUG
ia32_attr_t *attr = get_ia32_attr(res);
attr->attr_type |= IA32_ATTR_ia32_x87_attr_t;
#endif
}
ir_node *get_ia32_result_proj(const ir_node *node)
{
const ir_edge_t *edge;
......
......@@ -54,6 +54,8 @@ int ia32_has_x87_register(const ir_node *n);
ia32_attr_t *get_ia32_attr(ir_node *node);
const ia32_attr_t *get_ia32_attr_const(const ir_node *node);
ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node);
const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node);
/**
* Gets the type of an ia32 node.
......@@ -488,6 +490,8 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
const be_execution_unit_t ***execution_units,
int n_res, unsigned latency);
void init_ia32_x87_attributes(ir_node *node);
/**
* Registers the ia32_copy_attr function for all ia32 opcodes.
*/
......
......@@ -86,6 +86,14 @@ enum {
ia32_pn_Cmp_Unsigned = 0x100 /**< set this flag in a pnc to indicate an unsigned compare operation */
};
#ifndef NDEBUG
typedef enum {
IA32_ATTR_INVALID = 0,
IA32_ATTR_ia32_attr_t = 1 << 0,
IA32_ATTR_ia32_x87_attr_t = 1 << 1,
} ia32_attr_type_t;
#endif
typedef struct ia32_attr_t ia32_attr_t;
struct ia32_attr_t {
struct {
......@@ -133,17 +141,37 @@ struct ia32_attr_t {
unsigned latency; /**< the latency of the instruction in clock cycles */
#ifndef NDEBUG
const char *orig_node; /**< holds the name of the original ir node for debugging purposes */
#endif /* 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 *x87[3]; /**< register slots for x87 register */
const arch_register_t **slots; /**< register slots for assigned registers */
};
#endif /* FIRM_BE_IA32_IA32_NODES_ATTR_H */
typedef struct ia32_x87_attr_t ia32_x87_attr_t;
struct ia32_x87_attr_t {
ia32_attr_t attr;
const arch_register_t *x87[3]; /**< register slots for x87 register */
};
/* the following union is necessary to indicate to the compiler that we might want to cast
* the structs (we use them to simulate OO-inheritance) */
union allow_casts_attr_t_ {
ia32_attr_t attr;
ia32_x87_attr_t x87_attr;
};
#ifndef NDEBUG
#define CAST_IA32_ATTR(type,ptr) (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (type*) (ptr))
#define CONST_CAST_IA32_ATTR(type,ptr) (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (const type*) (ptr))
#else
#define CAST_IA32_ATTR(type,ptr) ((type*) (ptr))
#define CONST_CAST_IA32_ATTR(type,ptr) ((const type*) (ptr))
#endif
#endif
......@@ -289,6 +289,13 @@ $arch = "ia32";
$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
$default_attr_type = "ia32_attr_t";
%init_attr = (
ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
ia32_x87_attr_t =>
"\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
"\tinit_ia32_x87_attributes(res);",
);
%operands = (
);
......@@ -799,7 +806,8 @@ Unknown_VFP => {
reg_req => { out => [ "vfp_UKNWN" ] },
units => [],
emit => "",
mode => "mode_E"
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
Unknown_XMM => {
......@@ -829,7 +837,8 @@ NoReg_VFP => {
reg_req => { out => [ "vfp_NOREG" ] },
units => [],
emit => "",
mode => "mode_E"
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
NoReg_XMM => {
......@@ -1315,6 +1324,7 @@ vfCmpCMov => {
latency => 10,
units => [ "VFP" ],
mode => $mode_gp,
attr_type => "ia32_x87_attr_t",
},
CmpSet => {
......@@ -1347,6 +1357,7 @@ vfCmpSet => {
latency => 10,
units => [ "VFP" ],
mode => $mode_gp,
attr_type => "ia32_x87_attr_t",
},
vfCMov => {
......@@ -1355,6 +1366,7 @@ vfCMov => {
latency => 10,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
#----------------------------------------------------------#
......@@ -1377,6 +1389,7 @@ vfadd => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfmul => {
......@@ -1385,6 +1398,7 @@ vfmul => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
l_vfmul => {
......@@ -1399,6 +1413,7 @@ vfsub => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
l_vfsub => {
......@@ -1411,6 +1426,7 @@ vfdiv => {
outs => [ "res", "M" ],
latency => 20,
units => [ "VFP" ],
attr_type => "ia32_x87_attr_t",
},
l_vfdiv => {
......@@ -1424,6 +1440,7 @@ vfprem => {
latency => 20,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
l_vfprem => {
......@@ -1437,6 +1454,7 @@ vfabs => {
latency => 2,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfchs => {
......@@ -1445,6 +1463,7 @@ vfchs => {
latency => 2,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfsin => {
......@@ -1453,6 +1472,7 @@ vfsin => {
latency => 150,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfcos => {
......@@ -1461,6 +1481,7 @@ vfcos => {
latency => 150,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfsqrt => {
......@@ -1469,6 +1490,7 @@ vfsqrt => {
latency => 30,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
# virtual Load and Store
......@@ -1480,6 +1502,7 @@ vfld => {
outs => [ "res", "M" ],
latency => 2,
units => [ "VFP" ],
attr_type => "ia32_x87_attr_t",
},
vfst => {
......@@ -1489,6 +1512,7 @@ vfst => {
latency => 2,
units => [ "VFP" ],
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
# Conversions
......@@ -1498,6 +1522,7 @@ vfild => {
outs => [ "res", "M" ],
latency => 4,
units => [ "VFP" ],
attr_type => "ia32_x87_attr_t",
},
l_vfild => {
......@@ -1511,6 +1536,7 @@ vfist => {
latency => 4,
units => [ "VFP" ],
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
l_vfist => {
......@@ -1528,6 +1554,7 @@ vfldz => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfld1 => {
......@@ -1536,6 +1563,7 @@ vfld1 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfldpi => {
......@@ -1544,6 +1572,7 @@ vfldpi => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfldln2 => {
......@@ -1552,6 +1581,7 @@ vfldln2 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfldlg2 => {
......@@ -1560,6 +1590,7 @@ vfldlg2 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfldl2t => {
......@@ -1568,6 +1599,7 @@ vfldl2t => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfldl2e => {
......@@ -1576,16 +1608,17 @@ vfldl2e => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
vfConst => {
op_flags => "c",
irn_flags => "R",
# init_attr => " set_ia32_ls_mode(res, mode);",
reg_req => { out => [ "vfp" ] },
latency => 3,
units => [ "VFP" ],
mode => "mode_E",
attr_type => "ia32_x87_attr_t",
},
# other
......@@ -1597,6 +1630,7 @@ vfCondJmp => {
outs => [ "false", "true", "temp_reg_eax" ],
latency => 10,
units => [ "VFP" ],
attr_type => "ia32_x87_attr_t",
},
#------------------------------------------------------------------------#
......@@ -1615,6 +1649,7 @@ fadd => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fadd%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
faddp => {
......@@ -1622,6 +1657,7 @@ faddp => {
rd_constructor => "NONE",
reg_req => { },
emit => '. faddp %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fmul => {
......@@ -1629,6 +1665,7 @@ fmul => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fmul%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fmulp => {
......@@ -1636,6 +1673,7 @@ fmulp => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fmulp %x87_binop',,
attr_type => "ia32_x87_attr_t",
},
fsub => {
......@@ -1643,6 +1681,7 @@ fsub => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsub%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fsubp => {
......@@ -1651,6 +1690,7 @@ fsubp => {
reg_req => { },
# see note about gas bugs
emit => '. fsubrp %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fsubr => {
......@@ -1659,6 +1699,7 @@ fsubr => {
irn_flags => "R",
reg_req => { },
emit => '. fsubr%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fsubrp => {
......@@ -1668,6 +1709,7 @@ fsubrp => {
reg_req => { },
# see note about gas bugs
emit => '. fsubp %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fprem => {
......@@ -1675,6 +1717,7 @@ fprem => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fprem1',
attr_type => "ia32_x87_attr_t",
},
# this node is just here, to keep the simulator running
......@@ -1684,6 +1727,7 @@ fpremp => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fprem1',
attr_type => "ia32_x87_attr_t",
},
fdiv => {
......@@ -1691,6 +1735,7 @@ fdiv => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fdiv%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fdivp => {
......@@ -1699,6 +1744,7 @@ fdivp => {
reg_req => { },
# see note about gas bugs
emit => '. fdivrp %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fdivr => {
......@@ -1706,6 +1752,7 @@ fdivr => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fdivr%XM %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fdivrp => {
......@@ -1714,6 +1761,7 @@ fdivrp => {
reg_req => { },
# see note about gas bugs
emit => '. fdivp %x87_binop',
attr_type => "ia32_x87_attr_t",
},
fabs => {
......@@ -1721,6 +1769,7 @@ fabs => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fabs',
attr_type => "ia32_x87_attr_t",
},
fchs => {
......@@ -1728,6 +1777,7 @@ fchs => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fchs',
attr_type => "ia32_x87_attr_t",
},
fsin => {
......@@ -1735,6 +1785,7 @@ fsin => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsin',
attr_type => "ia32_x87_attr_t",
},
fcos => {
......@@ -1742,6 +1793,7 @@ fcos => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fcos',
attr_type => "ia32_x87_attr_t",
},
fsqrt => {
......@@ -1749,6 +1801,7 @@ fsqrt => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsqrt $',
attr_type => "ia32_x87_attr_t",
},
# x87 Load and Store
......@@ -1759,6 +1812,7 @@ fld => {
state => "exc_pinned",
reg_req => { },
emit => '. fld%XM %AM',
attr_type => "ia32_x87_attr_t",
},
fst => {
......@@ -1768,6 +1822,7 @@ fst => {
reg_req => { },
emit => '. fst%XM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
fstp => {
......@@ -1777,6 +1832,7 @@ fstp => {
reg_req => { },
emit => '. fstp%XM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
# Conversions
......@@ -1786,6 +1842,7 @@ fild => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fild%XM %AM',
attr_type => "ia32_x87_attr_t",
},
fist => {
......@@ -1794,6 +1851,7 @@ fist => {
reg_req => { },
emit => '. fist%XM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
fistp => {
......@@ -1802,6 +1860,7 @@ fistp => {
reg_req => { },
emit => '. fistp%XM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
},
# constants
......@@ -1811,6 +1870,7 @@ fldz => {
irn_flags => "R",
reg_req => { },
emit => '. fldz',
attr_type => "ia32_x87_attr_t",
},
fld1 => {
......@@ -1818,6 +1878,7 @@ fld1 => {
irn_flags => "R",
reg_req => { },
emit => '. fld1',
attr_type => "ia32_x87_attr_t",
},
fldpi => {
......@@ -1825,6 +1886,7 @@ fldpi => {
irn_flags => "R",
reg_req => { },
emit => '. fldpi',
attr_type => "ia32_x87_attr_t",
},
fldln2 => {
......@@ -1832,6 +1894,7 @@ fldln2 => {
irn_flags => "R",