Commit ad177bc3 authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Added call serialization for firm arch

parent 9f0f433b
......@@ -117,12 +117,25 @@ int arch_is_register_operand(const arch_env_t *env,
int arch_reg_is_allocatable(const arch_env_t *env, const ir_node *irn,
int pos, const arch_register_t *reg)
{
const arch_register_class_t *cls = arch_register_get_class(reg);
int n_regs = arch_register_class_n_regs(cls);
bitset_t *bs = bitset_alloca(n_regs);
arch_get_allocatable_regs(env, irn, pos, cls, bs);
return bitset_is_set(bs, arch_register_get_index(reg));
int res = 0;
arch_register_req_t req;
arch_get_register_req(env, &req, irn, pos);
switch(req.type) {
case arch_register_req_type_normal:
res = req.cls == reg->reg_class;
break;
case arch_register_req_type_limited:
{
bitset_t *bs = bitset_alloca(req.cls->n_regs);
req.data.limited(irn, pos, bs);
res = bitset_is_set(bs, arch_register_get_index(reg));
}
default:
res = 0;
}
return res;
}
const arch_register_class_t *
......
......@@ -196,6 +196,7 @@ typedef enum _arch_irn_class_t {
arch_irn_class_branch
} arch_irn_class_t;
/*
* Some words about positions and indices:
*
......@@ -304,6 +305,7 @@ struct _arch_irn_ops_t {
*/
arch_irn_class_t (*classify)(const arch_irn_ops_t *self, const ir_node *irn);
};
/**
......@@ -440,6 +442,13 @@ struct _arch_isa_if_t {
*/
const arch_register_class_t *(*get_reg_class)(int i);
/**
* Prepare a graph.
* This function is called each time, the backend starts running over
* a graph.
* @param irg The graph.
*/
void (*prepare_graph)(ir_graph *irg);
};
#define ARCH_MAX_HANDLERS 8
......
......@@ -9,7 +9,15 @@
#include "bitset.h"
#include "obst.h"
#include "irmode_t.h"
#include "irnode_t.h"
#include "irgmod.h"
#include "ircons_t.h"
#include "irgwalk.h"
#include "type.h"
#include "bearch.h"
#include "beutil.h"
#include "irreflect.h"
......@@ -21,6 +29,19 @@ static arch_register_class_t reg_classes[] = {
{ "datab", N_REGS, datab_regs },
};
static ir_op *op_push_end;
static ir_op *op_push;
static ir_op *op_imm;
static type *push_type;
typedef struct {
enum { imm_Const, imm_SymConst } tp;
union {
tarval *tv;
entity *ent;
} data;
} imm_attr_t;
#define N_CLASSES \
(sizeof(reg_classes) / sizeof(reg_classes[0]))
......@@ -57,6 +78,29 @@ static void firm_init(void)
reg->type = 0;
}
}
/*
* Create some opcodes and types to let firm look a little
* bit more like real machines.
*/
if(!op_push_end) {
op_push_end = new_ir_op(get_next_ir_opcode(), "PushEnd",
op_pin_state_pinned, 0, oparity_unary, 0, 0);
}
if(!op_push) {
op_push = new_ir_op(get_next_ir_opcode(), "Push",
op_pin_state_pinned, 0, oparity_binary, 0, 0);
}
if(!op_imm) {
op_imm = new_ir_op(get_next_ir_opcode(), "Imm",
op_pin_state_pinned, 0, oparity_zero, 0, sizeof(imm_attr_t));
}
if(!push_type)
push_type = new_type_pointer(new_id_from_str("push_ptr"), get_glob_type());
}
static int firm_get_n_reg_class(void)
......@@ -88,7 +132,7 @@ static const arch_register_req_t *
firm_get_irn_reg_req(const arch_irn_ops_t *self,
arch_register_req_t *req, const ir_node *irn, int pos)
{
if(mode_is_datab(get_irn_mode(irn)))
if(is_firm_be_mode(get_irn_mode(irn)))
memcpy(req, &firm_std_reg_req, sizeof(*req));
else
req = NULL;
......@@ -171,12 +215,6 @@ static const arch_irn_ops_t irn_ops = {
firm_classify
};
const arch_isa_if_t firm_isa = {
firm_init,
firm_get_n_reg_class,
firm_get_reg_class
};
static const arch_irn_ops_t *firm_get_irn_ops(const arch_irn_handler_t *self,
const ir_node *irn)
{
......@@ -186,3 +224,118 @@ static const arch_irn_ops_t *firm_get_irn_ops(const arch_irn_handler_t *self,
const arch_irn_handler_t firm_irn_handler = {
firm_get_irn_ops,
};
static ir_node *new_PushEnd(ir_graph *irg, ir_node *bl, ir_node *arg)
{
ir_node *ins[1];
ins[0] = arg;
return new_ir_node(NULL, irg, bl, op_push_end, mode_P, 1, ins);
}
static ir_node *new_Push(ir_graph *irg, ir_node *bl, ir_node *push, ir_node *arg)
{
ir_node *ins[2];
ins[0] = push;
ins[1] = arg;
return new_ir_node(NULL, irg, bl, op_push, mode_P, 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;
if(get_irn_opcode(cnst) == iro_SymConst) {
attr->tp = imm_SymConst;
attr->data.ent = get_SymConst_entity(cnst);
}
else {
attr->tp = imm_Const;
attr->data.tv = get_Const_tarval(cnst);
}
return res;
}
static void prepare_walker(ir_node *irn, void *data)
{
opcode opc = get_irn_opcode(irn);
/* A replacement for this node has already been computed. */
if(get_irn_link(irn))
return;
if(opc == iro_Call) {
ir_node *bl = get_nodes_block(irn);
ir_graph *irg = get_irn_irg(bl);
ir_node *ins[1];
ir_node *store = get_Call_mem(irn);
ir_node *ptr = get_Call_ptr(irn);
type *ct = get_Call_type(irn);
int np = get_Call_n_params(irn) > 0 ? 1 : 0;
if(np > 0) {
char buf[128];
ir_node *nc;
ir_node *push;
int i, n;
type *nt;
push = new_PushEnd(irg, bl, get_Call_param(irn, 0));
for(i = 1, n = get_Call_n_params(irn); i < n; ++i) {
push = new_Push(irg, bl, push, get_Call_param(irn, i));
}
snprintf(buf, sizeof(buf), "push_%s", get_type_name(ct));
n = get_method_n_ress(ct);
nt = new_type_method(new_id_from_str(buf), 1, n);
for(i = 0; i < n; ++i)
set_method_res_type(nt, i, get_method_res_type(ct, i));
set_method_param_type(nt, 0, push_type);
ins[0] = push;
nc = new_r_Call(irg, bl, store, ptr, 1, ins, nt);
exchange(irn, nc);
set_irn_link(nc, nc);
}
}
#if 0
else if(opc == iro_Const || opc == iro_SymConst) {
ir_node *bl = get_nodes_block(irn);
ir_graph *irg = get_irn_irg(bl);
ir_node *imm = new_Imm(irg, bl, irn);
exchange(irn, imm);
set_irn_link(imm, imm);
}
#endif
}
static void clear_link(ir_node *irn, void *data)
{
set_irn_link(irn, NULL);
}
static void firm_prepare_graph(ir_graph *irg)
{
irg_walk_graph(irg, clear_link, NULL, NULL);
irg_walk_graph(irg, NULL, prepare_walker, NULL);
}
const arch_isa_if_t firm_isa = {
firm_init,
firm_get_n_reg_class,
firm_get_reg_class,
firm_prepare_graph
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment