CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/powerpc64/codegen.cpp - machine code generator for 64-bit PowerPC
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 
28 #include <cassert>
29 #include <cstdio>
30 #include <stdint.h>
31 #include <signal.h>
32 
33 #include "vm/types.hpp"
34 
35 #include "md-abi.hpp"
36 
39 
40 #include "mm/memory.hpp"
41 
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
44 
45 #include "threads/lock.hpp"
46 
47 #include "vm/descriptor.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/field.hpp"
50 #include "vm/global.hpp"
51 #include "vm/loader.hpp"
52 #include "vm/options.hpp"
53 #include "vm/vm.hpp"
54 
55 #include "vm/jit/abi.hpp"
56 #include "vm/jit/abi-asm.hpp"
57 #include "vm/jit/builtin.hpp"
58 #include "vm/jit/asmpart.hpp"
60 #include "vm/jit/dseg.hpp"
61 #include "vm/jit/emit-common.hpp"
62 #include "vm/jit/jit.hpp"
64 #include "vm/jit/parse.hpp"
66 #include "vm/jit/reg.hpp"
67 #include "vm/jit/stacktrace.hpp"
68 #include "vm/jit/trap.hpp"
69 
70 
71 /**
72  * Generates machine code for the method prolog.
73  */
75 {
76  varinfo* var;
77  methoddesc* md;
78  int32_t s1;
79  int32_t p, t, l;
80  int32_t varindex;
81  int i;
82 
83  // Get required compiler data.
84  methodinfo* m = jd->m;
85  codeinfo* code = jd->code;
86  codegendata* cd = jd->cd;
87  registerdata* rd = jd->rd;
88 
89  if (!code_is_leafmethod(code)) {
92  }
93 
94  if (cd->stackframesize)
95  M_STDU(REG_SP, REG_SP, -cd->stackframesize * 8);
96 
97  /* save return address and used callee saved registers */
98 
99  p = cd->stackframesize;
100  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
101  p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
102  }
103  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
104  p --; M_DST(rd->savfltregs[i], REG_SP, p * 8);
105  }
106 
107  /* take arguments out of register or stack frame */
108 
109  md = m->parseddesc;
110 
111  for (p = 0, l = 0; p < md->paramcount; p++) {
112  t = md->paramtypes[p].type;
113  varindex = jd->local_map[l*5 + t];
114  l++;
115  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
116  l++;
117  if (varindex == jitdata::UNUSED)
118  continue;
119 
120  var = VAR(varindex);
121  s1 = md->params[p].regoff;
122 
123  if (IS_INT_LNG_TYPE(t)) {
124  if (!md->params[p].inmemory) {
125  if (!IS_INMEMORY(var->flags))
126  M_INTMOVE(s1, var->vv.regoff);
127  else
128  M_LST(s1, REG_SP, var->vv.regoff);
129  }
130  else {
131  if (!IS_INMEMORY(var->flags))
132  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
133  else
134  var->vv.regoff = cd->stackframesize * 8 + s1;
135  }
136  }
137  else {
138  if (!md->params[p].inmemory) {
139  if (!IS_INMEMORY(var->flags))
140  emit_fmove(cd, s1, var->vv.regoff);
141  else
142  if (IS_2_WORD_TYPE(t))
143  M_DST(s1, REG_SP, var->vv.regoff);
144  else
145  M_FST(s1, REG_SP, var->vv.regoff);
146  }
147  else {
148  if (!(var->flags & INMEMORY)) {
149  if (IS_2_WORD_TYPE(t))
150  M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
151  else
152  M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
153  }
154  else
155  var->vv.regoff = cd->stackframesize * 8 + s1;
156  }
157  }
158  }
159 }
160 
161 
162 /**
163  * Generates machine code for the method epilog.
164  */
166 {
167  int32_t p;
168  int i;
169 
170  // Get required compiler data.
171  codeinfo* code = jd->code;
172  codegendata* cd = jd->cd;
173  registerdata* rd = jd->rd;
174 
175  p = cd->stackframesize;
176 
177  /* restore return address */
178 
179  if (!code_is_leafmethod(code)) {
180  /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
181  may have a displacement overflow. */
182 
183  M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
184  M_MTLR(REG_ITMP1);
185  }
186 
187  /* restore saved registers */
188 
189  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
190  p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
191  }
192  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
193  p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
194  }
195 
196  /* deallocate stack */
197 
198  if (cd->stackframesize)
199  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
200 
201  M_RET;
202 }
203 
204 
205 /**
206  * Generates machine code for one ICMD.
207  */
209 {
210  varinfo* var;
211  builtintable_entry* bte;
212  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
213  unresolved_method* um;
214  fieldinfo* fi;
215  unresolved_field* uf = NULL; // prevent warning
216  int32_t fieldtype;
217  int32_t s1, s2, s3, d;
218  int32_t disp;
219 
220  // Get required compiler data.
221  codeinfo* code = jd->code;
222  codegendata* cd = jd->cd;
223 
224  switch (iptr->opc) {
225 
226  /* constant operations ************************************************/
227 
228  case ICMD_FCONST: /* ... ==> ..., constant */
229 
230  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
231  disp = dseg_add_float(cd, iptr->sx.val.f);
232  M_FLD(d, REG_PV, disp);
233  emit_store_dst(jd, iptr, d);
234  break;
235 
236  case ICMD_DCONST: /* ... ==> ..., constant */
237 
238  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
239  disp = dseg_add_double(cd, iptr->sx.val.d);
240  M_DLD(d, REG_PV, disp);
241  emit_store_dst(jd, iptr, d);
242  break;
243 
244  case ICMD_ACONST: /* ... ==> ..., constant */
245 
246  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
247 
248  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
249  disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref);
251  iptr->sx.val.c.ref,
252  disp);
253  } else {
254  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
255  }
256  M_ALD(d, REG_PV, disp);
257  emit_store_dst(jd, iptr, d);
258  break;
259 
260 
261  /* integer operations *************************************************/
262 
263  case ICMD_INEG: /* ..., value ==> ..., - value */
264  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
265  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
266  M_NEG(s1, d);
267  M_EXTSW(d, d);
268  emit_store_dst(jd, iptr, d);
269  break;
270 
271  case ICMD_LNEG:
272  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
273  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
274  M_NEG(s1, d);
275  emit_store_dst(jd, iptr, d);
276  break;
277 
278 
279  case ICMD_I2L: /* ..., value ==> ..., value */
280 
281  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
282  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
283  M_INTMOVE(s1, d);
284  emit_store_dst(jd, iptr, d);
285  break;
286 
287  case ICMD_L2I: /* ..., value ==> ..., value */
288 
289  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
290  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
291  M_ISEXT(s1, d);
292  emit_store_dst(jd, iptr, d);
293  break;
294 
295  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
296 
297  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
298  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
299  M_BSEXT(s1, d);
300  emit_store_dst(jd, iptr, d);
301  break;
302 
303  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
304 
305  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
306  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
307  M_CZEXT(s1, d);
308  emit_store_dst(jd, iptr, d);
309  break;
310 
311  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
312 
313  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
314  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
315  M_SSEXT(s1, d);
316  emit_store_dst(jd, iptr, d);
317  break;
318 
319 
320  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
321 
322  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
323  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
324  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
325  M_IADD(s1, s2, d);
326  M_EXTSW(d,d);
327  emit_store_dst(jd, iptr, d);
328  break;
329 
330  case ICMD_IINC:
331  case ICMD_IADDCONST:
332 
333  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
334  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
335  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
336  M_IADD_IMM(s1, iptr->sx.val.i, d);
337  } else {
338  ICONST(REG_ITMP2, iptr->sx.val.i);
339  M_IADD(s1, REG_ITMP2, d);
340  }
341  M_EXTSW(d,d);
342  emit_store_dst(jd, iptr, d);
343  break;
344 
345  case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
346 
347  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
348  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
349  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
350  M_LADD(s1, s2, d);
351  emit_store_dst(jd, iptr, d);
352  break;
353 
354  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
355  /* sx.val.l = constant */
356 
357  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
358  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
359  /* XXX check me */
360  if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
361  M_LADD_IMM(s1, iptr->sx.val.l, d);
362  } else {
363  LCONST(REG_ITMP2, iptr->sx.val.l);
364  M_LADD(s1, REG_ITMP2, d);
365  }
366  emit_store_dst(jd, iptr, d);
367  break;
368 
369  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
370 
371  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
372  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
373  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
374  M_SUB(s1, s2, d);
375  M_EXTSW(d, d);
376  emit_store_dst(jd, iptr, d);
377  break;
378 
379  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
380  /* sx.val.i = constant */
381 
382  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
383  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
384  if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
385  M_IADD_IMM(s1, -iptr->sx.val.i, d);
386  } else {
387  ICONST(REG_ITMP2, iptr->sx.val.i);
388  M_SUB(s1, REG_ITMP2, d);
389  }
390  M_EXTSW(d, d);
391  emit_store_dst(jd, iptr, d);
392  break;
393 
394  case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
395 
396  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
397  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
398  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
399  M_SUB(s1, s2, d);
400  emit_store_dst(jd, iptr, d);
401  break;
402 
403  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
404  /* sx.val.l = constant */
405 
406  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
407  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
408  /* XXX check me */
409  if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767)) {
410  M_LADD_IMM(s1, -iptr->sx.val.l, d);
411  } else {
412  LCONST(REG_ITMP2, iptr->sx.val.l);
413  M_SUB(s1, REG_ITMP2, d);
414  }
415  emit_store_dst(jd, iptr, d);
416  break;
417 
418  case ICMD_IDIV:
419  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
420  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
421  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
422  emit_arithmetic_check(cd, iptr, s2);
423 
424  M_DIV(s1, s2, d);
425  M_EXTSW(d, d);
426  emit_store_dst(jd, iptr, d);
427  break;
428 
429  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
430 
431  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
432  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
433  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
434  emit_arithmetic_check(cd, iptr, s2);
435 
436  M_DIV(s1, s2, d);
437  /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
438  /* we only need to check this if we did a LDIV, not for IDIV */
440  M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2); /* test OV */
441  M_BLE(1);
442  M_MOV(s1, d); /* java specs says result == dividend */
443  emit_store_dst(jd, iptr, d);
444  break;
445 
446  case ICMD_IREM:
447  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
448  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
449  emit_arithmetic_check(cd, iptr, s2);
450 
451  M_DIV(s1, s2, REG_ITMP3);
452  M_MUL(REG_ITMP3, s2, REG_ITMP2);
453  M_SUB(s1, REG_ITMP2, REG_ITMP3);
454  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
455 
456  M_MOV(REG_ITMP3, d);
457  emit_store_dst(jd, iptr, d);
458  break;
459 
460 
461  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
462  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
463  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
464  emit_arithmetic_check(cd, iptr, s2);
465 
466  M_DIV(s1, s2, REG_ITMP3);
467  /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
468  /* we only need to check this if we did a LDIV, not for IDIV */
470  M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2); /* test OV */
471  M_BLE(2);
472  LCONST(REG_ITMP3, 0); /* result == 0 in this case */
473  M_BR(2 + (s2==REG_ITMP2));
474  /* might require a reload */
475  emit_load_s2(jd, iptr, REG_ITMP2);
476  M_MUL(REG_ITMP3, s2, REG_ITMP2);
477  M_SUB(s1, REG_ITMP2, REG_ITMP3);
478  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
479 
480  M_MOV(REG_ITMP3, d);
481  emit_store_dst(jd, iptr, d);
482  break;
483 
484 
485  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
486  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
488  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
489  M_MUL(s1, s2, d);
490  M_EXTSW(d, d);
491  emit_store_dst(jd, iptr, d);
492  break;
493 
494  case ICMD_LMUL:
495  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
496  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
497  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
498  M_MUL(s1, s2, d);
499  emit_store_dst(jd, iptr, d);
500  break;
501 
502  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
503  /* sx.val.i = constant */
504 
505  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
507  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
508  M_MUL_IMM(s1, iptr->sx.val.i, d);
509  else {
510  ICONST(REG_ITMP3, iptr->sx.val.i);
511  M_MUL(s1, REG_ITMP3, d);
512  }
513  M_EXTSW(d, d);
514  emit_store_dst(jd, iptr, d);
515  break;
516  case ICMD_LMULCONST:
517  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519  if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767))
520  M_MUL_IMM(s1, iptr->sx.val.l, d);
521  else {
522  LCONST(REG_ITMP3, iptr->sx.val.l);
523  M_MUL(s1, REG_ITMP3, d);
524  }
525  emit_store_dst(jd, iptr, d);
526  break;
527 
528  case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
529 
530  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
532  M_SRA_IMM(s1, iptr->sx.val.i, d);
533  M_ADDZE(d, d);
534  M_EXTSW(d, d);
535  emit_store_dst(jd, iptr, d);
536  break;
537 
538  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
539 
540  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
542  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543  M_AND_IMM(s2, 0x1f, REG_ITMP3);
544  M_SLL(s1, REG_ITMP3, d);
545  M_EXTSW(d, d);
546  emit_store_dst(jd, iptr, d);
547  break;
548 
549  case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
550  /* sx.val.i = constant */
551 
552  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
554  M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
555  M_EXTSW(d,d);
556  emit_store_dst(jd, iptr, d);
557  break;
558 
559  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
560 
561  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
563  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564  M_AND_IMM(s2, 0x1f, REG_ITMP3);
565  M_SRA(s1, REG_ITMP3, d);
566  emit_store_dst(jd, iptr, d);
567  break;
568 
569  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
570  /* sx.val.i = constant */
571 
572  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
573  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
574  M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
575  emit_store_dst(jd, iptr, d);
576  break;
577 
578  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
579 
580  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
582  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
583  M_AND_IMM(s2, 0x1f, REG_ITMP2);
584  M_MOV(s1, REG_ITMP1);
587  M_EXTSW(d,d); /* for the case it was shift 0 bits */
588  emit_store_dst(jd, iptr, d);
589  break;
590 
591  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
592  /* sx.val.i = constant */
593 
594  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596  if (iptr->sx.val.i & 0x1f) {
597  M_MOV(s1, REG_ITMP1);
599  M_SRA_IMM(REG_ITMP1, iptr->sx.val.i & 0x1f, d);
600  } else {
601  M_INTMOVE(s1, d);
602  }
603  emit_store_dst(jd, iptr, d);
604  break;
605 
606  case ICMD_LSHLCONST:
607  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
609  M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
610  emit_store_dst(jd, iptr, d);
611  break;
612  case ICMD_LSHL:
613  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
615  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
616  M_AND_IMM(s2, 0x3f, REG_ITMP2);
617  M_SLL(s1, REG_ITMP2, d);
618  emit_store_dst(jd, iptr, d);
619  break;
620  case ICMD_LSHRCONST:
621  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623  M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
624  emit_store_dst(jd, iptr, d);
625  break;
626  case ICMD_LSHR:
627  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630  M_AND_IMM(s2, 0x3f, REG_ITMP2);
631  M_SRA(s1, REG_ITMP2, d);
632  emit_store_dst(jd, iptr, d);
633  break;
634  case ICMD_LUSHRCONST:
635  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
636  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
637  M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
638  emit_store_dst(jd, iptr, d);
639  break;
640  case ICMD_LUSHR:
641  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
643  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644  M_AND_IMM(s2, 0x3f, REG_ITMP2);
645  M_SRL(s1, REG_ITMP2, d);
646  emit_store_dst(jd, iptr, d);
647  break;
648 
649  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
650  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
652  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
653  M_AND(s1, s2, d);
654 /* M_EXTSW(d, d);*/
655  emit_store_dst(jd, iptr, d);
656  break;
657 
658  case ICMD_LAND:
659  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
661  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
662  M_AND(s1, s2, d);
663  emit_store_dst(jd, iptr, d);
664  break;
665 
666  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
667  /* sx.val.i = constant */
668 
669  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
671  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535)) {
672  M_AND_IMM(s1, iptr->sx.val.i, d);
673  }
674  /*
675  else if (iptr->sx.val.i == 0xffffff) {
676  M_RLWINM(s1, 0, 8, 31, d);
677  }
678  */
679  else {
680  ICONST(REG_ITMP3, iptr->sx.val.i);
681  M_AND(s1, REG_ITMP3, d);
682  }
683  emit_store_dst(jd, iptr, d);
684  break;
685 
686  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
687  /* sx.val.l = constant */
688 
689  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
691  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
692  M_AND_IMM(s1, iptr->sx.val.l, d);
693  /*
694  else if (iptr->sx.val.l == 0xffffff) {
695  M_RLWINM(s1, 0, 8, 31, d);
696  }
697  */
698  else {
699  LCONST(REG_ITMP3, iptr->sx.val.l);
700  M_AND(s1, REG_ITMP3, d);
701  }
702  emit_store_dst(jd, iptr, d);
703  break;
704 
705  case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
706  /* sx.val.i = constant */
707  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709 #if 0
710  /* fast division, result in REG_ITMP3) */
711  M_SRA_IMM(s1, iptr->sx.val.i, REG_ITMP3);
713 
714  M_SUB(s1, REG_ITMP3, d);
715  M_EXTSW(d, d);
716  emit_store_dst(jd, iptr, d);
717  break;
718 #else
719 
720  M_MOV(s1, REG_ITMP2);
721  M_CMPI(s1, 0);
722  M_BGE(1 + 3*(iptr->sx.val.i >= 32768));
723  if (iptr->sx.val.i >= 32768) {
724  M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
726  M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
727  M_IADD(s1, REG_ITMP2, REG_ITMP2);
728  } else {
729  M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
730  }
731  {
732  int b=0, m = iptr->sx.val.i;
733  while (m >>= 1)
734  ++b;
735  M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
736  }
737  M_SUB(s1, REG_ITMP2, d);
738  M_EXTSW(d, d);
739  emit_store_dst(jd, iptr, d);
740  break;
741 #endif
742 
743  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
744  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
745  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
746  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
747  M_OR(s1, s2, d);
748 /* M_EXTSW(d,d);*/
749  emit_store_dst(jd, iptr, d);
750  break;
751 
752  case ICMD_LOR:
753 
754  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
755  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
756  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
757  M_OR(s1, s2, d);
758  emit_store_dst(jd, iptr, d);
759  break;
760 
761  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
762  /* sx.val.i = constant */
763 
764  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
767  M_OR_IMM(s1, iptr->sx.val.i, d);
768  else {
769  ICONST(REG_ITMP3, iptr->sx.val.i);
770  M_OR(s1, REG_ITMP3, d);
771  }
772  emit_store_dst(jd, iptr, d);
773  break;
774 
775  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
776  /* sx.val.l = constant */
777 
778  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
780  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
781  M_OR_IMM(s1, iptr->sx.val.l, d);
782  else {
783  LCONST(REG_ITMP3, iptr->sx.val.l);
784  M_OR(s1, REG_ITMP3, d);
785  }
786  emit_store_dst(jd, iptr, d);
787  break;
788 
789 
790  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
791  case ICMD_LXOR:
792 
793  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
794  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
795  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
796  M_XOR(s1, s2, d);
797  emit_store_dst(jd, iptr, d);
798  break;
799 
800  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
801  /* sx.val.i = constant */
802 
803  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
806  M_XOR_IMM(s1, iptr->sx.val.i, d);
807  else {
808  ICONST(REG_ITMP3, iptr->sx.val.i);
809  M_XOR(s1, REG_ITMP3, d);
810  }
811  emit_store_dst(jd, iptr, d);
812  break;
813 
814  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
815  /* sx.val.l = constant */
816 
817  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
819  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 65535))
820  M_XOR_IMM(s1, iptr->sx.val.l, d);
821  else {
822  LCONST(REG_ITMP3, iptr->sx.val.l);
823  M_XOR(s1, REG_ITMP3, d);
824  }
825  emit_store_dst(jd, iptr, d);
826  break;
827 
828  case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
829 
830  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
832  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
833  /* XXX implement me!!! */
834  vm_abort("codegen: implement ICMD_LCMP!");
835  emit_store_dst(jd, iptr, d);
836  break;
837  break;
838 
839 
840  /* floating operations ************************************************/
841 
842  case ICMD_FNEG: /* ..., value ==> ..., - value */
843 
844  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
845  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
846  M_FMOVN(s1, d);
847  emit_store_dst(jd, iptr, d);
848  break;
849 
850  case ICMD_DNEG: /* ..., value ==> ..., - value */
851 
852  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
853  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
854  M_FMOVN(s1, d);
855  emit_store_dst(jd, iptr, d);
856  break;
857 
858  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
859 
860  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
861  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
862  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
863  M_FADD(s1, s2, d);
864  emit_store_dst(jd, iptr, d);
865  break;
866 
867  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
868 
869  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
870  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
871  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
872  M_DADD(s1, s2, d);
873  emit_store_dst(jd, iptr, d);
874  break;
875 
876  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
877 
878  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
879  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
880  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
881  M_FSUB(s1, s2, d);
882  emit_store_dst(jd, iptr, d);
883  break;
884 
885  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
886 
887  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
888  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
889  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
890  M_DSUB(s1, s2, d);
891  emit_store_dst(jd, iptr, d);
892  break;
893 
894  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
895 
896  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
897  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
898  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
899  M_FMUL(s1, s2, d);
900  emit_store_dst(jd, iptr, d);
901  break;
902 
903  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
904 
905  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
906  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
907  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
908  M_DMUL(s1, s2, d);
909  emit_store_dst(jd, iptr, d);
910  break;
911 
912  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
913 
914  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
915  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
916  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
917  M_FDIV(s1, s2, d);
918  emit_store_dst(jd, iptr, d);
919  break;
920 
921  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
922 
923  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
924  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
925  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
926  M_DDIV(s1, s2, d);
927  emit_store_dst(jd, iptr, d);
928  break;
929 
930  case ICMD_F2I: /* ..., value ==> ..., (int) value */
931  case ICMD_D2I:
932 
933  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
934  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
935  M_CLR(d);
936  disp = dseg_add_float(cd, 0.0);
937  M_FLD(REG_FTMP2, REG_PV, disp);
938  M_FCMPU(s1, REG_FTMP2);
939  M_BNAN(4);
940  disp = dseg_add_unique_s4(cd, 0);
941  M_CVTDL_C(s1, REG_FTMP1);
942  M_LDA(REG_ITMP1, REG_PV, disp);
944  M_ILD(d, REG_PV, disp);
945  emit_store_dst(jd, iptr, d);
946  break;
947 
948  case ICMD_F2D: /* ..., value ==> ..., (double) value */
949 
950  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
951  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
952  emit_fmove(cd, s1, d);
953  emit_store_dst(jd, iptr, d);
954  break;
955 
956  case ICMD_D2F: /* ..., value ==> ..., (double) value */
957 
958  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
959  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
960  M_CVTDF(s1, d);
961  emit_store_dst(jd, iptr, d);
962  break;
963 
964  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
965  case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
966 
967  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
968  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
969  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
970  M_FCMPU(s2, s1);
971  M_IADD_IMM(REG_ZERO, -1, d);
972  M_BNAN(4);
973  M_BGT(3);
974  M_IADD_IMM(REG_ZERO, 0, d);
975  M_BGE(1);
976  M_IADD_IMM(REG_ZERO, 1, d);
977  emit_store_dst(jd, iptr, d);
978  break;
979 
980  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
981  case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
982 
983  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
984  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
985  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
986  M_FCMPU(s1, s2);
987  M_IADD_IMM(REG_ZERO, 1, d);
988  M_BNAN(4);
989  M_BGT(3);
990  M_IADD_IMM(REG_ZERO, 0, d);
991  M_BGE(1);
992  M_IADD_IMM(REG_ZERO, -1, d);
993  emit_store_dst(jd, iptr, d);
994  break;
995 
996 
997  /* memory operations **************************************************/
998 
999  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1000 
1001  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1003  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1004  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1005  M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1006  /* implicit null-pointer check */
1007  M_LBZX(d, s1, REG_ITMP2);
1008  M_BSEXT(d, d);
1009  emit_store_dst(jd, iptr, d);
1010  break;
1011 
1012  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1013 
1014  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1016  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1017  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1018  M_SLL_IMM(s2, 1, REG_ITMP2);
1020  /* implicit null-pointer check */
1021  M_LHZX(d, s1, REG_ITMP2);
1022  emit_store_dst(jd, iptr, d);
1023  break;
1024 
1025  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1026 
1027  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1029  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1030  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1031  M_SLL_IMM(s2, 1, REG_ITMP2);
1033  /* implicit null-pointer check */
1034  M_LHAX(d, s1, REG_ITMP2);
1035  emit_store_dst(jd, iptr, d);
1036  break;
1037 
1038  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1039 
1040  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1042  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1044  M_SLL_IMM(s2, 2, REG_ITMP2);
1046  /* implicit null-pointer check */
1047  M_LWAX(d, s1, REG_ITMP2);
1048  emit_store_dst(jd, iptr, d);
1049  break;
1050 
1051  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1052 
1053  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1056  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1057  M_SLL_IMM(s2, 3, REG_ITMP2);
1058  M_IADD(s1, REG_ITMP2, REG_ITMP2);
1059  /* implicit null-pointer check */
1061  emit_store_dst(jd, iptr, d);
1062  break;
1063 
1064  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1065 
1066  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1068  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1069  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1070  M_SLL_IMM(s2, 2, REG_ITMP2);
1072  /* implicit null-pointer check */
1073  M_LFSX(d, s1, REG_ITMP2);
1074  emit_store_dst(jd, iptr, d);
1075  break;
1076 
1077  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1078 
1079  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1080  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1081  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1082  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1083  M_SLL_IMM(s2, 3, REG_ITMP2);
1085  /* implicit null-pointer check */
1086  M_LFDX(d, s1, REG_ITMP2);
1087  emit_store_dst(jd, iptr, d);
1088  break;
1089 
1090  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1091 
1092  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1094  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1096  M_SLL_IMM(s2, 3, REG_ITMP2);
1098  /* implicit null-pointer check */
1099  M_ALDX(d, s1, REG_ITMP2);
1100  emit_store_dst(jd, iptr, d);
1101  break;
1102 
1103 
1104  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1105 
1106  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1107  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1108  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1109  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1110  M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1111  /* implicit null-pointer check */
1112  M_STBX(s3, s1, REG_ITMP2);
1113  break;
1114 
1115  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1116 
1117  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1119  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1120  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1121  M_SLL_IMM(s2, 1, REG_ITMP2);
1123  /* implicit null-pointer check */
1124  M_STHX(s3, s1, REG_ITMP2);
1125  break;
1126 
1127  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1128 
1129  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1131  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1132  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1133  M_SLL_IMM(s2, 1, REG_ITMP2);
1135  M_STHX(s3, s1, REG_ITMP2);
1136  break;
1137 
1138  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1139 
1140  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1143  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1144  M_SLL_IMM(s2, 2, REG_ITMP2);
1146  /* implicit null-pointer check */
1147  M_STWX(s3, s1, REG_ITMP2);
1148  break;
1149 
1150  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1151 
1152  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1153  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1154  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1155  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1156  M_SLL_IMM(s2, 3, REG_ITMP2);
1158  /* implicit null-pointer check */
1159  M_LSTX(s3, s1, REG_ITMP2);
1160  break;
1161 
1162  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1163 
1164  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1165  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1166  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1167  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1168  M_SLL_IMM(s2, 2, REG_ITMP2);
1170  /* implicit null-pointer check */
1171  M_STFSX(s3, s1, REG_ITMP2);
1172  break;
1173 
1174  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1175 
1176  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1177  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1178  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1179  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1180  M_SLL_IMM(s2, 3, REG_ITMP2);
1182  /* implicit null-pointer check */
1183  M_STFDX(s3, s1, REG_ITMP2);
1184  break;
1185 
1186  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1187 
1188  s1 = emit_load_s1(jd, iptr, REG_A0);
1189  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1190  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1191  s3 = emit_load_s3(jd, iptr, REG_A1);
1192 
1194  M_ALD(REG_ITMP3, REG_PV, disp);
1195  M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
1196  M_MTCTR(REG_ITMP3);
1197 
1198  M_INTMOVE(s1, REG_A0);
1199  M_INTMOVE(s3, REG_A1);
1200 
1201  M_JSR;
1202  emit_arraystore_check(cd, iptr);
1203 
1204  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1205  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1206  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1207  M_SLL_IMM(s2, 3, REG_ITMP2);
1209  /* implicit null-pointer check */
1210  M_ASTX(s3, s1, REG_ITMP2);
1211  break;
1212 
1213  case ICMD_GETFIELD: /* ... ==> ..., value */
1214 
1215  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1216 
1217  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1218  uf = iptr->sx.s23.s3.uf;
1219  fieldtype = uf->fieldref->parseddesc.fd->type;
1220  disp = 0;
1221 
1223  }
1224  else {
1225  fi = iptr->sx.s23.s3.fmiref->p.field;
1226  fieldtype = fi->type;
1227  disp = fi->offset;
1228  }
1229 
1230  /* implicit null-pointer check */
1231  switch (fieldtype) {
1232  case TYPE_INT:
1233  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1234  M_ILD(d, s1, disp);
1235  break;
1236  case TYPE_LNG:
1237  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1238  M_LLD(d, s1, disp);
1239  break;
1240  case TYPE_ADR:
1241  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1242  M_ALD(d, s1, disp);
1243  break;
1244  case TYPE_FLT:
1245  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1246  M_FLD(d, s1, disp);
1247  break;
1248  case TYPE_DBL:
1249  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1250  M_DLD(d, s1, disp);
1251  break;
1252  default:
1253  assert(false);
1254  break;
1255  }
1256  emit_store_dst(jd, iptr, d);
1257  break;
1258 
1259  case ICMD_PUTFIELD: /* ..., value ==> ... */
1260 
1261  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1262 
1263  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1264  uf = iptr->sx.s23.s3.uf;
1265  fieldtype = uf->fieldref->parseddesc.fd->type;
1266  disp = 0;
1267  }
1268  else {
1269  fi = iptr->sx.s23.s3.fmiref->p.field;
1270  fieldtype = fi->type;
1271  disp = fi->offset;
1272  }
1273 
1274  if (IS_INT_LNG_TYPE(fieldtype)) {
1275  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1276  }
1277  else
1278  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1279 
1280  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1282  }
1283 
1284 
1285  /* implicit null-pointer check */
1286  switch (fieldtype) {
1287  case TYPE_INT:
1288  M_IST(s2, s1, disp);
1289  break;
1290  case TYPE_LNG:
1291  M_LST(s2, s1, disp);
1292  break;
1293  case TYPE_ADR:
1294  M_AST(s2, s1, disp);
1295  break;
1296  case TYPE_FLT:
1297  M_FST(s2, s1, disp);
1298  break;
1299  case TYPE_DBL:
1300  M_DST(s2, s1, disp);
1301  break;
1302  default:
1303  assert(false);
1304  break;
1305  }
1306  break;
1307 
1308 
1309  /* branch operations **************************************************/
1310 
1311  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1312 
1314  break;
1315 
1316  case ICMD_IF_LEQ: /* ..., value ==> ... */
1317  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1318  LCONST(REG_ITMP2, iptr->sx.val.l);
1319  M_CMP(s1, REG_ITMP2);
1320  emit_beq(cd, iptr->dst.block);
1321  break;
1322  case ICMD_IF_LLT: /* ..., value ==> ... */
1323  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324  LCONST(REG_ITMP2, iptr->sx.val.l);
1325  M_CMP(s1, REG_ITMP2);
1326  emit_blt(cd, iptr->dst.block);
1327  break;
1328  case ICMD_IF_LLE: /* ..., value ==> ... */
1329  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330  LCONST(REG_ITMP2, iptr->sx.val.l);
1331  M_CMP(s1, REG_ITMP2);
1332  emit_ble(cd, iptr->dst.block);
1333  break;
1334 
1335  case ICMD_IF_LNE: /* ..., value ==> ... */
1336  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337  LCONST(REG_ITMP2, iptr->sx.val.l);
1338  M_CMP(s1, REG_ITMP2);
1339  emit_bne(cd, iptr->dst.block);
1340  break;
1341  case ICMD_IF_LGE: /* ..., value ==> ... */
1342  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1343  LCONST(REG_ITMP2, iptr->sx.val.l);
1344  M_CMP(s1, REG_ITMP2);
1345  emit_bge(cd, iptr->dst.block);
1346  break;
1347  case ICMD_IF_LGT: /* ..., value ==> ... */
1348  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1349  LCONST(REG_ITMP2, iptr->sx.val.l);
1350  M_CMP(s1, REG_ITMP2);
1351  emit_bgt(cd, iptr->dst.block);
1352  break;
1353  case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1354 
1355  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1356  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1357  M_CMP(s1, s2);
1358  emit_beq(cd, iptr->dst.block);
1359  break;
1360 
1361  case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1362 
1363  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365  M_CMP(s1, s2);
1366  emit_bne(cd, iptr->dst.block);
1367  break;
1368 
1369 
1370  case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1371 
1372  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1373  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1374  M_CMP(s1, s2);
1375  emit_blt(cd, iptr->dst.block);
1376  break;
1377 
1378  case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1379 
1380  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1381  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1382  M_CMP(s1, s2);
1383  emit_bgt(cd, iptr->dst.block);
1384  break;
1385 
1386  case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1387 
1388  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1389  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1390  M_CMP(s1, s2);
1391  emit_ble(cd, iptr->dst.block);
1392  break;
1393 
1394  case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1395 
1396  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398  M_CMP(s1, s2);
1399  emit_bge(cd, iptr->dst.block);
1400  break;
1401 
1402  case ICMD_TABLESWITCH: /* ..., index ==> ... */
1403  {
1404  s4 i, l;
1405  branch_target_t *table;
1406 
1407  table = iptr->dst.table;
1408 
1409  l = iptr->sx.s23.s2.tablelow;
1410  i = iptr->sx.s23.s3.tablehigh;
1411 
1412  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1413  if (l == 0) {
1414  M_INTMOVE(s1, REG_ITMP1);
1415  } else if (l <= 32768) {
1416  M_LDA(REG_ITMP1, s1, -l);
1417  } else {
1418  ICONST(REG_ITMP2, l);
1419  M_SUB(s1, REG_ITMP2, REG_ITMP1);
1420  }
1421 
1422  /* number of targets */
1423  i = i - l + 1;
1424 
1425  /* range check */
1426 
1427  M_CMPUI(REG_ITMP1, i - 1);
1428  emit_bgt(cd, table[0].block);
1429 
1430  /* build jump table top down and use address of lowest entry */
1431 
1432  table += i;
1433 
1434  while (--i >= 0) {
1435  dseg_add_target(cd, table->block);
1436  --table;
1437  }
1438 
1439  /* length of dataseg after last dseg_add_unique_target is used by load */
1440 
1443  M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1444  M_MTCTR(REG_ITMP2);
1445  M_RTS;
1446  ALIGNCODENOP;
1447  }
1448  break;
1449 
1450 
1451  case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1452  bte = iptr->sx.s23.s3.bte;
1453  if (bte->stub == NULL) {
1454  disp = dseg_add_functionptr(cd, bte->fp);
1455  M_ALD(REG_PV, REG_PV, disp);
1456  M_ALD(REG_PV, REG_PV, 0); /* TOC */
1457  }
1458  else {
1459  disp = dseg_add_functionptr(cd, bte->stub);
1460  M_ALD(REG_PV, REG_PV, disp);
1461  }
1462 
1463  /* generate the actual call */
1464  M_MTCTR(REG_PV);
1465  M_JSR;
1466  break;
1467 
1468  case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1469  emit_nullpointer_check(cd, iptr, REG_A0);
1470  /* fall through */
1471 
1472  case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1473  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1474  um = iptr->sx.s23.s3.um;
1475  disp = dseg_add_unique_address(cd, um);
1476 
1478  um, disp);
1479  } else {
1480  lm = iptr->sx.s23.s3.fmiref->p.method;
1481  disp = dseg_add_address(cd, lm->stubroutine);
1482  }
1483  M_ALD(REG_PV, REG_PV, disp);
1484 
1485  /* generate the actual call */
1486 
1487  M_MTCTR(REG_PV);
1488  M_JSR;
1489  break;
1490 
1491  case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1492  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1493  um = iptr->sx.s23.s3.um;
1495  s1 = 0;
1496  } else {
1497  lm = iptr->sx.s23.s3.fmiref->p.method;
1498  s1 = OFFSET(vftbl_t, table[0]) +
1499  sizeof(methodptr) * lm->vftblindex;
1500  }
1501 
1502  /* implicit null-pointer check */
1504  M_ALD(REG_PV, REG_METHODPTR, s1);
1505 
1506  /* generate the actual call */
1507 
1508  M_MTCTR(REG_PV);
1509  M_JSR;
1510  break;
1511 
1512  case ICMD_INVOKEINTERFACE:
1513  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1514  um = iptr->sx.s23.s3.um;
1516 
1517  s1 = 0;
1518  s2 = 0;
1519 
1520  } else {
1521  lm = iptr->sx.s23.s3.fmiref->p.method;
1522  s1 = OFFSET(vftbl_t, interfacetable[0]) -
1523  sizeof(methodptr*) * lm->clazz->index;
1524 
1525  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1526  }
1527 
1528  /* implicit null-pointer check */
1531  M_ALD(REG_PV, REG_METHODPTR, s2);
1532 
1533  /* generate the actual call */
1534 
1535  M_MTCTR(REG_PV);
1536  M_JSR;
1537  break;
1538 
1539  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1540  /* val.a: (classinfo*) superclass */
1541 
1542  /* superclass is an interface:
1543  *
1544  * OK if ((sub == NULL) ||
1545  * (sub->vftbl->interfacetablelength > super->index) &&
1546  * (sub->vftbl->interfacetable[-super->index] != NULL));
1547  *
1548  * superclass is a class:
1549  *
1550  * OK if ((sub == NULL) || (0
1551  * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1552  * super->vftbl->diffvall));
1553  */
1554 
1555  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1556  /* object type cast-check */
1557 
1558  classinfo *super;
1559  s4 superindex;
1560 
1561  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1562  super = NULL;
1563  superindex = 0;
1564  }
1565  else {
1566  super = iptr->sx.s23.s3.c.cls;
1567  superindex = super->index;
1568  }
1569 
1570  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1571 
1572  /* if class is not resolved, check which code to call */
1573 
1574  if (super == NULL) {
1575  M_TST(s1);
1576  emit_label_beq(cd, BRANCH_LABEL_1);
1577  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
1578 
1581  iptr->sx.s23.s3.c.ref,
1582  disp);
1583 
1584  M_ILD(REG_ITMP2, REG_PV, disp);
1586 
1587  emit_label_beq(cd, BRANCH_LABEL_2);
1588  }
1589 
1590  /* interface checkcast code */
1591 
1592  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1593  if (super == NULL) {
1596  iptr->sx.s23.s3.c.ref,
1597  0);
1598  } else {
1599  M_TST(s1);
1600  emit_label_beq(cd, BRANCH_LABEL_3);
1601  }
1602 
1603  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1604  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1605  M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
1606  emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1608  OFFSET(vftbl_t, interfacetable[0]) -
1609  superindex * sizeof(methodptr*));
1610  M_TST(REG_ITMP3);
1611  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1612 
1613  if (super == NULL) {
1615  } else {
1617  }
1618  }
1619 
1620  /* class checkcast code */
1621 
1622  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1623  if (super == NULL) {
1625 
1626  disp = dseg_add_unique_address(cd, NULL);
1628  iptr->sx.s23.s3.c.ref,
1629  disp);
1630  } else {
1631  disp = dseg_add_address(cd, super->vftbl);
1632  M_TST(s1);
1633  emit_label_beq(cd, BRANCH_LABEL_5);
1634  }
1635 
1636  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1637  M_ALD(REG_ITMP3, REG_PV, disp);
1638 
1639  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1640  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1642  M_ALD(REG_ITMP1, REG_ITMP1, 0);
1644  emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1645 
1646  if (super == NULL) {
1647  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1648  M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
1649  emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1650  }
1651 
1652  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1653  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
1655  emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1656  /* reload */
1657  M_ALD(REG_ITMP3, REG_PV, disp);
1658  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1659 
1661  M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*8, REG_ITMP2);
1664  emit_label_beq(cd, BRANCH_LABEL_7); /* good */
1665 
1667  if (super == NULL)
1669 
1670  /* reload s1, might have been destroyed */
1671  emit_load_s1(jd, iptr, REG_ITMP1);
1673 
1676  /* reload s1, might have been destroyed */
1677  emit_load_s1(jd, iptr, REG_ITMP1);
1678  }
1679  else {
1680  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
1682  emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP2, s1);
1683  }
1684 
1685  if (super != NULL)
1687  }
1688 
1689  if (super == NULL) {
1692  }
1693  d = codegen_reg_of_dst(jd, iptr, s1);
1694 
1695  } else {
1696  /* array type cast-check */
1697 
1698  s1 = emit_load_s1(jd, iptr, REG_A0);
1699  M_INTMOVE(s1, REG_A0);
1700 
1701 
1702  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1703  disp = dseg_add_unique_address(cd, NULL);
1705  iptr->sx.s23.s3.c.ref,
1706  disp);
1707  } else {
1708  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
1709  }
1710 
1711  M_ALD(REG_A1, REG_PV, disp);
1713  M_ALD(REG_ITMP2, REG_PV, disp);
1714  M_ALD(REG_ITMP2, REG_ITMP2, 0); /* TOC */
1715  M_MTCTR(REG_ITMP2);
1716  M_JSR;
1717  M_TST(REG_RESULT);
1718  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1720 
1721  d = codegen_reg_of_dst(jd, iptr, s1);
1722  }
1723  M_INTMOVE(s1, d);
1724  emit_store_dst(jd, iptr, d);
1725  break;
1726 
1727 
1728  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1729  /* val.a: (classinfo*) superclass */
1730 
1731  /* superclass is an interface:
1732  *
1733  * return (sub != NULL) &&
1734  * (sub->vftbl->interfacetablelength > super->index) &&
1735  * (sub->vftbl->interfacetable[-super->index] != NULL);
1736  *
1737  * superclass is a class:
1738  *
1739  * return ((sub != NULL) && (0
1740  * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1741  * super->vftbl->diffvall));
1742  */
1743 
1744  {
1745  classinfo *super;
1746  s4 superindex;
1747 
1748  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1749  super = NULL;
1750  superindex = 0;
1751  }
1752  else {
1753  super = iptr->sx.s23.s3.c.cls;
1754  superindex = super->index;
1755  }
1756 
1757  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1758  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1759  if (s1 == d) {
1760  M_MOV(s1, REG_ITMP1);
1761  s1 = REG_ITMP1;
1762  }
1763 
1764  /* if class is not resolved, check which code to call */
1765 
1766  if (super == NULL) {
1767  M_TST(s1);
1768  M_CLR(d);
1769  emit_label_beq(cd, BRANCH_LABEL_1);
1770  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
1771 
1773  iptr->sx.s23.s3.c.ref, disp);
1774 
1775  M_ILD(REG_ITMP3, REG_PV, disp);
1777  emit_label_beq(cd, BRANCH_LABEL_2);
1778  }
1779 
1780  /* interface instanceof code */
1781 
1782  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1783  if (super == NULL) {
1784  /* If d == REG_ITMP2, then it's destroyed in check
1785  code above. */
1786  if (d == REG_ITMP2)
1787  M_CLR(d);
1788 
1791  iptr->sx.s23.s3.c.ref, 0);
1792 
1793  } else {
1794  M_TST(s1);
1795  M_CLR(d);
1796  emit_label_beq(cd, BRANCH_LABEL_3);
1797  }
1798 
1799  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
1800  M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
1801  M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
1802  M_BLE(3);
1804  OFFSET(vftbl_t, interfacetable[0]) -
1805  superindex * sizeof(methodptr*));
1806  /* This seems to be the canonical sequence to emulate
1807  * the Alpha instruction M_CMPULT(zero,x) (check for non-null). */
1808  M_ADDIC(REG_ITMP1, -1, d);
1809  M_SUBE(REG_ITMP1, d, d);
1810 
1811  if (super == NULL) {
1813  } else {
1815  }
1816  }
1817 
1818  /* class instanceof code */
1819 
1820  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1821 
1822  if (super == NULL) {
1824 
1825  disp = dseg_add_unique_address(cd, NULL);
1827  iptr->sx.s23.s3.c.ref,
1828  disp);
1829 
1830  } else {
1831  disp = dseg_add_address(cd, super->vftbl);
1832 
1833  M_TST(s1);
1834  M_CLR(d);
1835  emit_label_beq(cd, BRANCH_LABEL_5);
1836  }
1837 
1838  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1839  M_ALD(REG_ITMP3, REG_PV, disp);
1840 
1841  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1842  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1844  M_ALD(REG_ITMP1, REG_ITMP1, 0);
1846  emit_label_bne(cd, BRANCH_LABEL_8);
1847  ICONST(d, 1);
1848  emit_label_br(cd, BRANCH_LABEL_6); /* true */
1850 
1851  if (super == NULL) {
1852  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1853  M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
1854  emit_label_bne(cd, BRANCH_LABEL_10); /* false */
1855  }
1856 
1857  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1858 
1859  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
1861  emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
1862  /* reload */
1863  M_ALD(REG_ITMP3, REG_PV, disp);
1864  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1865 
1867  M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*8, REG_ITMP2);
1869  /* This seems to be the canonical sequence to emulate
1870  * the Alpha instruction M_CMPEQ. */
1871  M_XOR(REG_ITMP1, REG_ITMP3, d);
1872  M_CNTLZ(d, d);
1873  M_RLDICL(d, 58, 6, d);
1874 
1875  if (d == REG_ITMP2)
1878  if (super == NULL)
1880  if (d == REG_ITMP2) {
1881  M_CLR(d);
1882 
1884  }
1886  }
1887  else {
1888  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
1889  M_XOR(REG_ITMP2, REG_ITMP3, d);
1890  M_CNTLZ(d, d);
1891  M_RLDICL(d, 58, 6, d);
1892  }
1893 
1894  if (super != NULL)
1896  }
1897 
1898  if (super == NULL) {
1901  }
1902 
1903  emit_store_dst(jd, iptr, d);
1904  }
1905  break;
1906 
1907  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1908 
1909  /* check for negative sizes and copy sizes to stack if necessary */
1910 
1911  MCODECHECK((iptr->s1.argcount << 2) + 128);
1912 
1913  for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
1914 
1915  var = VAR(iptr->sx.s23.s2.args[s1]);
1916 
1917  /* copy SAVEDVAR sizes to stack */
1918 
1919  if (!(var->flags & PREALLOC)) {
1920  s2 = emit_load(jd, iptr, var, REG_ITMP1);
1921 #if defined(__DARWIN__)
1922  M_LST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 8);
1923 #else
1924  M_LST(s2, REG_SP, LA_SIZE + (s1 + 3) * 8);
1925 #endif
1926  }
1927  }
1928 
1929  /* a0 = dimension count */
1930 
1931  ICONST(REG_A0, iptr->s1.argcount);
1932 
1933  /* is patcher function set? */
1934 
1935  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1936  disp = dseg_add_unique_address(cd, NULL);
1937 
1939  iptr->sx.s23.s3.c.ref, disp);
1940  } else {
1941  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
1942  }
1943 
1944  /* a1 = arraydescriptor */
1945 
1946  M_ALD(REG_A1, REG_PV, disp);
1947 
1948  /* a2 = pointer to dimensions = stack pointer */
1949 
1950 #if defined(__DARWIN__)
1952 #else
1953  M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 8);
1954 #endif
1955 
1957  M_ALD(REG_ITMP3, REG_PV, disp);
1958  M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
1959  M_MTCTR(REG_ITMP3);
1960  M_JSR;
1961 
1962  /* check for exception before result assignment */
1963  emit_exception_check(cd, iptr);
1964 
1965  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1966  M_INTMOVE(REG_RESULT, d);
1967  emit_store_dst(jd, iptr, d);
1968  break;
1969 
1970  default:
1971  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
1972  } /* switch */
1973 }
1974 
1975 
1976 /* codegen_emit_stub_native ****************************************************
1977 
1978  Emits a stub routine which calls a native method.
1979 
1980 *******************************************************************************/
1981 
1982 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
1983 {
1984  methodinfo *m;
1985  codeinfo *code;
1986  codegendata *cd;
1987  methoddesc *md;
1988  s4 i, j;
1989  s4 t;
1990  int s1, s2;
1991  int disp;
1992 
1993  /* get required compiler data */
1994 
1995  m = jd->m;
1996  code = jd->code;
1997  cd = jd->cd;
1998 
1999  /* Sanity check. */
2000 
2001  assert(!code_is_leafmethod(code));
2002 
2003  /* set some variables */
2004 
2005  md = m->parseddesc;
2006 
2007  /* calculate stackframe size */
2008 
2009  cd->stackframesize =
2010  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2011  sizeof(localref_table) / SIZEOF_VOID_P +
2012  4 + /* 4 stackframeinfo arguments (darwin)*/
2013  nmd->paramcount +
2014  nmd->memuse;
2015 
2016 /* cd->stackframesize = (cd->stackframesize + 3) & ~3;*/ /* keep stack 16-byte aligned */
2017 
2018  /* create method header */
2019 
2020  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2021  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2022  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2023  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2024  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2025 
2026  /* generate code */
2027 
2028  M_MFLR(REG_ZERO);
2030  M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2031 
2032  /* save integer and float argument registers */
2033 
2034  for (i = 0; i < md->paramcount; i++) {
2035  if (!md->params[i].inmemory) {
2036  s1 = md->params[i].regoff;
2037 
2038  switch (md->paramtypes[i].type) {
2039  case TYPE_INT:
2040  case TYPE_LNG:
2041  case TYPE_ADR:
2042  M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2043  break;
2044  case TYPE_FLT:
2045  case TYPE_DBL:
2046  M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2047  break;
2048  default:
2049  assert(false);
2050  break;
2051  }
2052  }
2053  }
2054 
2055  /* create native stack info */
2056 
2057  M_MOV(REG_SP, REG_A0);
2058  M_MOV(REG_PV, REG_A1);
2060  M_ALD(REG_ITMP1, REG_PV, disp);
2061  M_ALD(REG_ITMP1, REG_ITMP1, 0); /* TOC */
2062  M_MTCTR(REG_ITMP1);
2063  M_JSR;
2064 
2065  /* remember class argument */
2066 
2067  if (m->flags & ACC_STATIC)
2069 
2070  /* restore integer and float argument registers */
2071 
2072  for (i = 0; i < md->paramcount; i++) {
2073  if (!md->params[i].inmemory) {
2074  s1 = md->params[i].regoff;
2075 
2076  switch (md->paramtypes[i].type) {
2077  case TYPE_INT:
2078  case TYPE_LNG:
2079  case TYPE_ADR:
2080  M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2081  break;
2082  case TYPE_FLT:
2083  case TYPE_DBL:
2084  M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8);
2085  break;
2086  default:
2087  assert(false);
2088  break;
2089  }
2090  }
2091  }
2092 
2093  /* copy or spill arguments to new locations */
2094 
2095  for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2096  t = md->paramtypes[i].type;
2097 
2098  if (IS_INT_LNG_TYPE(t)) {
2099  if (!md->params[i].inmemory) {
2100  s1 = md->params[i].regoff;
2101  s2 = nmd->params[j].regoff;
2102 
2103  if (!nmd->params[j].inmemory)
2104  M_INTMOVE(s1, s2);
2105  else
2106  M_LST(s1, REG_SP, s2);
2107  }
2108  else {
2109  s1 = md->params[i].regoff + cd->stackframesize * 8;
2110  s2 = nmd->params[j].regoff;
2111 
2112  M_LLD(REG_ITMP1, REG_SP, s1);
2113  M_LST(REG_ITMP1, REG_SP, s2);
2114  }
2115  }
2116  else {
2117  /* We only copy spilled float arguments, as the float
2118  argument registers keep unchanged. */
2119 
2120  if (md->params[i].inmemory) {
2121  s1 = md->params[i].regoff + cd->stackframesize * 8;
2122  s2 = nmd->params[j].regoff;
2123 
2124 
2125  if (IS_2_WORD_TYPE(t)) {
2126  M_DLD(REG_FTMP1, REG_SP, s1);
2127  M_DST(REG_FTMP1, REG_SP, s2);
2128  }
2129  else {
2130  M_FLD(REG_FTMP1, REG_SP, s1);
2131  M_FST(REG_FTMP1, REG_SP, s2 + 4);
2132  }
2133  }
2134  }
2135  }
2136 
2137  /* Handle native Java methods. */
2138 
2139  if (m->flags & ACC_NATIVE) {
2140  /* put class into second argument register */
2141 
2142  if (m->flags & ACC_STATIC)
2144 
2145  /* put env into first argument register */
2146 
2147  disp = dseg_add_unique_address(cd, VM::get_current()->get_jnienv());
2148  M_ALD(REG_A0, REG_PV, disp);
2149  }
2150 
2151  /* Call the native function. */
2152  /* native functions have a different TOC for sure */
2153 
2154  M_AST(REG_TOC, REG_SP, 40); /* save old TOC */
2155  disp = dseg_add_functionptr(cd, f);
2156  M_ALD(REG_ITMP3, REG_PV, disp);
2157  M_ALD(REG_TOC, REG_ITMP3, 8); /* load TOC from func. descriptor */
2158  M_ALD(REG_ITMP3, REG_ITMP3, 0);
2159  M_MTCTR(REG_ITMP3);
2160  M_JSR;
2161  M_ALD(REG_TOC, REG_SP, 40); /* restore TOC */
2162 
2163  /* save return value */
2164 
2165  if (md->returntype.type != TYPE_VOID) {
2166  if (IS_INT_LNG_TYPE(md->returntype.type)) {
2167  M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2168  }
2169  else {
2170  M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2171  }
2172  }
2173 
2174  /* remove native stackframe info */
2175 
2176  M_MOV(REG_SP, REG_A0);
2177  M_MOV(REG_PV, REG_A1);
2179  M_ALD(REG_ITMP1, REG_PV, disp);
2180  M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
2181  M_MTCTR(REG_ITMP1);
2182  M_JSR;
2184 
2185  /* restore return value */
2186 
2187  if (md->returntype.type != TYPE_VOID) {
2188  if (IS_INT_LNG_TYPE(md->returntype.type)) {
2189  M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2190  }
2191  else {
2192  M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8);
2193  }
2194  }
2195 
2198  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */
2199 
2200  /* check for exception */
2201 
2203  M_BNE(1); /* if no exception then return */
2204 
2205  M_RET;
2206 
2207  /* handle exception */
2208 
2210 }
2211 
2212 
2213 /*
2214  * These are local overrides for various environment variables in Emacs.
2215  * Please do not remove this and leave it at the end of the file, where
2216  * Emacs will automagically detect them.
2217  * ---------------------------------------------------------------------
2218  * Local variables:
2219  * mode: c++
2220  * indent-tabs-mode: t
2221  * c-basic-offset: 4
2222  * tab-width: 4
2223  * End:
2224  * vim:noexpandtab:sw=4:ts=4:
2225  */
void codegen_emit_instruction(jitdata *jd, instruction *iptr)
Generates machine code for one ICMD.
Definition: codegen.cpp:217
s4 dseg_add_double(codegendata *cd, double value)
Definition: dseg.cpp:465
#define REG_SP
Definition: md-abi.hpp:53
val_operand_t val
#define BUILTIN_FAST_canstore
Definition: builtin.hpp:153
#define PATCHER_resolve_classref_to_flags
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
#define M_SRA(a, b, c)
Definition: codegen.hpp:307
basicblock * block
union varinfo::@19 vv
#define REG_PV
Definition: md-abi.hpp:42
#define M_JSR(a, b)
Definition: codegen.hpp:260
s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:63
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
#define M_DMUL(a, b, c)
Definition: codegen.hpp:378
#define PATCHER_invokeinterface
#define REG_A1
Definition: md-abi.hpp:36
#define M_ANDIS(a, b, c)
Definition: codegen.hpp:194
Definition: jit.hpp:126
#define M_RLDICL(a, b, c, d)
Definition: codegen.hpp:166
#define M_LST(a, b, disp)
Definition: codegen.hpp:349
#define REG_A0
Definition: md-abi.hpp:35
#define M_RLWINM(a, b, c, d, e)
Definition: codegen.hpp:233
paramdesc * params
Definition: descriptor.hpp:164
#define M_SLL(a, b, c)
Definition: codegen.hpp:306
#define BRANCH_LE
#define M_SUBE(a, b, c)
Definition: codegen.hpp:249
#define M_ILD(a, b, disp)
Definition: codegen.hpp:347
#define BRANCH_LABEL_7
Definition: emit-common.hpp:53
s4 dseg_add_unique_address(codegendata *cd, void *value)
Definition: dseg.cpp:525
int * savintregs
Definition: reg.hpp:71
methodinfo * methods
Definition: class.hpp:113
#define M_STFDX(a, b, c)
Definition: codegen.hpp:402
#define PATCHER_resolve_classref_to_vftbl
#define M_ISEXT(a, b)
Definition: codegen.hpp:344
#define BUILTIN_multianewarray
Definition: builtin.hpp:201
#define M_CMP(a, b)
Definition: codegen.hpp:430
#define IS_INT_LNG_TYPE(a)
Definition: global.hpp:130
#define BRANCH_NE
#define M_AND(a, b, c)
Definition: codegen.hpp:294
#define M_IST(a, b, disp)
Definition: codegen.hpp:351
#define M_BNE(off)
Definition: codegen.hpp:483
#define ICONST(d, c)
Definition: codegen.hpp:53
#define M_LDA(a, b, disp)
Definition: codegen.hpp:163
#define M_SRL(a, b, c)
Definition: codegen.hpp:308
#define PATCHER_get_putfield
#define M_NEG(a)
Definition: codegen.hpp:234
#define BRANCH_EQ
#define M_CZEXT(a, b)
Definition: codegen.hpp:451
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define M_OR_IMM(a, b, c)
Definition: codegen.hpp:299
#define M_MUL(d, a, b)
Definition: codegen.hpp:478
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define REG_FRESULT
Definition: md-abi.hpp:59
int32_t argcount
Definition: instruction.hpp:64
#define dseg_add_functionptr(cd, value)
Definition: dseg.hpp:39
codegendata * cd
Definition: jit.hpp:129
void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
Definition: codegen.cpp:2010
#define BRANCH_LABEL_10
Definition: emit-common.hpp:56
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
#define M_CMPI(a, b)
Definition: codegen.hpp:208
#define M_STHX(a, b, c)
Definition: codegen.hpp:245
#define M_LDATST(a, b, c)
Definition: codegen.hpp:264
#define M_STFIWX(a, b, c)
Definition: codegen.hpp:403
#define REG_ITMP1_XPTR
Definition: md-abi.hpp:50
#define M_LWAX(a, b, c)
Definition: codegen.hpp:183
#define LA_LR_OFFSET
Definition: md-abi.hpp:97
#define REG_A2
Definition: md-abi.hpp:37
#define M_LSTX(a, b, c)
Definition: codegen.hpp:338
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
int savintreguse
Definition: reg.hpp:88
#define M_FST(a, b, disp)
Definition: codegen.hpp:357
patchref_t * patcher_add_patch_ref(jitdata *jd, functionptr patcher, void *ref, s4 disp)
constant_classref * ref
Definition: references.hpp:62
#define M_FLD(a, b, disp)
Definition: codegen.hpp:354
void dseg_add_target(codegendata *cd, basicblock *target)
Definition: dseg.cpp:565
#define M_ADDIS(a, b, c)
Definition: codegen.hpp:190
u1 * methodptr
Definition: global.hpp:40
#define M_DIV(a, b, c)
Definition: codegen.hpp:171
#define BRANCH_LABEL_6
Definition: emit-common.hpp:52
java_object_t * codegen_finish_native_call(u1 *sp, u1 *pv)
u1 * stub
Definition: builtin.hpp:64
#define M_TST(a, b)
Definition: codegen.hpp:428
#define M_OR(a, b, c)
Definition: codegen.hpp:295
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define M_MUL_IMM(a, b, c)
Definition: codegen.hpp:170
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define BUILTIN_arraycheckcast
Definition: builtin.hpp:148
#define REG_ITMP2_XPC
Definition: md-abi.hpp:51
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
#define ALIGNCODENOP
Definition: codegen.hpp:47
s4 regoff
Definition: reg.hpp:47
void(* functionptr)(void)
Definition: global.hpp:39
#define REG_TOC
Definition: md-abi.hpp:34
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define M_ALDX(a, b, c)
Definition: codegen.hpp:298
#define INT_SAV_CNT
Definition: md-abi.hpp:73
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
#define PATCHER_instanceof_interface
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define M_LHZX(a, b, c)
Definition: codegen.hpp:221
#define M_MFLR(a)
Definition: codegen.hpp:224
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
BeginInst *& block
#define M_FSUB(a, b, c)
Definition: codegen.hpp:375
classref_or_classinfo c
#define M_BNAN(a)
Definition: codegen.hpp:202
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
#define M_LWZ(a, b, disp)
Definition: codegen.hpp:265
#define LA_SIZE
Definition: md-abi.hpp:93
dst_operand_t dst
flags_operand_t flags
#define M_XOR_IMM(a, b, c)
Definition: codegen.hpp:300
#define PA_SIZE
Definition: md-abi.hpp:147
#define M_STDU(a, b, disp)
Definition: codegen.hpp:216
#define M_XOR(a, b, c)
Definition: codegen.hpp:296
constant_FMIref * fieldref
Definition: resolve.hpp:88
#define M_FCMPU(a, b)
Definition: codegen.hpp:393
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
void emit_label_br(codegendata *cd, s4 label)
#define M_CLR_HIGH(a)
Definition: codegen.hpp:443
#define M_MTLR(a)
Definition: codegen.hpp:227
#define BRANCH_LABEL_3
Definition: emit-common.hpp:49
#define M_MTCTR(a)
Definition: codegen.hpp:226
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
#define M_BSEXT(b, c)
Definition: codegen.hpp:247
#define INT_ARG_CNT
Definition: md-abi.hpp:74
#define M_FADD(a, b, c)
Definition: codegen.hpp:373
s4 flags
Definition: class.hpp:90
#define M_CVTDL_C(b, c)
Definition: codegen.hpp:395
typedesc * fd
Definition: references.hpp:74
s4 * local_map
Definition: jit.hpp:153
#define M_SRL_IMM(a, b, c)
Definition: codegen.hpp:312
#define REG_FTMP2
Definition: md-abi.hpp:66
MIIterator i
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
typedesc returntype
Definition: descriptor.hpp:166
#define M_BGE(off)
Definition: codegen.hpp:484
#define BRANCH_LABEL_4
Definition: emit-common.hpp:50
int32_t s4
Definition: types.hpp:45
#define BRANCH_LABEL_9
Definition: emit-common.hpp:55
s4 dseg_add_unique_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:229
int * savfltregs
Definition: reg.hpp:73
registerdata * rd
Definition: jit.hpp:130
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
s4 index
Definition: class.hpp:116
#define M_CNTLZ(a, b)
Definition: codegen.hpp:211
union instruction::@12 sx
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:346
#define M_RTS
Definition: codegen.hpp:234
#define M_ADDIC(a, b, c)
Definition: codegen.hpp:188
#define M_CMPUI(a, b)
Definition: codegen.hpp:210
#define PACK_REGS(low, high)
#define M_STWX(a, b, c)
Definition: codegen.hpp:247
#define PATCHER_checkcast_interface
int savfltreguse
Definition: reg.hpp:91
#define M_MOV(a, b)
Definition: codegen.hpp:340
bool inmemory
Definition: descriptor.hpp:151
#define REG_ITMP2
Definition: md-abi.hpp:47
void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
#define M_LADD_IMM(a, b, c)
Definition: codegen.hpp:271
s1_operand_t s1
#define M_LADD(a, b, c)
Definition: codegen.hpp:264
#define M_STBX(a, b, c)
Definition: codegen.hpp:244
basicblock * block
Definition: instruction.hpp:50
#define PATCHER_invokestatic_special
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
#define BRANCH_LABEL_1
Definition: emit-common.hpp:47
#define M_BGT(off)
Definition: codegen.hpp:485
vftbl_t * vftbl
Definition: class.hpp:121
methoddesc * parseddesc
Definition: method.hpp:78
#define M_SRA_IMM(a, b, c)
Definition: codegen.hpp:311
#define M_FMOVN(fa, fb)
Definition: codegen.hpp:412
#define M_MFXER(a)
Definition: codegen.hpp:225
#define M_FDIV(a, b, c)
Definition: codegen.hpp:379
#define REG_FTMP1
Definition: md-abi.hpp:65
#define M_AND_IMM(a, b, c)
Definition: codegen.hpp:298
#define PATCHER_invokevirtual
#define M_ASTX(a, b, c)
Definition: codegen.hpp:337
Definition: builtin.hpp:60
#define M_SLL_IMM(a, b, c)
Definition: codegen.hpp:310
#define M_DSUB(a, b, c)
Definition: codegen.hpp:376
methodinfo * m
Definition: jit.hpp:127
static bool IS_INMEMORY(s4 flags)
Definition: stack.hpp:51
s4 type
Definition: field.hpp:60
void codegen_emit_epilog(jitdata *jd)
Generates machine code for the method epilog.
Definition: codegen.cpp:174
#define M_LLD_INTERN(a, b, disp)
Definition: codegen.hpp:181
#define s3
Definition: md-asm.hpp:71
#define BRANCH_LABEL_8
Definition: emit-common.hpp:54
#define M_AST_INTERN(a, b, c)
Definition: codegen.hpp:1167
#define M_EXTSW(a, b)
Definition: codegen.hpp:123
#define M_LFSX(a, b, c)
Definition: codegen.hpp:401
s4 flags
Definition: reg.hpp:45
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
#define M_FMUL(a, b, c)
Definition: codegen.hpp:377
#define M_LFDX(a, b, c)
Definition: codegen.hpp:400
int8_t s1
Definition: types.hpp:39
#define M_LHAX(a, b, c)
Definition: codegen.hpp:220
#define LCONST(d, c)
Definition: codegen.hpp:54
int16_t s2
Definition: types.hpp:42
#define M_IADD(a, b, c)
Definition: codegen.hpp:263
#define M_DST(a, b, disp)
Definition: codegen.hpp:356
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
#define REG_ZERO
Definition: md-abi.hpp:54
#define M_SSEXT(b, c)
Definition: codegen.hpp:248
void codegen_emit_prolog(jitdata *jd)
Generates machine code for the method prolog.
Definition: codegen.cpp:73
#define M_RET(a, b)
Definition: codegen.hpp:261
#define REG_FTMP3
Definition: md-abi.hpp:67
#define M_LLD(a, b, disp)
Definition: codegen.hpp:344
const parseddesc_t parseddesc
Definition: references.hpp:105
static void emit_fmove(codegendata *cd, int s, int d)
Generates a float-move from register s to d.
#define REG_ITMP3
Definition: md-abi.hpp:48
#define PATCHER_resolve_classref_to_classinfo
#define MCODECHECK(icnt)
Definition: codegen.hpp:40
#define BRANCH_LABEL_2
Definition: emit-common.hpp:48
#define M_SUB(d, a, b)
Definition: codegen.hpp:423
functionptr fp
Definition: builtin.hpp:63
#define M_ADDZE(a, b)
Definition: codegen.hpp:193
#define M_BLE(off)
Definition: codegen.hpp:487
#define M_STFSX(a, b, c)
Definition: codegen.hpp:404
void emit_label(codegendata *cd, s4 label)
#define M_CLR(c)
Definition: codegen.hpp:303
s4 flags
Definition: method.hpp:70
#define M_IADD_IMM(a, b, c)
Definition: codegen.hpp:270
#define M_CVTDF(b, c)
Definition: codegen.hpp:391
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
#define M_DDIV(a, b, c)
Definition: codegen.hpp:380
uint32_t regoff
Definition: descriptor.hpp:153
#define M_LBZX(a, b, c)
Definition: codegen.hpp:219
s4 dseg_add_float(codegendata *cd, float value)
Definition: dseg.cpp:392
#define OFFSET(s, el)
Definition: memory.hpp:90
branch_target_t * table
#define M_BR(disp)
Definition: codegen.hpp:250
#define REG_RESULT
Definition: md-abi.hpp:33
#define M_INTMOVE(a, b)
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define REG_ITMP1
Definition: md-abi.hpp:46
static VM * get_current()
Definition: vm.hpp:99
#define M_DADD(a, b, c)
Definition: codegen.hpp:374