#define CLS_DATAB 0
+static int dump_node_Imm(ir_node *n, FILE *F, dump_reason_t reason) {
+ ir_mode *mode;
+ int bad = 0;
+ char buf[1024];
+ tarval *tv;
+ imm_attr_t *attr;
+
+ switch (reason) {
+ case dump_node_opcode_txt:
+ tv = get_Imm_tv(n);
+
+ if (tv) {
+ tarval_snprintf(buf, sizeof(buf), tv);
+ fprintf(F, "%s", buf);
+ }
+ else {
+ fprintf(F, "immSymC");
+ }
+ break;
+
+ case dump_node_mode_txt:
+ mode = get_irn_mode(n);
+
+ if (mode && mode != mode_BB && mode != mode_ANY && mode != mode_BAD && mode != mode_T) {
+ fprintf(F, "[%s]", get_mode_name(mode));
+ }
+ break;
+
+ case dump_node_nodeattr_txt:
+ attr = (imm_attr_t *)get_irn_generic_attr(n);
+
+ if (is_Imm(n) && attr->tp == imm_SymConst) {
+ const char *name = NULL;
+ ir_node *old_sym = attr->data.symconst;
+
+ switch (get_SymConst_kind(old_sym)) {
+ case symconst_addr_name:
+ name = get_id_str(get_SymConst_name(old_sym));
+ break;
+
+ case symconst_addr_ent:
+ name = get_entity_ld_name(get_SymConst_entity(old_sym));
+ break;
+
+ default:
+ assert(!"Unsupported SymConst");
+ }
+
+ fprintf(F, "&%s ", name);
+ }
+
+ break;
+
+ case dump_node_info_txt:
+ break;
+ }
+
+ return bad;
+}
+
static void firm_init(void)
{
static struct obstack obst;
if(!op_imm) {
rflct_sig_t *sig;
int imm_opc = get_next_ir_opcode();
+ ir_op_ops ops;
+
+ memset(&ops, 0, sizeof(ops));
+ ops.dump_node = dump_node_Imm;
op_imm = new_ir_op(imm_opc, "Imm",
- op_pin_state_pinned, 0, oparity_zero, 0, sizeof(imm_attr_t), NULL);
+ op_pin_state_pinned, 0, oparity_zero, 0, sizeof(imm_attr_t), &ops);
sig = rflct_signature_allocate(1, 1);
rflct_signature_set_arg(sig, 0, 0, "Imm", RFLCT_MC(Data), 0, 0);
return new_ir_node(NULL, irg, bl, op_push, mode_M, 2, ins);
}
-static ir_node *new_Imm(ir_graph *irg, ir_node *bl, ir_node *cnst)
-{
- ir_node *ins[1];
- ir_node *res;
- imm_attr_t *attr;
-
- res = new_ir_node(NULL, irg, bl, op_imm, get_irn_mode(cnst), 0, ins);
- attr = (imm_attr_t *) &res->attr;
-
- switch (get_irn_opcode(cnst)) {
- case iro_Const:
- attr->tp = imm_Const;
- attr->data.tv = get_Const_tarval(cnst);
- break;
- case iro_SymConst:
- attr->tp = imm_SymConst;
- //attr->data.ent = get_SymConst_entity(cnst);
- break;
- case iro_Unknown:
- break;
- default: assert(0 && "Cannot create Imm for this opcode");
- }
+/**
+ * Creates an op_Imm node from an op_Const.
+ */
+static ir_node *new_Imm(ir_graph *irg, ir_node *bl, ir_node *cnst) {
+ ir_node *ins[1];
+ ir_node *res;
+ imm_attr_t *attr;
+
+ res = new_ir_node(NULL, irg, bl, op_imm, get_irn_mode(cnst), 0, ins);
+ attr = (imm_attr_t *) &res->attr;
+
+ switch (get_irn_opcode(cnst)) {
+ case iro_Const:
+ attr->tp = imm_Const;
+ attr->data.tv = get_Const_tarval(cnst);
+ break;
+ case iro_SymConst:
+ attr->tp = imm_SymConst;
+ attr->data.symconst = cnst;
+ break;
+ case iro_Unknown:
+ break;
+ default:
+ assert(0 && "Cannot create Imm for this opcode");
+ }
- return res;
+ return res;
}
int is_Imm(const ir_node *irn) {
- return get_irn_op(irn) == op_imm;
+ return get_irn_op(irn) == op_imm;
}
+/**
+ * Returns the tarval from an Imm node or NULL in case of a SymConst
+ */
+tarval *get_Imm_tv(ir_node *irn) {
+ imm_attr_t *attr;
+
+ assert(is_Imm(irn) && "Cannot get tv from non-Imm");
+ attr = (imm_attr_t *)get_irn_generic_attr(irn);
+ if (attr->tp == imm_Const) {
+ return attr->data.tv;
+ }
+ else
+ return NULL;
+}
+
+/**
+ * Returns the SymConst from an Imm node or NULL in case of a Const
+ */
+ir_node *get_Imm_sc(ir_node *irn) {
+ imm_attr_t *attr;
+
+ assert(is_Imm(irn) && "Cannot get SymConst from non-Imm");
+ attr = (imm_attr_t *)get_irn_generic_attr(irn);
+ if (attr->tp == imm_SymConst) {
+ return attr->data.symconst;
+ }
+ else
+ return NULL;
+}
+
+
static void prepare_walker(ir_node *irn, void *data)
{
opcode opc = get_irn_opcode(irn);
char buf[128];
ir_node *nc;
ir_node *push;
- int i, n;
+ int i, n = get_Call_n_params(irn);
type *nt;
+ unsigned cc = get_method_calling_convention(get_Call_type(irn));
- store = new_Push(irg, bl, store, get_Call_param(irn, 0));
+ if (cc & cc_last_on_top) {
+ store = new_Push(irg, bl, store, get_Call_param(irn, 0));
- for(i = 1, n = get_Call_n_params(irn); i < n; ++i) {
- store = new_Push(irg, bl, store, get_Call_param(irn, i));
- }
+ for (i = 1; i < n; ++i)
+ store = new_Push(irg, bl, store, get_Call_param(irn, i));
+ }
+ else {
+ store = new_Push(irg, bl, store, get_Call_param(irn, n - 1));
+
+ for (i = n - 2; i >= 0; --i)
+ store = new_Push(irg, bl, store, get_Call_param(irn, i));
+ }
snprintf(buf, sizeof(buf), "push_%s", get_type_name(ct));
}
const arch_isa_if_t firm_isa = {
- firm_init,
- firm_get_n_reg_class,
- firm_get_reg_class,
- firm_prepare_graph
+ firm_init,
+ firm_get_n_reg_class,
+ firm_get_reg_class,
+ firm_prepare_graph,
+ &firm_irn_handler
};