Remove the very thin wrapper function arch_register_get_name().
[libfirm] / ir / be / sparc / sparc_stackframe.c
index 1ed784e..23283f4 100644 (file)
@@ -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 */
@@ -216,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);
@@ -259,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;
@@ -277,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);
 
@@ -301,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;
 
@@ -313,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);
 }