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 */
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 */
/* 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);
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;
ir_node *start_block = get_irg_start_block(irg);
- process_frame_types(irg);
-
ir_reserve_resources(irg, IR_RESOURCE_BLOCK_VISITED);
inc_irg_block_visited(irg);
process_bias(start_block, sp_relative, 0, 0);