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 /* determine how function parameters and return values are passed. */
43 calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
44 ir_type *function_type)
47 reg_or_stackslot_t *params;
48 reg_or_stackslot_t *results;
50 = sizeof(param_regs)/sizeof(param_regs[0]);
52 = sizeof(result_regs)/sizeof(result_regs[0]);
53 int n_float_result_regs
54 = sizeof(float_result_regs)/sizeof(float_result_regs[0]);
60 calling_convention_t *cconv;
62 /* determine how parameters are passed */
63 n_params = get_method_n_params(function_type);
65 params = XMALLOCNZ(reg_or_stackslot_t, n_params);
67 for (i = 0; i < n_params; ++i) {
68 ir_type *param_type = get_method_param_type(function_type,i);
69 ir_mode *mode = get_type_mode(param_type);
70 int bits = get_mode_size_bits(mode);
71 reg_or_stackslot_t *param = ¶ms[i];
72 param->type = param_type;
74 if (regnum < n_param_regs) {
75 const arch_register_t *reg = param_regs[regnum++];
78 param->offset = stack_offset;
79 /* increase offset 4 bytes so everything is aligned */
80 stack_offset += bits > 32 ? bits/8 : 4;
84 /* we might need a 2nd 32bit component (for 64bit or double values) */
87 panic("only 32 and 64bit modes supported in arm backend");
89 if (regnum < n_param_regs) {
90 const arch_register_t *reg = param_regs[regnum++];
93 ir_mode *mode = param_regs[0]->reg_class->mode;
94 ir_type *type = get_type_for_mode(mode);
96 param->offset = stack_offset;
97 assert(get_mode_size_bits(mode) == 32);
103 n_results = get_method_n_ress(function_type);
106 results = XMALLOCNZ(reg_or_stackslot_t, n_results);
107 for (i = 0; i < n_results; ++i) {
108 ir_type *result_type = get_method_res_type(function_type, i);
109 ir_mode *result_mode = get_type_mode(result_type);
110 reg_or_stackslot_t *result = &results[i];
112 if (mode_is_float(result_mode)) {
113 if (float_regnum >= n_float_result_regs) {
114 panic("Too many float results for arm backend");
116 const arch_register_t *reg = float_result_regs[float_regnum++];
120 if (get_mode_size_bits(result_mode) > 32) {
121 panic("Results with more than 32bits not supported by arm backend yet");
124 if (regnum >= n_result_regs) {
125 panic("Too many results for arm backend");
127 const arch_register_t *reg = result_regs[regnum++];
133 cconv = XMALLOCZ(calling_convention_t);
134 cconv->parameters = params;
135 cconv->param_stack_size = stack_offset;
136 cconv->results = results;
138 /* setup allocatable registers */
140 be_irg_t *birg = be_birg_from_irg(irg);
141 size_t n_ignores = ARRAY_SIZE(ignore_regs);
142 struct obstack *obst = &birg->obst;
145 assert(birg->allocatable_regs == NULL);
146 birg->allocatable_regs = rbitset_obstack_alloc(obst, N_ARM_REGISTERS);
147 rbitset_set_all(birg->allocatable_regs, N_ARM_REGISTERS);
148 for (r = 0; r < n_ignores; ++r) {
149 rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
156 void arm_free_calling_convention(calling_convention_t *cconv)
158 free(cconv->parameters);
159 free(cconv->results);