X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fsparc%2Fsparc_stackframe.c;h=23283f417850ced7fd1b72be3ac2d198955ba2eb;hb=96cdb5f8baa27173cbf79ef6983af4c42de1f9b6;hp=aa12f11259b881c95cbd7d11df8da7b8515fb9e7;hpb=06bb226000aca453df078d8320164d48b8f737a7;p=libfirm diff --git a/ir/be/sparc/sparc_stackframe.c b/ir/be/sparc/sparc_stackframe.c index aa12f1125..23283f417 100644 --- a/ir/be/sparc/sparc_stackframe.c +++ b/ir/be/sparc/sparc_stackframe.c @@ -21,7 +21,6 @@ * @file * @brief Manage addressing into the stackframe * @author Matthias Braun - * @version $Id$ */ #include "config.h" @@ -31,9 +30,9 @@ #include "sparc_new_nodes.h" #include "sparc_cconv.h" #include "bitfiddle.h" -#include "../bearch.h" -#include "../benode.h" -#include "../besched.h" +#include "bearch.h" +#include "benode.h" +#include "besched.h" static void set_irn_sp_bias(ir_node *node, int new_bias) { @@ -51,9 +50,6 @@ static void set_irn_sp_bias(ir_node *node, int new_bias) static void process_bias(ir_node *block, bool sp_relative, int bias, int free_bytes) { - const ir_edge_t *edge; - ir_node *irn; - mark_Block_block_visited(block); /* process schedule */ @@ -65,10 +61,18 @@ static void process_bias(ir_node *block, bool sp_relative, int bias, if (entity != NULL) { int offset = get_entity_offset(entity); if (sp_relative) - offset += bias; + offset += bias + SPARC_MIN_STACKSIZE; arch_set_frame_offset(irn, offset); } + /* The additional alignment bytes cannot be used + * anymore after alloca. */ + if (is_sparc_SubSP(irn)) { + free_bytes = 0; + } else if (is_sparc_AddSP(irn)) { + assert(free_bytes == 0); + } + irn_bias = arch_get_sp_bias(irn); if (irn_bias == 0) { /* do nothing */ @@ -116,6 +120,13 @@ static void adjust_entity_offsets(ir_type *type, long offset) } } +/** + * Perform some fixups for variadic functions. + * To make the rest of the frontend code easier to understand we add + * "dummy" parameters until the number of parameters transmitted in registers. + * (because otherwise the backend wouldn't store the value of the register + * parameters into memory for the VLA magic) + */ bool sparc_variadic_fixups(ir_graph *irg, calling_convention_t *cconv) { ir_entity *entity = get_irg_entity(irg); @@ -154,7 +165,7 @@ bool sparc_variadic_fixups(ir_graph *irg, calling_convention_t *cconv) set_method_variadicity(new_mtp, get_method_variadicity(mtp)); set_method_calling_convention(new_mtp, get_method_calling_convention(mtp)); set_method_additional_properties(new_mtp, get_method_additional_properties(mtp)); - set_lowered_type(mtp, new_mtp); + set_higher_type(new_mtp, mtp); set_entity_type(entity, new_mtp); } @@ -209,7 +220,7 @@ static ir_type *compute_arg_type(ir_graph *irg, calling_convention_t *cconv, if (param->reg0 != NULL) { /* use reserved spill space on between type */ if (entity != NULL) { - long offset = SPARC_PARAMS_SPILL_OFFSET + i*4; + long offset = SPARC_PARAMS_SPILL_OFFSET + i * SPARC_REGISTER_SIZE; assert(i < SPARC_N_PARAM_REGS); set_entity_owner(entity, between_type); set_entity_offset(entity, offset); @@ -226,7 +237,7 @@ static ir_type *compute_arg_type(ir_graph *irg, calling_convention_t *cconv, if (va_start_entity != NULL) { /* sparc_variadic_fixups() fiddled with our type, find out the * original number of parameters */ - ir_type *non_lowered = get_associated_type(mtp); + ir_type *non_lowered = get_higher_type(mtp); size_t orig_n_params = get_method_n_params(non_lowered); long offset; assert(get_method_variadicity(mtp) == variadicity_variadic); @@ -252,7 +263,11 @@ void sparc_create_stacklayout(ir_graph *irg, calling_convention_t *cconv) memset(layout, 0, sizeof(*layout)); between_type = new_type_class(new_id_from_str("sparc_between_type")); - set_type_size_bytes(between_type, SPARC_MIN_STACKSIZE); + if (cconv->omit_fp) { + set_type_size_bytes(between_type, 0); + } else { + set_type_size_bytes(between_type, SPARC_MIN_STACKSIZE); + } layout->frame_type = get_irg_frame_type(irg); layout->between_type = between_type; @@ -270,7 +285,7 @@ void sparc_create_stacklayout(ir_graph *irg, calling_convention_t *cconv) /* Assign entity offsets, to all stack-related entities. * The offsets are relative to the begin of the stack frame. */ -static void process_frame_types(ir_graph *irg) +void sparc_adjust_stack_entity_offsets(ir_graph *irg) { be_stack_layout_t *layout = be_get_irg_stack_layout(irg); @@ -294,8 +309,27 @@ static void process_frame_types(ir_graph *irg) ir_type *between_type = layout->between_type; unsigned between_size = get_type_size_bytes(between_type); - ir_type *frame_type = get_irg_frame_type(irg); - unsigned frame_size = get_type_size_bytes(frame_type); + ir_type *frame_type = get_irg_frame_type(irg); + unsigned frame_size = get_type_size_bytes(frame_type); + unsigned frame_align = get_type_alignment_bytes(frame_type); + + /* There's the tricky case of the stackframe size not being a multiple + * of the alignment. There are 2 variants: + * + * - frame-pointer relative addressing: + * Increase frame_size in case it is not a multiple of the alignment as we + * address entities from the "top" with negative offsets + * - stack-pointer relative addressing: + * Stackframesize + SPARC_MIN_STACK_SIZE has to be aligned. Increase + * frame_size accordingly. + */ + if (!layout->sp_relative) { + frame_size = (frame_size + frame_align-1) & ~(frame_align-1); + } else { + unsigned misalign = (SPARC_MIN_STACKSIZE+frame_size) % frame_align; + frame_size += misalign; + } + set_type_size_bytes(frame_type, frame_size); ir_type *arg_type = layout->arg_type; @@ -306,12 +340,12 @@ static void process_frame_types(ir_graph *irg) void sparc_fix_stack_bias(ir_graph *irg) { - ir_node *start_block = get_irg_start_block(irg); + bool sp_relative = be_get_irg_stack_layout(irg)->sp_relative; - process_frame_types(irg); + ir_node *start_block = get_irg_start_block(irg); ir_reserve_resources(irg, IR_RESOURCE_BLOCK_VISITED); inc_irg_block_visited(irg); - process_bias(start_block, be_get_irg_stack_layout(irg)->sp_relative, 0, 0); + process_bias(start_block, sp_relative, 0, 0); ir_free_resources(irg, IR_RESOURCE_BLOCK_VISITED); }