CACAO
md-abi.cpp
Go to the documentation of this file.
1 /* src/vm/jit/x86_64/md-abi.cpp - functions for x86_64 Linux ABI
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 #include "vm/types.hpp"
28 
29 #include "vm/jit/x86_64/md-abi.hpp"
30 
31 #include "vm/descriptor.hpp"
32 #include "vm/global.hpp"
33 #include "vm/method.hpp"
34 
35 #include "vm/jit/abi.hpp"
36 #include "vm/jit/code.hpp"
37 #include "vm/jit/jit.hpp" /* for REG_* (maybe can be removed) */
38 #include "vm/jit/stack.hpp"
39 
40 
41 /* register descripton array **************************************************/
42 
46  REG_END
47 };
48 
49 const char *abi_registers_integer_name[] = {
50  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
51  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
52 };
53 
55  7, /* a0 */
56  6, /* a1 */
57  2, /* a2 */
58  1, /* a3 */
59  8, /* a4 */
60  9, /* a5 */
61 };
62 
64  5, /* s0 */
65  12, /* s1 */
66  13, /* s2 */
67  14, /* s3 */
68  15, /* s4 */
69 };
70 
72  3, /* t0 */
73 };
74 
75 
76 /* float registers *************************************************************
77 
78  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
79  (fa0) (fa1) (fa2) (fa3) (fa4) (fa5) (fa6) (fa7)
80 
81  xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
82  (ftmp1) (ftmp2) (ftmp3) (ft0) (ft1) (ft2) (ft3) (ft4)
83 
84 *******************************************************************************/
85 
89  REG_END
90 };
91 
92 
94  0, /* fa0 */
95  1, /* fa1 */
96  2, /* fa2 */
97  3, /* fa3 */
98  4, /* fa4 */
99  5, /* fa5 */
100  6, /* fa6 */
101  7, /* fa7 */
102 };
103 
105  -1,
106 };
107 
109  11, /* ft0 */
110  12, /* ft1 */
111  13, /* ft2 */
112  14, /* ft3 */
113  15, /* ft4 */
114 };
115 
116 
117 /* md_param_alloc **************************************************************
118 
119  XXX
120 
121 *******************************************************************************/
122 
124 {
125  paramdesc *pd;
126  s4 i;
127  s4 iarg;
128  s4 farg;
129  s4 stacksize;
130 
131  /* set default values */
132 
133  iarg = 0;
134  farg = 0;
135  stacksize = 0;
136 
137  /* get params field of methoddesc */
138 
139  pd = md->params;
140 
141  for (i = 0; i < md->paramcount; i++, pd++) {
142  switch (md->paramtypes[i].type) {
143  case TYPE_INT:
144  case TYPE_ADR:
145  case TYPE_LNG:
146  if (iarg < INT_ARG_CNT) {
147  pd->inmemory = false;
148  pd->index = iarg;
150  iarg++;
151  }
152  else {
153  pd->inmemory = true;
154  pd->index = stacksize;
155  pd->regoff = stacksize * 8;
156  stacksize++;
157  }
158  break;
159 
160  case TYPE_FLT:
161  case TYPE_DBL:
162  if (farg < FLT_ARG_CNT) {
163  pd->inmemory = false;
164  pd->index = farg;
166  farg++;
167  }
168  else {
169  pd->inmemory = true;
170  pd->index = stacksize;
171  pd->regoff = stacksize * 8;
172  stacksize++;
173  }
174  break;
175  default:
176  assert(false);
177  break;
178  }
179  }
180 
181  /* Since XMM0 (==A0) is used for passing return values, this
182  argument register usage has to be regarded, too. */
183 
185  if (farg < 1)
186  farg = 1;
187 
188  /* fill register and stack usage */
189 
190  md->argintreguse = iarg;
191  md->argfltreguse = farg;
192  md->memuse = stacksize;
193 }
194 
195 
196 /* md_param_alloc_native *******************************************************
197 
198  Pre-allocate arguments according the native ABI.
199 
200 *******************************************************************************/
201 
203 {
204  /* On x86_64 we use the same ABI for JIT method calls as for
205  native method calls. */
206 
207  md_param_alloc(md);
208 }
209 
210 
211 /* md_return_alloc *************************************************************
212 
213  Precolor the Java Stackelement containing the Return Value. Only
214  for float/ double types straight forward possible, since INT_LNG
215  types use "reserved" registers Float/Double values use a00 as
216  return register.
217 
218  --- in
219  jd: jitdata of the current method
220  stackslot: Java Stackslot to contain the Return Value
221 
222  --- out
223  if precoloring was possible:
224  VAR(stackslot->varnum)->flags = PREALLOC
225  ->vv.regoff = [REG_RESULT|REG_FRESULT]
226  rd->arg[flt|int]reguse set to a value according the register usage
227 
228  NOTE: Do not pass a LOCALVAR in stackslot->varnum.
229 
230 *******************************************************************************/
231 
233 {
234  methodinfo *m;
235  codeinfo *code;
236  registerdata *rd;
237  methoddesc *md;
238 
239  /* get required compiler data */
240 
241  m = jd->m;
242  code = jd->code;
243  rd = jd->rd;
244 
245  md = m->parseddesc;
246 
247  /* precoloring only straightforward possible with flt/dbl types
248  For Address/Integer/Long REG_RESULT == rax == REG_ITMP1 and so
249  could be destroyed if the return value Stack Slot "lives too
250  long" */
251 
252  if (IS_FLT_DBL_TYPE(md->returntype.type)) {
253  /* In Leafmethods Local Vars holding parameters are precolored
254  to their argument register -> so leafmethods with
255  paramcount > 0 could already use a00! */
256 
257  if (!code_is_leafmethod(code) || (md->paramcount == 0)) {
258  /* Only precolor the stackslot, if it is not a SAVEDVAR
259  <-> has not to survive method invokations */
260 
261  if (!(stackslot->flags & SAVEDVAR)) {
262 
263  VAR(stackslot->varnum)->flags = PREALLOC;
264 
265  /* float/double */
266  if (rd->argfltreguse < 1)
267  rd->argfltreguse = 1;
268 
269  VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
270  }
271  }
272  }
273 }
274 
275 
276 /*
277  * These are local overrides for various environment variables in Emacs.
278  * Please do not remove this and leave it at the end of the file, where
279  * Emacs will automagically detect them.
280  * ---------------------------------------------------------------------
281  * Local variables:
282  * mode: c++
283  * indent-tabs-mode: t
284  * c-basic-offset: 4
285  * tab-width: 4
286  * End:
287  * vim:noexpandtab:sw=4:ts=4:
288  */
const s4 abi_registers_float_argument[]
Definition: md-abi.cpp:107
void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
Definition: md-abi.cpp:250
Definition: jit.hpp:126
paramdesc * params
Definition: descriptor.hpp:164
#define REG_SAV
Definition: jit.hpp:442
const s4 abi_registers_integer_argument[]
Definition: md-abi.cpp:64
codeinfo * code
Definition: jit.hpp:128
s4 nregdescint[]
Definition: md-abi.cpp:41
#define REG_FRESULT
Definition: md-abi.hpp:59
#define REG_END
Definition: jit.hpp:446
int32_t flags
Definition: stack.hpp:67
#define REG_RES
Definition: jit.hpp:439
const s4 abi_registers_integer_saved[]
Definition: md-abi.cpp:75
uint32_t index
Definition: descriptor.hpp:152
const s4 abi_registers_float_temporary[]
Definition: md-abi.cpp:129
#define VAR(i)
Definition: jit.hpp:252
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define REG_RET
Definition: jit.hpp:440
const s4 abi_registers_float_saved[]
Definition: md-abi.cpp:118
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
#define INT_ARG_CNT
Definition: md-abi.hpp:74
const s4 abi_registers_integer_temporary[]
Definition: md-abi.cpp:88
MIIterator i
typedesc returntype
Definition: descriptor.hpp:166
int32_t s4
Definition: types.hpp:45
int argfltreguse
Definition: reg.hpp:89
registerdata * rd
Definition: jit.hpp:130
void md_param_alloc(methoddesc *md)
Definition: md-abi.cpp:153
bool inmemory
Definition: descriptor.hpp:151
const char * abi_registers_integer_name[]
Definition: md-abi.cpp:57
void md_param_alloc_native(methoddesc *md)
Definition: md-abi.cpp:224
methoddesc * parseddesc
Definition: method.hpp:78
methodinfo * m
Definition: jit.hpp:127
#define FLT_ARG_CNT
Definition: md-abi.hpp:81
#define REG_ARG
Definition: jit.hpp:444
#define REG_TMP
Definition: jit.hpp:443
s4 nregdescfloat[]
Definition: md-abi.cpp:98
int32_t varnum
Definition: stack.hpp:69
uint32_t regoff
Definition: descriptor.hpp:153