Commit a24eac8c authored by Christoph Mallon's avatar Christoph Mallon
Browse files

sparc: Correctly handle compound types as variadic parameters.

They are passed as a pointer, not the value itself, so an extra load is needed.
parent 98b90d04
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "irnode_t.h" #include "irnode_t.h"
#include "util.h" #include "util.h"
void be_default_lower_va_arg(ir_node *node) static void be_default_lower_va_arg(ir_node *const node, bool const compound_is_ptr)
{ {
ir_node *block = get_nodes_block(node); ir_node *block = get_nodes_block(node);
dbg_info *dbgi = get_irn_dbg_info(node); dbg_info *dbgi = get_irn_dbg_info(node);
...@@ -31,7 +31,11 @@ void be_default_lower_va_arg(ir_node *node) ...@@ -31,7 +31,11 @@ void be_default_lower_va_arg(ir_node *node)
ir_mode *apmode = get_type_mode(aptype); ir_mode *apmode = get_type_mode(aptype);
ir_node *res; ir_node *res;
ir_node *new_mem; ir_node *new_mem;
if (apmode != NULL) { if (apmode) {
goto load;
} else if (compound_is_ptr) {
apmode = mode_P;
load:;
ir_node *const load = new_rd_Load(dbgi, block, node_mem, ap, apmode, aptype, cons_none); ir_node *const load = new_rd_Load(dbgi, block, node_mem, ap, apmode, aptype, cons_none);
res = new_r_Proj(load, apmode, pn_Load_res); res = new_r_Proj(load, apmode, pn_Load_res);
new_mem = new_r_Proj(load, mode_M,pn_Load_M); new_mem = new_r_Proj(load, mode_M,pn_Load_M);
...@@ -51,3 +55,13 @@ void be_default_lower_va_arg(ir_node *node) ...@@ -51,3 +55,13 @@ void be_default_lower_va_arg(ir_node *node)
ir_node *const in[] = { new_mem, res, new_ap }; ir_node *const in[] = { new_mem, res, new_ap };
turn_into_tuple(node, ARRAY_SIZE(in), in); turn_into_tuple(node, ARRAY_SIZE(in), in);
} }
void be_default_lower_va_arg_compound_ptr(ir_node *const node)
{
be_default_lower_va_arg(node, true);
}
void be_default_lower_va_arg_compound_val(ir_node *const node)
{
be_default_lower_va_arg(node, false);
}
...@@ -14,6 +14,17 @@ ...@@ -14,6 +14,17 @@
#include "firm_types.h" #include "firm_types.h"
/**
* Default implementation to lower a va_arg node.
*
* This implementation assumes that all arguments except compound types are
* stored on the stack and that the va_list value points to the next variadic
* argument. For compound types a pointer to the object is stored on the stack.
*
* @param node A Builtin node with kind ir_bk_va_arg to be lowered
*/
void be_default_lower_va_arg_compound_ptr(ir_node *node);
/** /**
* Default implementation to lower a va_arg node. * Default implementation to lower a va_arg node.
* *
...@@ -23,6 +34,6 @@ ...@@ -23,6 +34,6 @@
* *
* @param node A Builtin node with kind ir_bk_va_arg to be lowered * @param node A Builtin node with kind ir_bk_va_arg to be lowered
*/ */
void be_default_lower_va_arg(ir_node *node); void be_default_lower_va_arg_compound_val(ir_node *node);
#endif #endif
...@@ -1365,7 +1365,7 @@ static backend_params ia32_backend_params = { ...@@ -1365,7 +1365,7 @@ static backend_params ia32_backend_params = {
.float_int_overflow = ir_overflow_indefinite, .float_int_overflow = ir_overflow_indefinite,
.vararg = { .vararg = {
.va_list_type = NULL, /* will be set later */ .va_list_type = NULL, /* will be set later */
.lower_va_arg = be_default_lower_va_arg, .lower_va_arg = be_default_lower_va_arg_compound_val,
}, },
}; };
......
...@@ -543,7 +543,7 @@ static const backend_params *sparc_get_backend_params(void) ...@@ -543,7 +543,7 @@ static const backend_params *sparc_get_backend_params(void)
.float_int_overflow = ir_overflow_min_max, .float_int_overflow = ir_overflow_min_max,
.vararg = { .vararg = {
.va_list_type = NULL, /* will be set later */ .va_list_type = NULL, /* will be set later */
.lower_va_arg = be_default_lower_va_arg, .lower_va_arg = be_default_lower_va_arg_compound_ptr,
}, },
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment