void amd64_emit_immediate(const ir_node *node)
{
- (void) node;
- /* TODO */
+ const amd64_immediate_attr_t *attr = get_amd64_immediate_attr_const (node);
+ be_emit_char('$');
+ be_emit_irprintf("0x%X", attr->imm_value);
}
void amd64_emit_source_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_in_reg(node, pos);
+ be_emit_char('%');
be_emit_string(arch_register_get_name(reg));
}
void amd64_emit_dest_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_out_reg(node, pos);
+ be_emit_char('%');
be_emit_string(arch_register_get_name(reg));
}
(void) node;
}
+/**
+ * Emit a SymConst.
+ */
+static void emit_amd64_SymConst(const ir_node *irn)
+{
+ const amd64_SymConst_attr_t *attr = get_amd64_SymConst_attr_const(irn);
+// sym_or_tv_t key, *entry;
+// unsigned label;
+//
+// key.u.id = get_entity_ld_ident(attr->entity);
+// key.is_ident = 1;
+// key.label = 0;
+// entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
+// if (entry->label == 0) {
+// /* allocate a label */
+// entry->label = get_unique_label();
+// }
+// label = entry->label;
+
+
+ be_gas_emit_entity(attr->entity);
+ be_emit_char(':');
+ be_emit_finish_line_gas(irn);
+ be_emit_cstring("\t.long 0x0");
+ be_emit_finish_line_gas(irn);
+}
+
+
/**
* Emits code for a return.
*/
return (amd64_attr_t *)get_irn_generic_attr(node);
}
-static const amd64_immediate_attr_t *get_amd64_immediate_attr_const(const ir_node *node)
+const amd64_immediate_attr_t *get_amd64_immediate_attr_const(const ir_node *node)
{
const amd64_attr_t *attr = get_amd64_attr_const(node);
const amd64_immediate_attr_t *imm_attr = CONST_CAST_AMD64_ATTR(amd64_immediate_attr_t, attr);
}
*/
+const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node)
+{
+ const amd64_attr_t *attr = get_amd64_attr_const(node);
+ const amd64_SymConst_attr_t *sym_attr = CONST_CAST_AMD64_ATTR(amd64_SymConst_attr_t, attr);
+
+ return sym_attr;
+}
+
/**
* Returns the argument register requirements of a amd64 node.
attr->imm_value = imm_value;
}
+/**
+ * Initialize SymConst attributes.
+ */
+static void init_amd64_SymConst_attributes(ir_node *node, ir_entity *entity)
+{
+ amd64_SymConst_attr_t *attr = get_irn_generic_attr (node);
+ attr->entity = entity;
+}
+
+/** Compare node attributes for SymConst. */
+static int cmp_amd64_attr_SymConst(ir_node *a, ir_node *b)
+{
+ const amd64_SymConst_attr_t *attr_a = get_amd64_SymConst_attr_const(a);
+ const amd64_SymConst_attr_t *attr_b = get_amd64_SymConst_attr_const(b);
+
+ if (attr_a->entity != attr_b->entity)
+ return 1;
+
+ return 0;
+}
+
+
/** Compare node attributes for Immediates. */
static int cmp_amd64_attr_immediate(ir_node *a, ir_node *b)
{
amd64_attr_t *get_amd64_attr(ir_node *node);
const amd64_attr_t *get_amd64_attr_const(const ir_node *node);
+const amd64_immediate_attr_t *get_amd64_immediate_attr_const(const ir_node *node);
+const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node);
/**
* Returns the argument register requirements of an amd64 node.
typedef struct amd64_attr_t amd64_attr_t;
typedef struct amd64_immediate_attr_t amd64_immediate_attr_t;
+typedef struct amd64_SymConst_attr_t amd64_SymConst_attr_t;
struct amd64_attr_t
{
unsigned imm_value; /**< the immediate value to load */
};
+struct amd64_SymConst_attr_t
+{
+ ir_entity *entity;
+};
+
#define CAST_AMD64_ATTR(type,ptr) ((type *)(ptr))
#define CONST_CAST_AMD64_ATTR(type,ptr) ((const type *)(ptr))
amd64_immediate_attr_t =>
"\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
. "\tinit_amd64_immediate_attributes(res, imm_value);",
+ amd64_SymConst_attr_t =>
+ "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
+ . "\tinit_amd64_SymConst_attributes(res, entity);",
);
%compare_attr = (
amd64_attr_t => "cmp_amd64_attr",
amd64_immediate_attr_t => "cmp_amd64_attr_immediate",
+ amd64_SymConst_attr_t => "cmp_amd64_attr_SymConst",
);
%nodes = (
emit => '. movq %C, %D1',
mode => "mode_Iu",
},
+SymConst => {
+ op_flags => "c",
+ irn_flags => "R",
+ attr => "ir_entity *entity",
+ attr_type => "amd64_SymConst_attr_t",
+ reg_req => { out => [ "gp" ] },
+ mode => 'mode_Iu',
+},
);
return res;
}
+/**
+ * Transforms a SymConst node.
+ *
+ * @return The transformed ARM node.
+ */
+static ir_node *gen_SymConst(ir_node *node)
+{
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_entity *entity = get_SymConst_entity(node);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *new_node;
+
+ new_node = new_bd_amd64_SymConst(dbgi, block, entity);
+ be_dep_on_frame(new_node);
+ return new_node;
+}
+
/**
* Transforms an Add node.
*
be_dep_on_frame (res);
return res;
}
+
+
+
/* Boilerplate code for transformation: */
static void amd64_pretransform_node(void)
/* set stack parameter passing style */
be_abi_call_set_flags(abi, call_flags, &amd64_abi_callbacks);
- for (i = 0; i < n; i++) {
- /* TODO: implement register parameter: */
- /* reg = get reg for param i; */
- /* be_abi_call_param_reg(abi, i, reg); */
+ int no_reg = 0;
- /* default: all parameters on stack */
+ for (i = 0; i < n; i++) {
tp = get_method_param_type(method_type, i);
mode = get_type_mode(tp);
- be_abi_call_param_stack(abi, i, mode, 4, 0, 0, ABI_CONTEXT_BOTH);
+ printf ("MODE %p %p XX %d\n", mode, mode_Iu, i);
+
+ if (!no_reg && (i == 0 || i == 1) && mode == mode_Iu) {
+ printf("TEST%d\n", i);
+ be_abi_call_param_reg(abi, i,
+ i == 0 ? &amd64_gp_regs[REG_RDI]
+ : &amd64_gp_regs[REG_RSI],
+ ABI_CONTEXT_BOTH);
+ /* default: all parameters on stack */
+ } else {
+ no_reg = 1;
+ be_abi_call_param_stack(abi, i, mode, 4, 0, 0, ABI_CONTEXT_BOTH);
+ }
}
/* TODO: set correct return register */