static beabi_helper_env_t *abihelper;
static const arch_register_t *sp_reg = &sparc_registers[REG_SP];
static const arch_register_t *fp_reg = &sparc_registers[REG_FRAME_POINTER];
-static calling_convention_t *cconv = NULL;
+static calling_convention_t *current_cconv = NULL;
static ir_mode *mode_gp;
static ir_mode *mode_flags;
static ir_mode *mode_fp;
//static ir_mode *mode_fp4;
static pmap *node_to_stack;
+static const arch_register_t *const caller_saves[] = {
+ &sparc_registers[REG_G1],
+ &sparc_registers[REG_G2],
+ &sparc_registers[REG_G3],
+ &sparc_registers[REG_G4],
+ &sparc_registers[REG_O0],
+ &sparc_registers[REG_O1],
+ &sparc_registers[REG_O2],
+ &sparc_registers[REG_O3],
+ &sparc_registers[REG_O4],
+ &sparc_registers[REG_O5],
+
+ &sparc_registers[REG_F0],
+ &sparc_registers[REG_F1],
+ &sparc_registers[REG_F2],
+ &sparc_registers[REG_F3],
+ &sparc_registers[REG_F4],
+ &sparc_registers[REG_F5],
+ &sparc_registers[REG_F6],
+ &sparc_registers[REG_F7],
+ &sparc_registers[REG_F8],
+ &sparc_registers[REG_F9],
+ &sparc_registers[REG_F10],
+ &sparc_registers[REG_F11],
+ &sparc_registers[REG_F12],
+ &sparc_registers[REG_F13],
+ &sparc_registers[REG_F14],
+ &sparc_registers[REG_F15],
+ &sparc_registers[REG_F16],
+ &sparc_registers[REG_F17],
+ &sparc_registers[REG_F18],
+ &sparc_registers[REG_F19],
+ &sparc_registers[REG_F20],
+ &sparc_registers[REG_F21],
+ &sparc_registers[REG_F22],
+ &sparc_registers[REG_F23],
+ &sparc_registers[REG_F24],
+ &sparc_registers[REG_F25],
+ &sparc_registers[REG_F26],
+ &sparc_registers[REG_F27],
+ &sparc_registers[REG_F28],
+ &sparc_registers[REG_F29],
+ &sparc_registers[REG_F30],
+ &sparc_registers[REG_F31],
+};
+
+static const arch_register_t *const omit_fp_callee_saves[] = {
+ &sparc_registers[REG_L0],
+ &sparc_registers[REG_L1],
+ &sparc_registers[REG_L2],
+ &sparc_registers[REG_L3],
+ &sparc_registers[REG_L4],
+ &sparc_registers[REG_L5],
+ &sparc_registers[REG_L6],
+ &sparc_registers[REG_L7],
+ &sparc_registers[REG_I0],
+ &sparc_registers[REG_I1],
+ &sparc_registers[REG_I2],
+ &sparc_registers[REG_I3],
+ &sparc_registers[REG_I4],
+ &sparc_registers[REG_I5],
+};
+
static inline bool mode_needs_gp_reg(ir_mode *mode)
{
if (mode_is_int(mode) || mode_is_reference(mode)) {
assert(get_mode_size_bits(mode2) <= 32);
if (is_imm_encodeable(op2)) {
- ir_node *new_op1 = be_transform_node(op1);
int32_t immediate = get_tarval_long(get_Const_tarval(op2));
+ new_op1 = be_transform_node(op1);
if (! (flags & MATCH_MODE_NEUTRAL) && needs_extension(mode1)) {
new_op1 = gen_extension(dbgi, block, new_op1, mode1);
}
assert(match_flags & MATCH_MODE_NEUTRAL);
if (is_imm_encodeable(op2)) {
- ir_node *new_op1 = be_transform_node(op1);
int32_t immediate = get_tarval_long(get_Const_tarval(op2));
+ new_op1 = be_transform_node(op1);
return new_binopx_imm(dbgi, block, new_op1, new_flags, NULL, immediate);
}
new_op2 = be_transform_node(op2);
return res;
}
-#if 0
-static ir_node *gen_Abs(ir_node *node)
-{
- ir_mode *const mode = get_irn_mode(node);
-
- if (mode_is_float(mode)) {
- return gen_helper_unfpop(node, mode, new_bd_sparc_fabs_s,
- new_bd_sparc_fabs_d, new_bd_sparc_fabs_q);
- } else {
- ir_node *const block = be_transform_node(get_nodes_block(node));
- dbg_info *const dbgi = get_irn_dbg_info(node);
- ir_node *const op = get_Abs_op(node);
- ir_node *const new_op = be_transform_node(op);
- ir_node *const sra = new_bd_sparc_Sra_imm(dbgi, block, new_op, NULL, 31);
- ir_node *const xor = new_bd_sparc_Xor_reg(dbgi, block, new_op, sra);
- ir_node *const sub = new_bd_sparc_Sub_reg(dbgi, block, xor, sra);
- return sub;
- }
-}
-#endif
-
/**
* Transforms a Not node.
*
long default_pn = get_Cond_default_proj(node);
ir_entity *entity;
ir_node *table_address;
- ir_node *index;
+ ir_node *idx;
ir_node *load;
ir_node *address;
set_entity_visibility(entity, ir_visibility_private);
add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
- /* TODO: this code does not construct code to check for access
- * out-of bounds of the jumptable yet. I think we should put this stuff
- * into the switch_lowering phase to get some additional optimisations
- * done. */
-
/* construct base address */
table_address = make_address(dbgi, block, entity, 0);
/* scale index */
- index = new_bd_sparc_Sll_imm(dbgi, block, new_selector, NULL, 2);
+ idx = new_bd_sparc_Sll_imm(dbgi, block, new_selector, NULL, 2);
/* load from jumptable */
- load = new_bd_sparc_Ld_reg(dbgi, block, table_address, index,
+ load = new_bd_sparc_Ld_reg(dbgi, block, table_address, idx,
get_irg_no_mem(current_ir_graph),
mode_gp);
address = new_r_Proj(load, mode_gp, pn_sparc_Ld_res);
ir_node *op = get_Conv_op(node);
ir_mode *src_mode = get_irn_mode(op);
ir_mode *dst_mode = get_irn_mode(node);
- dbg_info *dbg = get_irn_dbg_info(node);
+ dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_op;
int src_bits = get_mode_size_bits(src_mode);
if (mode_is_float(src_mode)) {
if (mode_is_float(dst_mode)) {
/* float -> float conv */
- return create_fftof(dbg, block, new_op, src_mode, dst_mode);
+ return create_fftof(dbgi, block, new_op, src_mode, dst_mode);
} else {
/* float -> int conv */
if (!mode_is_signed(dst_mode))
panic("float to unsigned not implemented yet");
- return create_ftoi(dbg, block, new_op, src_mode);
+ return create_ftoi(dbgi, block, new_op, src_mode);
}
} else {
/* int -> float conv */
if (src_bits < 32) {
- new_op = gen_extension(dbg, block, new_op, src_mode);
+ new_op = gen_extension(dbgi, block, new_op, src_mode);
} else if (src_bits == 32 && !mode_is_signed(src_mode)) {
panic("unsigned to float not lowered!");
}
- return create_itof(dbg, block, new_op, dst_mode);
+ return create_itof(dbgi, block, new_op, dst_mode);
}
} else if (src_mode == mode_b) {
panic("ConvB not lowered %+F", node);
}
if (mode_is_signed(min_mode)) {
- return gen_sign_extension(dbg, block, new_op, min_bits);
+ return gen_sign_extension(dbgi, block, new_op, min_bits);
} else {
- return gen_zero_extension(dbg, block, new_op, min_bits);
+ return gen_zero_extension(dbgi, block, new_op, min_bits);
}
}
}
static ir_type *between_type = NULL;
static ir_type *between_type0 = NULL;
- if (cconv->omit_fp) {
+ if (current_cconv->omit_fp) {
if (between_type0 == NULL) {
between_type0
= new_type_class(new_id_from_str("sparc_between_type"));
int n_params;
/* calling conventions must be decided by now */
- assert(cconv != NULL);
+ assert(current_cconv != NULL);
/* construct argument type */
arg_type = new_type_struct(id_mangle_u(get_entity_ident(entity), new_id_from_chars("arg_type", 8)));
n_params = get_method_n_params(function_type);
for (p = 0; p < n_params; ++p) {
- reg_or_stackslot_t *param = &cconv->parameters[p];
+ reg_or_stackslot_t *param = ¤t_cconv->parameters[p];
char buf[128];
ident *id;
layout->arg_type = arg_type;
layout->initial_offset = 0;
layout->initial_bias = 0;
- layout->sp_relative = cconv->omit_fp;
+ layout->sp_relative = current_cconv->omit_fp;
assert(N_FRAME_TYPES == 3);
layout->order[0] = layout->frame_type;
arch_register_req_type_ignore);
/* function parameters in registers */
for (i = 0; i < get_method_n_params(function_type); ++i) {
- const reg_or_stackslot_t *param = &cconv->parameters[i];
+ const reg_or_stackslot_t *param = ¤t_cconv->parameters[i];
if (param->reg0 != NULL) {
be_prolog_add_reg(abihelper, param->reg0,
arch_register_req_type_none);
}
/* we need the values of the callee saves (Note: non omit-fp mode has no
* callee saves) */
- if (cconv->omit_fp) {
+ if (current_cconv->omit_fp) {
size_t n_callee_saves = ARRAY_SIZE(omit_fp_callee_saves);
size_t c;
for (c = 0; c < n_callee_saves; ++c) {
for (i = 0; i < n_res; ++i) {
ir_node *res_value = get_Return_res(node, i);
ir_node *new_res_value = be_transform_node(res_value);
- const reg_or_stackslot_t *slot = &cconv->results[i];
+ const reg_or_stackslot_t *slot = ¤t_cconv->results[i];
const arch_register_t *reg = slot->reg0;
assert(slot->reg1 == NULL);
be_epilog_add_reg(abihelper, reg, arch_register_req_type_none,
new_res_value);
}
/* callee saves */
- if (cconv->omit_fp) {
+ if (current_cconv->omit_fp) {
size_t n_callee_saves = ARRAY_SIZE(omit_fp_callee_saves);
- size_t i;
for (i = 0; i < n_callee_saves; ++i) {
const arch_register_t *reg = omit_fp_callee_saves[i];
ir_node *value
dbg_info *dbgi = get_irn_dbg_info(node);
ir_type *type = get_Call_type(node);
size_t n_params = get_Call_n_params(node);
- size_t n_param_regs = sizeof(param_regs)/sizeof(param_regs[0]);
/* max inputs: memory, callee, register arguments */
- int max_inputs = 2 + n_param_regs;
- ir_node **in = ALLOCAN(ir_node*, max_inputs);
ir_node **sync_ins = ALLOCAN(ir_node*, n_params);
struct obstack *obst = be_get_be_obst(irg);
- const arch_register_req_t **in_req
- = OALLOCNZ(obst, const arch_register_req_t*, max_inputs);
calling_convention_t *cconv
= sparc_decide_calling_convention(type, NULL);
+ size_t n_param_regs = cconv->n_param_regs;
+ /* param-regs + mem + stackpointer + callee */
+ unsigned max_inputs = 3 + n_param_regs;
+ ir_node **in = ALLOCAN(ir_node*, max_inputs);
+ const arch_register_req_t **in_req
+ = OALLOCNZ(obst, const arch_register_req_t*, max_inputs);
int in_arity = 0;
int sync_arity = 0;
int n_caller_saves
set_irn_pinned(str, op_pin_state_floats);
sync_ins[sync_arity++] = str;
}
- assert(in_arity <= max_inputs);
/* construct memory input */
if (sync_arity == 0) {
in_req[in_arity] = sparc_reg_classes[CLASS_sparc_gp].class_req;
++in_arity;
}
+ assert(in_arity <= (int)max_inputs);
/* outputs:
* - memory
static ir_node *get_frame_base(void)
{
- const arch_register_t *reg = cconv->omit_fp ? sp_reg : fp_reg;
+ const arch_register_t *reg = current_cconv->omit_fp ? sp_reg : fp_reg;
return be_prolog_get_reg_value(abihelper, reg);
}
return new_r_Bad(get_irn_irg(block), mode_T);
case pn_Start_P_frame_base:
return get_frame_base();
- case pn_Start_max:
- break;
}
panic("Unexpected start proj: %ld\n", pn);
}
/* Proj->Proj->Start must be a method argument */
assert(get_Proj_proj(get_Proj_pred(node)) == pn_Start_T_args);
- param = &cconv->parameters[pn];
+ param = ¤t_cconv->parameters[pn];
if (param->reg0 != NULL) {
/* argument transmitted in register */
case pn_Call_X_regular:
case pn_Call_X_except:
case pn_Call_T_result:
- case pn_Call_max:
break;
}
panic("Unexpected Call proj %ld\n", pn);
abihelper = be_abihelper_prepare(irg);
be_collect_stacknodes(abihelper);
- cconv = sparc_decide_calling_convention(get_entity_type(entity), irg);
+ current_cconv
+ = sparc_decide_calling_convention(get_entity_type(entity), irg);
create_stacklayout(irg);
be_transform_graph(irg, NULL);
be_abihelper_finish(abihelper);
- sparc_free_calling_convention(cconv);
+ sparc_free_calling_convention(current_cconv);
frame_type = get_irg_frame_type(irg);
if (get_type_state(frame_type) == layout_undefined)