-
/**
* ISA implementation for Firm IR nodes.
*/
#include "config.h"
#endif
-#ifdef WITH_LIBCORE
-#include <libcore/lc_opts.h>
-#endif
-
#include "bitset.h"
#include "obst.h"
#include "ircons_t.h"
#include "irgwalk.h"
#include "type.h"
+#include "irtools.h"
-#include "../bearch.h"
+#include "../be_t.h"
+#include "../bearch_t.h"
#include "../besched.h"
#include "../beutil.h"
+#include "../beabi.h"
#define N_REGS 3
static arch_register_t datab_regs[N_REGS];
static arch_register_class_t reg_classes[] = {
- { "datab", N_REGS, datab_regs },
+ { "datab", N_REGS, NULL, datab_regs },
};
static ir_op *op_push;
return bad;
}
-static void *firm_init(void)
+static void *firm_init(FILE *outfile)
{
static struct obstack obst;
static int inited = 0;
- arch_isa_t *isa = malloc(sizeof(*isa));
+ arch_isa_t *isa = xmalloc(sizeof(*isa));
int k;
- isa->impl = &firm_isa;
+ isa->impl = &firm_isa;
if(inited)
return NULL;
obstack_init(&obst);
for(k = 0; k < N_CLASSES; ++k) {
- const arch_register_class_t *cls = ®_classes[k];
+ arch_register_class_t *cls = ®_classes[k];
int i;
+ cls->mode = mode_Is;
for(i = 0; i < cls->n_regs; ++i) {
int n;
char buf[8];
return ®_classes[i];
}
+static const arch_register_class_t *firm_get_reg_class_for_mode(const void *self, const ir_mode *irm)
+{
+ return mode_is_datab(irm) ? ®_classes[CLS_DATAB] : NULL;
+}
+
+static ir_type *firm_abi_get_between_type(void *self) {
+ static ir_type *between_type = NULL;
+
+ if(!between_type) {
+ between_type = new_type_class(new_id_from_str("firm_be_between"));
+ set_type_size_bytes(between_type, 0);
+ }
+
+ return between_type;
+}
+
+static const be_abi_callbacks_t firm_abi_callbacks = {
+ NULL,
+ NULL,
+ firm_abi_get_between_type,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static void firm_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi)
+{
+ const arch_register_class_t *cls = ®_classes[CLS_DATAB];
+ int i, n;
+ be_abi_call_flags_t flags = { { 0, 0, 0, 0, 0 } };
+
+
+ for(i = 0, n = get_method_n_params(method_type); i < n; ++i) {
+ ir_type *t = get_method_param_type(method_type, i);
+ if(is_Primitive_type(t))
+ be_abi_call_param_reg(abi, i, &cls->regs[i]);
+ else
+ be_abi_call_param_stack(abi, i, 1, 0, 0);
+ }
+
+ for(i = 0, n = get_method_n_ress(method_type); i < n; ++i) {
+ ir_type *t = get_method_res_type(method_type, i);
+ if(is_Primitive_type(t))
+ be_abi_call_res_reg(abi, i, &cls->regs[i]);
+ }
+
+ flags.val = 0;
+ be_abi_call_set_flags(abi, flags, &firm_abi_callbacks);
+}
+
+
static const arch_register_req_t firm_std_reg_req = {
arch_register_req_type_normal,
®_classes[CLS_DATAB],
- NULL,
- NULL
+ 0,
+ 0
};
static const arch_register_req_t *
-firm_get_irn_reg_req(const void *self,
- arch_register_req_t *req, const ir_node *irn, int pos)
+firm_get_irn_reg_req(const void *self, const ir_node *irn, int pos)
{
if(is_firm_be_mode(get_irn_mode(irn)))
- memcpy(req, &firm_std_reg_req, sizeof(*req));
- else
- req = NULL;
+ return &firm_std_reg_req;
- return req;
+ return NULL;
}
struct irn_reg_assoc {
static arch_irn_flags_t firm_get_flags(const void *self, const ir_node *irn)
{
- arch_irn_flags_t res = arch_irn_flags_spillable;
+ arch_irn_flags_t res = 0;
if(get_irn_op(irn) == op_imm)
res |= arch_irn_flags_rematerializable;
return res;
}
+static void firm_set_stack_bias(const void *self, ir_node *irn, int bias)
+{
+}
+
+static ir_entity *firm_get_frame_entity(const void *self, const ir_node *irn)
+{
+ return NULL;
+}
+
+static void firm_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent)
+{
+}
+
static const arch_irn_ops_if_t firm_irn_ops_if = {
firm_get_irn_reg_req,
firm_set_irn_reg,
firm_get_irn_reg,
firm_classify,
- firm_get_flags
+ firm_get_flags,
+ firm_get_frame_entity,
+ firm_set_frame_entity,
+ firm_set_stack_bias,
+ NULL, /* get_inverse */
+ NULL, /* get_op_estimated_cost */
+ NULL, /* possible_memory_operand */
+ NULL, /* perform_memory_operand */
};
static const arch_irn_ops_t firm_irn_ops = {
static void prepare_walker(ir_node *irn, void *data)
{
- opcode opc = get_irn_opcode(irn);
+ ir_opcode opc = get_irn_opcode(irn);
/* A replacement for this node has already been computed. */
if(get_irn_link(irn))
ir_node *bl = get_nodes_block(irn);
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
- ir_node *op = get_irn_n(irn, i);
- opcode opc = get_irn_opcode(op);
+ ir_node *op = get_irn_n(irn, i);
+ ir_opcode opc = get_irn_opcode(op);
if(opc == iro_Const
|| opc == iro_Unknown
} firm_code_gen_t;
-static void clear_link(ir_node *irn, void *data)
-{
- set_irn_link(irn, NULL);
-}
-
static void firm_prepare_graph(void *self)
{
firm_code_gen_t *cg = self;
- irg_walk_graph(cg->irg, clear_link, localize_const_walker, NULL);
+ irg_walk_graph(cg->irg, firm_clear_link, localize_const_walker, NULL);
irg_walk_graph(cg->irg, NULL, prepare_walker, NULL);
}
irg_walk_graph(cg->irg, imm_scheduler, NULL, NULL);
}
+static void firm_after_ra(void *self)
+{
+}
+
static void firm_codegen_done(void *self)
{
free(self);
}
-static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env);
+static void *firm_cg_init(be_irg_t *birg);
-static const arch_code_generator_if_t firm_code_gen = {
+static const arch_code_generator_if_t firm_code_gen_if = {
firm_cg_init,
+ NULL,
firm_prepare_graph,
+ NULL, /* spill */
firm_before_sched,
firm_before_ra,
+ firm_after_ra,
firm_codegen_done
};
-static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env)
+static void *firm_cg_init(be_irg_t *birg)
{
firm_code_gen_t *cg = xmalloc(sizeof(*cg));
- cg->impl = &firm_code_gen;
- cg->irg = irg;
+ cg->impl = &firm_code_gen_if;
+ cg->irg = be_get_birg_irg(birg);
return cg;
}
-static const arch_code_generator_if_t *firm_get_code_generator(void *self)
+static const arch_code_generator_if_t *firm_get_code_generator_if(void *self)
{
- return &firm_code_gen;
+ return &firm_code_gen_if;
}
-static const list_sched_selector_t *firm_get_list_sched_selector(const void *self) {
+static const list_sched_selector_t *firm_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
return trivial_selector;
}
-#ifdef WITH_LIBCORE
-static void firm_register_options(lc_opt_entry_t *ent)
-{
+static const ilp_sched_selector_t *firm_get_ilp_sched_selector(const void *self) {
+ return NULL;
+}
+
+/**
+ * Returns the necessary byte alignment for storing a register of given class.
+ */
+static int firm_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
+ ir_mode *mode = arch_register_class_mode(cls);
+ return get_mode_size_bytes(mode);
+}
+
+static const be_execution_unit_t ***firm_get_allowed_execution_units(const void *self, const ir_node *irn) {
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+static const be_machine_t *firm_get_machine(const void *self) {
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+/**
+ * Return irp irgs in the desired order.
+ */
+static ir_graph **firm_get_irg_list(const void *self, ir_graph ***irg_list) {
+ return NULL;
+}
+
+/**
+ * Returns the libFirm configuration parameter for this backend.
+ */
+static const backend_params *firm_get_libfirm_params(void) {
+ static arch_dep_params_t ad = {
+ 1, /* allow subs */
+ 0, /* Muls are fast enough on Firm */
+ 31, /* shift would be ok */
+ 0, /* no Mulhs */
+ 0, /* no Mulhu */
+ 0, /* no Mulh */
+ };
+ static backend_params p = {
+ NULL, /* no additional opcodes */
+ NULL, /* will be set later */
+ 0, /* no dword lowering */
+ NULL, /* no creator function */
+ NULL, /* context for create_intrinsic_fkt */
+ };
+
+ p.dep_param = &ad;
+ return &p;
}
-#endif
const arch_isa_if_t firm_isa = {
-#ifdef WITH_LIBCORE
- firm_register_options,
-#endif
firm_init,
firm_done,
firm_get_n_reg_class,
firm_get_reg_class,
+ firm_get_reg_class_for_mode,
+ firm_get_call_abi,
firm_get_irn_handler,
- firm_get_code_generator,
- firm_get_list_sched_selector
+ firm_get_code_generator_if,
+ firm_get_list_sched_selector,
+ firm_get_ilp_sched_selector,
+ firm_get_reg_class_alignment,
+ firm_get_libfirm_params,
+ firm_get_allowed_execution_units,
+ firm_get_machine,
+ firm_get_irg_list,
};