1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Default (pointer-based) implementation of variadic functions
* @author Andreas Fried
*/
#include "bevarargs.h"
#include "be_t.h"
#include "bitfiddle.h"
#include "ircons.h"
#include "irgmod.h"
#include "irnode_t.h"
#include "util.h"
void be_default_lower_va_arg(ir_node *const node, bool const compound_is_ptr,
unsigned const stack_param_align)
{
ir_node *block = get_nodes_block(node);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_graph *irg = get_irn_irg(node);
ir_type *aptype = get_method_res_type(get_Builtin_type(node), 0);
ir_node *const ap = get_irn_n(node, 1);
ir_node *const node_mem = get_Builtin_mem(node);
ir_mode *apmode = get_type_mode(aptype);
ir_node *res;
ir_node *new_mem;
if (apmode) {
goto load;
} else if (compound_is_ptr) {
apmode = mode_P;
aptype = get_type_for_mode(apmode);
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);
} else {
/* aptype has no associated mode, so it is represented as a pointer. */
res = ap;
new_mem = node_mem;
}
unsigned const round_up = round_up2(get_type_size(aptype),
stack_param_align);
ir_mode *const offset_mode = get_reference_offset_mode(mode_P);
ir_node *const offset = new_r_Const_long(irg, offset_mode, round_up);
ir_node *const new_ap = new_rd_Add(dbgi, block, ap, offset);
ir_node *const in[] = { new_mem, res, new_ap };
turn_into_tuple(node, ARRAY_SIZE(in), in);
}
ir_entity *be_make_va_start_entity(ir_type *const frame_type, int const offset)
{
ident *const id = new_id_from_str("$va_start");
ir_type *const unknown = get_unknown_type();
ir_entity *const va_start = new_entity(frame_type, id, unknown);
set_entity_offset(va_start, offset);
return va_start;
}
|