Commit 4ec0521f authored by Matthias Braun's avatar Matthias Braun
Browse files

implement sparc floatingpoint constants

[r27787]
parent b4e27346
...@@ -302,6 +302,7 @@ static void *sparc_cg_init(ir_graph *irg) ...@@ -302,6 +302,7 @@ static void *sparc_cg_init(ir_graph *irg)
cg->irg = irg; cg->irg = irg;
cg->isa = isa; cg->isa = isa;
cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) != 0; cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) != 0;
cg->constants = pmap_create();
/* enter the current code generator */ /* enter the current code generator */
isa->cg = cg; isa->cg = cg;
...@@ -618,31 +619,42 @@ static void sparc_get_call_abi(const void *self, ir_type *method_type, ...@@ -618,31 +619,42 @@ static void sparc_get_call_abi(const void *self, ir_type *method_type,
be_abi_call_set_flags(abi, call_flags, &sparc_abi_callbacks); be_abi_call_set_flags(abi, call_flags, &sparc_abi_callbacks);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
/* reg = get reg for param i; */ ir_type *type = get_method_param_type(method_type, i);
/* be_abi_call_param_reg(abi, i, reg); */ ir_mode *mode = get_type_mode(type);
/* pass outgoing params 0-5 via registers, remaining via stack */ if (mode_is_float(mode) || i >= 6) {
/* on sparc we need to set the ABI context since register names of parameters change to i0-i5 if we are the callee */ unsigned align = get_type_size_bytes(type);
if (i < 6) { be_abi_call_param_stack(abi, i, mode, align, 0, 0,
be_abi_call_param_reg(abi, i, sparc_get_RegParamOut_reg(i), ABI_CONTEXT_CALLER); ABI_CONTEXT_BOTH);
be_abi_call_param_reg(abi, i, sparc_get_RegParamIn_reg(i), ABI_CONTEXT_CALLEE); continue;
} else {
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); /*< stack args have no special context >*/
} }
/* pass integer params 0-5 via registers.
* On sparc we need to set the ABI context since register names of
* parameters change to i0-i5 if we are the callee */
be_abi_call_param_reg(abi, i, sparc_get_RegParamOut_reg(i),
ABI_CONTEXT_CALLER);
be_abi_call_param_reg(abi, i, sparc_get_RegParamIn_reg(i),
ABI_CONTEXT_CALLEE);
} }
/* set return value register: return value is in i0 resp. f0 */ n = get_method_n_ress(method_type);
if (get_method_n_ress(method_type) > 0) { /* more than 1 result not supported */
tp = get_method_res_type(method_type, 0); assert(n <= 1);
for (i = 0; i < n; ++i) {
tp = get_method_res_type(method_type, i);
mode = get_type_mode(tp); mode = get_type_mode(tp);
be_abi_call_res_reg(abi, 0, /* set return value register: return value is in i0 resp. f0 */
mode_is_float(mode) ? &sparc_fp_regs[REG_F0] : &sparc_gp_regs[REG_I0], ABI_CONTEXT_CALLEE); /*< return has no special context >*/ if (mode_is_float(mode)) {
be_abi_call_res_reg(abi, i, &sparc_fp_regs[REG_F0],
be_abi_call_res_reg(abi, 0, ABI_CONTEXT_BOTH);
mode_is_float(mode) ? &sparc_fp_regs[REG_F0] : &sparc_gp_regs[REG_O0], ABI_CONTEXT_CALLER); /*< return has no special context >*/ } else {
be_abi_call_res_reg(abi, i, &sparc_gp_regs[REG_I0],
ABI_CONTEXT_CALLEE);
be_abi_call_res_reg(abi, i, &sparc_gp_regs[REG_O0],
ABI_CONTEXT_CALLER);
}
} }
} }
......
...@@ -38,6 +38,7 @@ typedef struct sparc_code_gen_t { ...@@ -38,6 +38,7 @@ typedef struct sparc_code_gen_t {
sparc_isa_t *isa; /**< the isa instance */ sparc_isa_t *isa; /**< the isa instance */
bool dump; /**< set to 1 if graphs should bool dump; /**< set to 1 if graphs should
be dumped */ be dumped */
pmap *constants;
} sparc_code_gen_t; } sparc_code_gen_t;
struct sparc_isa_t { struct sparc_isa_t {
......
...@@ -503,4 +503,15 @@ FdTOi => { ...@@ -503,4 +503,15 @@ FdTOi => {
emit =>'. FdTOi %S1, %D1' emit =>'. FdTOi %S1, %D1'
}, },
Ldf => {
op_flags => [ "labeled", "fragile" ],
state => "exc_pinned",
ins => [ "ptr", "mem" ],
outs => [ "res", "M" ],
reg_req => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
attr_type => "sparc_load_store_attr_t",
attr => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
emit => '. ld [%S1%O], %D1'
},
); # end of %nodes ); # end of %nodes
...@@ -173,17 +173,6 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block) ...@@ -173,17 +173,6 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block)
return create_const_graph_value(dbgi, block, value); return create_const_graph_value(dbgi, block, value);
} }
/**
* create a DAG to load fp constant. sparc only supports loading from global memory
*/
static ir_node *create_fp_const_graph(ir_node *irn, ir_node *block)
{
(void) block;
(void) irn;
panic("FP constants not implemented");
}
typedef enum { typedef enum {
MATCH_NONE = 0, MATCH_NONE = 0,
MATCH_COMMUTATIVE = 1 << 0, MATCH_COMMUTATIVE = 1 << 0,
...@@ -557,6 +546,42 @@ static ir_node *gen_Minus(ir_node *node) ...@@ -557,6 +546,42 @@ static ir_node *gen_Minus(ir_node *node)
return new_bd_sparc_Minus(dbgi, block, new_op); return new_bd_sparc_Minus(dbgi, block, new_op);
} }
static ir_node *make_addr(dbg_info *dbgi, ir_entity *entity)
{
ir_node *block = get_irg_start_block(current_ir_graph);
ir_node *node = new_bd_sparc_SymConst(dbgi, block, entity);
be_dep_on_frame(node);
return node;
}
/**
* Create an entity for a given (floatingpoint) tarval
*/
static ir_entity *create_float_const_entity(tarval *tv)
{
ir_entity *entity = (ir_entity*) pmap_get(env_cg->constants, tv);
ir_initializer_t *initializer;
ir_mode *mode;
ir_type *type;
ir_type *glob;
if (entity != NULL)
return entity;
mode = get_tarval_mode(tv);
type = get_type_for_mode(mode);
glob = get_glob_type();
entity = new_entity(glob, id_unique("C%u"), type);
set_entity_visibility(entity, ir_visibility_private);
add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
initializer = create_initializer_tarval(tv);
set_entity_initializer(entity, initializer);
pmap_insert(env_cg->constants, tv, entity);
return entity;
}
/** /**
* Transforms a Const node. * Transforms a Const node.
* *
...@@ -567,12 +592,18 @@ static ir_node *gen_Const(ir_node *node) ...@@ -567,12 +592,18 @@ static ir_node *gen_Const(ir_node *node)
{ {
ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *block = be_transform_node(get_nodes_block(node));
ir_mode *mode = get_irn_mode(node); ir_mode *mode = get_irn_mode(node);
dbg_info *dbg = get_irn_dbg_info(node);
(void) dbg;
if (mode_is_float(mode)) { if (mode_is_float(mode)) {
return create_fp_const_graph(node, block); dbg_info *dbgi = get_irn_dbg_info(node);
tarval *tv = get_Const_tarval(node);
ir_entity *entity = create_float_const_entity(tv);
ir_node *addr = make_addr(dbgi, entity);
ir_node *mem = new_NoMem();
ir_node *new_op
= new_bd_sparc_Ldf(dbgi, block, addr, mem, mode, NULL, 0, 0, false);
ir_node *proj = new_Proj(new_op, mode, pn_sparc_Ldf_res);
return proj;
} }
return create_const_graph(node, block); return create_const_graph(node, block);
...@@ -806,14 +837,10 @@ static ir_node *gen_Cmp(ir_node *node) ...@@ -806,14 +837,10 @@ static ir_node *gen_Cmp(ir_node *node)
*/ */
static ir_node *gen_SymConst(ir_node *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); ir_entity *entity = get_SymConst_entity(node);
dbg_info *dbgi = get_irn_dbg_info(node); dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_node;
new_node = new_bd_sparc_SymConst(dbgi, block, entity); return make_addr(dbgi, entity);
be_dep_on_frame(new_node);
return new_node;
} }
/** /**
......
Markdown is supported
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