2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief calling convention helpers
23 * @author Matthias Braun
28 #include "arm_cconv.h"
35 static const unsigned ignore_regs[] = {
42 calling_convention_t *arm_decide_calling_convention(ir_graph *irg,
43 ir_type *function_type)
46 reg_or_stackslot_t *params;
47 reg_or_stackslot_t *results;
49 = sizeof(param_regs)/sizeof(param_regs[0]);
51 = sizeof(result_regs)/sizeof(result_regs[0]);
52 int n_float_result_regs
53 = sizeof(float_result_regs)/sizeof(float_result_regs[0]);
59 calling_convention_t *cconv;
61 /* determine how parameters are passed */
62 n_params = get_method_n_params(function_type);
64 params = XMALLOCNZ(reg_or_stackslot_t, n_params);
66 for (i = 0; i < n_params; ++i) {
67 ir_type *param_type = get_method_param_type(function_type,i);
68 ir_mode *mode = get_type_mode(param_type);
69 int bits = get_mode_size_bits(mode);
70 reg_or_stackslot_t *param = ¶ms[i];
71 param->type = param_type;
73 if (regnum < n_param_regs) {
74 const arch_register_t *reg = param_regs[regnum++];
77 param->offset = stack_offset;
78 /* increase offset 4 bytes so everything is aligned */
79 stack_offset += bits > 32 ? bits/8 : 4;
83 /* we might need a 2nd 32bit component (for 64bit or double values) */
86 panic("only 32 and 64bit modes supported in arm backend");
88 if (regnum < n_param_regs) {
89 const arch_register_t *reg = param_regs[regnum++];
92 ir_mode *mode = param_regs[0]->reg_class->mode;
93 ir_type *type = get_type_for_mode(mode);
95 param->offset = stack_offset;
96 assert(get_mode_size_bits(mode) == 32);
102 n_results = get_method_n_ress(function_type);
105 results = XMALLOCNZ(reg_or_stackslot_t, n_results);
106 for (i = 0; i < n_results; ++i) {
107 ir_type *result_type = get_method_res_type(function_type, i);
108 ir_mode *result_mode = get_type_mode(result_type);
109 reg_or_stackslot_t *result = &results[i];
111 if (mode_is_float(result_mode)) {
112 if (float_regnum >= n_float_result_regs) {
113 panic("Too many float results for arm backend");
115 const arch_register_t *reg = float_result_regs[float_regnum++];
119 if (get_mode_size_bits(result_mode) > 32) {
120 panic("Results with more than 32bits not supported by arm backend yet");
123 if (regnum >= n_result_regs) {
124 panic("Too many results for arm backend");
126 const arch_register_t *reg = result_regs[regnum++];
132 cconv = XMALLOCZ(calling_convention_t);
133 cconv->parameters = params;
134 cconv->param_stack_size = stack_offset;
135 cconv->results = results;
137 /* setup allocatable registers */
139 be_irg_t *birg = be_birg_from_irg(irg);
140 size_t n_ignores = ARRAY_SIZE(ignore_regs);
141 struct obstack *obst = &birg->obst;
144 assert(birg->allocatable_regs == NULL);
145 birg->allocatable_regs = rbitset_obstack_alloc(obst, N_ARM_REGISTERS);
146 rbitset_set_all(birg->allocatable_regs, N_ARM_REGISTERS);
147 for (r = 0; r < n_ignores; ++r) {
148 rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
155 void arm_free_calling_convention(calling_convention_t *cconv)
157 free(cconv->parameters);
158 free(cconv->results);