#include "config.h"
#include <stdint.h>
+#include <stdbool.h>
#include "irnode_t.h"
#include "irgraph_t.h"
//static ir_mode *mode_fp4;
static pmap *node_to_stack;
-static inline int mode_needs_gp_reg(ir_mode *mode)
+static inline bool mode_needs_gp_reg(ir_mode *mode)
{
- return mode_is_int(mode) || mode_is_reference(mode);
+ if (mode_is_int(mode) || mode_is_reference(mode)) {
+ /* we should only see 32bit code */
+ assert(get_mode_size_bits(mode) <= 32);
+ return true;
+ }
+ return false;
}
/**
}
mode1 = get_irn_mode(op1);
mode2 = get_irn_mode(op2);
+ /* we shouldn't see 64bit code */
+ assert(get_mode_size_bits(mode1) <= 32);
+ assert(get_mode_size_bits(mode2) <= 32);
if (is_imm_encodeable(op2)) {
ir_node *new_op1 = be_transform_node(op1);
ir_node *new_load = NULL;
address_t address;
+ if (get_Load_unaligned(node) == align_non_aligned) {
+ panic("sparc: transformation of unaligned Loads not implemented yet");
+ }
+
if (mode_is_float(mode)) {
match_address(ptr, &address, false);
new_load = create_ldf(dbgi, block, address.ptr, new_mem, mode,
ir_node *new_store = NULL;
address_t address;
+ if (get_Store_unaligned(node) == align_non_aligned) {
+ panic("sparc: transformation of unaligned Stores not implemented yet");
+ }
+
if (mode_is_float(mode)) {
/* TODO: variants with reg+reg address mode */
match_address(ptr, &address, false);
new_store = create_stf(dbgi, block, new_val, address.ptr, new_mem,
mode, address.entity, address.offset, false);
} else {
+ assert(get_mode_size_bits(mode) <= 32);
match_address(ptr, &address, true);
if (address.ptr2 != NULL) {
assert(address.entity == NULL && address.offset == 0);
layout->arg_type = arg_type;
layout->initial_offset = 0;
layout->initial_bias = 0;
- layout->stack_dir = -1;
layout->sp_relative = cconv->omit_fp;
assert(N_FRAME_TYPES == 3);
}
/**
- * transform the start node to the prolog code + initial barrier
+ * transform the start node to the prolog code
*/
static ir_node *gen_Start(ir_node *node)
{
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *mem;
ir_node *start;
- ir_node *sp;
+ir_node *sp;
size_t i;
/* stackpointer is important at function prolog */
}
start = be_prolog_create_start(abihelper, dbgi, new_block);
+#if 0
mem = be_prolog_get_memory(abihelper);
sp = be_prolog_get_reg_value(abihelper, sp_reg);
arch_irn_add_flags(save, arch_irn_flags_prolog);
arch_set_irn_register(save, sp_reg);
sp = save;
+ keep_alive(save);
}
sp = be_new_IncSP(sp_reg, new_block, sp, BE_STACK_FRAME_SIZE_EXPAND, 0);
arch_irn_add_flags(sp, arch_irn_flags_prolog);
be_prolog_set_reg_value(abihelper, sp_reg, sp);
be_prolog_set_memory(abihelper, mem);
+#endif
return start;
}
ir_node *new_mem = be_transform_node(mem);
ir_node *sp = get_stack_pointer_for(node);
size_t n_res = get_Return_n_ress(node);
- ir_node *barrier;
ir_node *bereturn;
size_t i;
}
}
+#if 0
/* we need a restore instruction */
if (!cconv->omit_fp) {
- ir_node *restore = new_bd_sparc_RestoreZero(NULL, block);
+ ir_node *fp = be_prolog_get_reg_value(abihelper, fp_reg);
+ ir_node *restore = new_bd_sparc_RestoreZero(NULL, block, fp);
arch_irn_add_flags(restore, arch_irn_flags_epilog);
- add_irn_dep(restore, barrier);
arch_set_irn_register(restore, sp_reg);
be_epilog_set_reg_value(abihelper, sp_reg, restore);
} else {
sp = be_epilog_get_reg_value(abihelper, sp_reg);
sp = be_new_IncSP(sp_reg, new_block, sp,
BE_STACK_FRAME_SIZE_SHRINK, 0);
+ arch_irn_add_flags(sp, arch_irn_flags_epilog);
be_epilog_set_reg_value(abihelper, sp_reg, sp);
}
+#endif
bereturn = be_epilog_create_return(abihelper, dbgi, new_block);
- arch_irn_add_flags(bereturn, arch_irn_flags_epilog);
-
return bereturn;
}
{
ir_node *block = get_nodes_block(node);
ir_node *new_block = be_transform_node(block);
- ir_node *barrier = be_transform_node(get_Proj_pred(node));
long pn = get_Proj_proj(node);
+ /* make sure prolog is constructed */
+ be_transform_node(get_Proj_pred(node));
switch ((pn_Start) pn) {
case pn_Start_X_initial_exec:
/* exchange ProjX with a jump */
return new_bd_sparc_Ba(NULL, new_block);
case pn_Start_M:
- return new_r_Proj(barrier, mode_M, 0);
+ return be_prolog_get_memory(abihelper);
case pn_Start_T_args:
- return barrier;
+ /* we should never need this explicitely */
+ return new_r_Bad(get_irn_irg(block));
case pn_Start_P_frame_base:
return get_frame_base();
- case pn_Start_P_tls:
- return new_r_Bad(current_ir_graph);
case pn_Start_max:
break;
}
case pn_Call_X_regular:
case pn_Call_X_except:
case pn_Call_T_result:
- case pn_Call_P_value_res_base:
case pn_Call_max:
break;
}
be_set_transform_function(op_sparc_Save, be_duplicate_node);
}
-/* hack to avoid unused fp proj at start barrier */
-static void assure_fp_keep(void)
-{
- unsigned n_users = 0;
- const ir_edge_t *edge;
- ir_node *fp_proj = be_prolog_get_reg_value(abihelper, fp_reg);
-
- foreach_out_edge(fp_proj, edge) {
- ir_node *succ = get_edge_src_irn(edge);
- if (is_End(succ) || is_Anchor(succ))
- continue;
- ++n_users;
- }
-
- if (n_users == 0) {
- ir_node *block = get_nodes_block(fp_proj);
- ir_node *in[1] = { fp_proj };
- be_new_Keep(block, 1, in);
- }
-}
-
/**
* Transform a Firm graph into a SPARC graph.
*/
create_stacklayout(irg);
be_transform_graph(irg, NULL);
- if (!cconv->omit_fp)
- assure_fp_keep();
be_abihelper_finish(abihelper);
sparc_free_calling_convention(cconv);