#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)
{
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);
}
}
}
+/**
+ * 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);
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);
}
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);
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);
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;
void sparc_fix_stack_bias(ir_graph *irg)
{
+ bool sp_relative = be_get_irg_stack_layout(irg)->sp_relative;
+
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, 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);
}