summaryrefslogtreecommitdiffhomepage
path: root/ir/be/bevarargs.c
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2016-09-27 09:04:16 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2016-09-27 09:05:41 +0200
commita24eac8cdb7f3c2b851a6c5c321a9a311298a254 (patch)
tree4e43f1f13ef742cc378a56b0ab0edff6bb0e0388 /ir/be/bevarargs.c
parent98b90d044b00eaced5871e5e9662389aa4febc98 (diff)
sparc: Correctly handle compound types as variadic parameters.
They are passed as a pointer, not the value itself, so an extra load is needed.
Diffstat (limited to 'ir/be/bevarargs.c')
-rw-r--r--ir/be/bevarargs.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/ir/be/bevarargs.c b/ir/be/bevarargs.c
index fc4d76e..1878bad 100644
--- a/ir/be/bevarargs.c
+++ b/ir/be/bevarargs.c
@@ -18,7 +18,7 @@
#include "irnode_t.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);
dbg_info *dbgi = get_irn_dbg_info(node);
@@ -31,7 +31,11 @@ void be_default_lower_va_arg(ir_node *node)
ir_mode *apmode = get_type_mode(aptype);
ir_node *res;
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);
res = new_r_Proj(load, apmode, pn_Load_res);
new_mem = new_r_Proj(load, mode_M,pn_Load_M);
@@ -51,3 +55,13 @@ void be_default_lower_va_arg(ir_node *node)
ir_node *const in[] = { new_mem, res, new_ap };
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);
+}