CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/powerpc/codegen.cpp - machine code generator for 32-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 <assert.h>
29 #include <stdio.h>
30 #include <signal.h>
31 
32 #include "vm/types.hpp"
33 
34 #include "md-abi.hpp"
35 
36 #include "vm/jit/powerpc/arch.hpp"
38 
39 #include "mm/memory.hpp"
40 
41 #include "native/localref.hpp"
42 #include "native/native.hpp"
43 
44 #include "threads/lock.hpp"
45 
46 #include "vm/descriptor.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/field.hpp"
49 #include "vm/global.hpp"
50 #include "vm/loader.hpp"
51 #include "vm/options.hpp"
52 #include "vm/vm.hpp"
53 
54 #include "vm/jit/abi.hpp"
55 #include "vm/jit/abi-asm.hpp"
56 #include "vm/jit/asmpart.hpp"
57 #include "vm/jit/builtin.hpp"
59 #include "vm/jit/dseg.hpp"
60 #include "vm/jit/emit-common.hpp"
61 #include "vm/jit/jit.hpp"
63 #include "vm/jit/methodheader.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  /* create stack frame (if necessary) */
90 
91  if (!code_is_leafmethod(code)) {
94  }
95 
96  if (cd->stackframesize)
97  M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
98 
99  /* save return address and used callee saved registers */
100 
101  p = cd->stackframesize;
102  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
103  p--; M_IST(rd->savintregs[i], REG_SP, p * 8);
104  }
105  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
106  p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
107  }
108 
109  /* take arguments out of register or stack frame */
110 
111  md = m->parseddesc;
112 
113  for (p = 0, l = 0; p < md->paramcount; p++) {
114  t = md->paramtypes[p].type;
115  varindex = jd->local_map[l * 5 + t];
116 
117  l++;
118  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
119  l++;
120 
121  if (varindex == jitdata::UNUSED)
122  continue;
123 
124  var = VAR(varindex);
125  s1 = md->params[p].regoff;
126 
127  if (IS_INT_LNG_TYPE(t)) {
128  if (!md->params[p].inmemory) {
129  if (!IS_INMEMORY(var->flags)) {
130  if (IS_2_WORD_TYPE(t))
131  M_LNGMOVE(s1, var->vv.regoff);
132  else
133  M_INTMOVE(s1, var->vv.regoff);
134  }
135  else {
136  if (IS_2_WORD_TYPE(t))
137  M_LST(s1, REG_SP, var->vv.regoff);
138  else
139  M_IST(s1, REG_SP, var->vv.regoff);
140  }
141  }
142  else {
143  if (!IS_INMEMORY(var->flags)) {
144  if (IS_2_WORD_TYPE(t))
145  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
146  else
147  M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
148  }
149  else {
150 #if 1
151  M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1);
152  M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
153  if (IS_2_WORD_TYPE(t)) {
154  M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1 + 4);
155  M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
156  }
157 #else
158  /* Reuse Memory Position on Caller Stack */
159  var->vv.regoff = cd->stackframesize * 8 + s1;
160 #endif
161  }
162  }
163  }
164  else {
165  if (!md->params[p].inmemory) {
166  if (!IS_INMEMORY(var->flags))
167  emit_fmove(cd, s1, var->vv.regoff);
168  else
169  if (IS_2_WORD_TYPE(t))
170  M_DST(s1, REG_SP, var->vv.regoff);
171  else
172  M_FST(s1, REG_SP, var->vv.regoff);
173  }
174  else {
175  if (!IS_INMEMORY(var->flags))
176  if (IS_2_WORD_TYPE(t))
177  M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
178  else
179  M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
180  else {
181  /* Reuse Memory Position on Caller Stack */
182  var->vv.regoff = cd->stackframesize * 8 + s1;
183  }
184  }
185  }
186  }
187 }
188 
189 
190 /**
191  * Generates machine code for the method epilog.
192  */
194 {
195  int32_t p;
196  int i;
197 
198  // Get required compiler data.
199  codeinfo* code = jd->code;
200  codegendata* cd = jd->cd;
201  registerdata* rd = jd->rd;
202 
203  p = cd->stackframesize;
204 
205  /* restore return address */
206 
207  if (!code_is_leafmethod(code)) {
208  /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
209  may have a displacement overflow. */
210 
211  M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
212  M_MTLR(REG_ITMP1);
213  }
214 
215  /* restore saved registers */
216 
217  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
218  p--; M_ILD(rd->savintregs[i], REG_SP, p * 8);
219  }
220  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
221  p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
222  }
223 
224  /* deallocate stack */
225 
226  if (cd->stackframesize)
227  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
228 
229  M_RET;
230 }
231 
232 
233 /**
234  * Generates machine code for one ICMD.
235  */
237 {
238  varinfo* var;
239  builtintable_entry* bte;
240  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
241  unresolved_method* um;
242  fieldinfo* fi;
243  unresolved_field* uf = NULL; // prevent warning
244  int32_t fieldtype;
245  int32_t s1, s2, s3, d;
246  int32_t disp;
247 
248  // Get required compiler data.
249  codeinfo* code = jd->code;
250  codegendata* cd = jd->cd;
251 
252  /* the big switch */
253  switch (iptr->opc) {
254 
255  /* constant operations ************************************************/
256 
257  case ICMD_FCONST: /* ... ==> ..., constant */
258 
259  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
260  disp = dseg_add_float(cd, iptr->sx.val.f);
261  M_FLD(d, REG_PV, disp);
262  emit_store_dst(jd, iptr, d);
263  break;
264 
265  case ICMD_DCONST: /* ... ==> ..., constant */
266 
267  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
268  disp = dseg_add_double(cd, iptr->sx.val.d);
269  M_DLD(d, REG_PV, disp);
270  emit_store_dst(jd, iptr, d);
271  break;
272 
273  case ICMD_ACONST: /* ... ==> ..., constant */
274 
275  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
276 
277  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
278  constant_classref *cr = iptr->sx.val.c.ref;;
279 
280  disp = dseg_add_unique_address(cd, cr);
281 
283  cr, disp);
284  }
285  else
286  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
287 
288  M_ALD(d, REG_PV, disp);
289  emit_store_dst(jd, iptr, d);
290  break;
291 
292 
293  /* integer operations *************************************************/
294 
295  case ICMD_INEG: /* ..., value ==> ..., - value */
296 
297  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
298  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
299  M_NEG(s1, d);
300  emit_store_dst(jd, iptr, d);
301  break;
302 
303  case ICMD_LNEG: /* ..., value ==> ..., - value */
304 
305  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
306  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
307  M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
309  emit_store_dst(jd, iptr, d);
310  break;
311 
312  case ICMD_I2L: /* ..., value ==> ..., value */
313 
314  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
315  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
316  M_INTMOVE(s1, GET_LOW_REG(d));
317  M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
318  emit_store_dst(jd, iptr, d);
319  break;
320 
321  case ICMD_L2I: /* ..., value ==> ..., value */
322 
323  s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
324  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
325  M_INTMOVE(s1, d);
326  emit_store_dst(jd, iptr, d);
327  break;
328 
329  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
330 
331  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
332  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
333  M_BSEXT(s1, d);
334  emit_store_dst(jd, iptr, d);
335  break;
336 
337  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
338 
339  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
340  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
341  M_CZEXT(s1, d);
342  emit_store_dst(jd, iptr, d);
343  break;
344 
345  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
346 
347  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
348  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
349  M_SSEXT(s1, d);
350  emit_store_dst(jd, iptr, d);
351  break;
352 
353 
354  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
355 
356  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
357  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
358  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
359  M_IADD(s1, s2, d);
360  emit_store_dst(jd, iptr, d);
361  break;
362 
363  /* s1.localindex = variable, sx.val.i = constant*/
364 
365  case ICMD_IINC:
366  case ICMD_IADDCONST:
367 
368  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
369  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
370  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
371  M_IADD_IMM(s1, iptr->sx.val.i, d);
372  } else {
373  ICONST(REG_ITMP2, iptr->sx.val.i);
374  M_IADD(s1, REG_ITMP2, d);
375  }
376  /* XXX the old code for ICMD_IINC was as follows:
377  {
378  u4 m = iptr->sx.val.i;
379  if (m & 0x8000)
380  m += 65536;
381  if (m & 0xffff0000)
382  M_ADDIS(s1, m >> 16, d);
383  if (m & 0xffff)
384  M_IADD_IMM(s1, m & 0xffff, d);
385  }
386  */
387  emit_store_dst(jd, iptr, d);
388  break;
389 
390  case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
391 
392  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
393  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
394  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
395  M_ADDC(s1, s2, GET_LOW_REG(d));
396  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
397  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
398  M_ADDE(s1, s2, GET_HIGH_REG(d));
399  emit_store_dst(jd, iptr, d);
400  break;
401 
402  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
403  /* sx.val.l = constant */
404 
405  s3 = iptr->sx.val.l & 0xffffffff;
406  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
407  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
408  if ((s3 >= -32768) && (s3 <= 32767))
409  M_ADDIC(s1, s3, GET_LOW_REG(d));
410  else {
411  ICONST(REG_ITMP2, s3);
412  M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
413  }
414  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
415  s3 = iptr->sx.val.l >> 32;
416  if (s3 == -1)
417  M_ADDME(s1, GET_HIGH_REG(d));
418  else if (s3 == 0)
419  M_ADDZE(s1, GET_HIGH_REG(d));
420  else {
421  ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
422  M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
423  }
424  emit_store_dst(jd, iptr, d);
425  break;
426 
427  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
428 
429  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
430  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
431  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
432  M_ISUB(s1, s2, d);
433  emit_store_dst(jd, iptr, d);
434  break;
435 
436  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
437  /* sx.val.i = constant */
438 
439  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
440  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
441  if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
442  M_IADD_IMM(s1, -iptr->sx.val.i, d);
443  else {
444  ICONST(REG_ITMP2, iptr->sx.val.i);
445  M_ISUB(s1, REG_ITMP2, d);
446  }
447  emit_store_dst(jd, iptr, d);
448  break;
449 
450  case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
451 
452  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
453  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
454  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
455  M_SUBC(s1, s2, GET_LOW_REG(d));
456  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
457  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
458  M_SUBE(s1, s2, GET_HIGH_REG(d));
459  emit_store_dst(jd, iptr, d);
460  break;
461 
462  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
463  /* sx.val.l = constant */
464 
465  s3 = (-iptr->sx.val.l) & 0xffffffff;
466  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
467  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
468  if ((s3 >= -32768) && (s3 <= 32767)) {
469  M_ADDIC(s1, s3, GET_LOW_REG(d));
470  } else {
471  ICONST(REG_ITMP2, s3);
472  M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
473  }
474  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
475  s3 = (-iptr->sx.val.l) >> 32;
476  if (s3 == -1)
477  M_ADDME(s1, GET_HIGH_REG(d));
478  else if (s3 == 0)
479  M_ADDZE(s1, GET_HIGH_REG(d));
480  else {
481  ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
482  M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
483  }
484  emit_store_dst(jd, iptr, d);
485  break;
486 
487  case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
488 
489  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
490  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
491  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
492  emit_arithmetic_check(cd, iptr, s2);
493  M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
494  M_CMP(REG_ITMP3, s1);
495  M_BNE(3 + (s1 != d));
496  M_CMPI(s2, -1);
497  M_BNE(1 + (s1 != d));
498  M_INTMOVE(s1, d);
499  M_BR(1);
500  M_IDIV(s1, s2, d);
501  emit_store_dst(jd, iptr, d);
502  break;
503 
504  case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
505 
506  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
507  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
508  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509  emit_arithmetic_check(cd, iptr, s2);
510  M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
511  M_CMP(REG_ITMP3, s1);
512  M_BNE(4);
513  M_CMPI(s2, -1);
514  M_BNE(2);
515  M_CLR(d);
516  M_BR(3);
517  M_IDIV(s1, s2, REG_ITMP3);
518  M_IMUL(REG_ITMP3, s2, REG_ITMP3);
519  M_ISUB(s1, REG_ITMP3, d);
520  emit_store_dst(jd, iptr, d);
521  break;
522 
523  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
524  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
525 
526  s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
527  s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
528 
529  /* XXX TODO: only do this if arithmetic check is really done! */
531  /* XXX could be optimized */
532  emit_arithmetic_check(cd, iptr, REG_ITMP3);
533 
534  bte = iptr->sx.s23.s3.bte;
535  disp = dseg_add_functionptr(cd, bte->fp);
536  M_ALD(REG_ITMP3, REG_PV, disp);
538 
541 
542  M_JSR;
543 
544  d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
546  emit_store_dst(jd, iptr, d);
547  break;
548 
549  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
550 
551  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
553  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
554  M_IMUL(s1, s2, d);
555  emit_store_dst(jd, iptr, d);
556  break;
557 
558  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
559  /* sx.val.i = constant */
560 
561  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
564  M_IMUL_IMM(s1, iptr->sx.val.i, d);
565  else {
566  ICONST(REG_ITMP3, iptr->sx.val.i);
567  M_IMUL(s1, REG_ITMP3, d);
568  }
569  emit_store_dst(jd, iptr, d);
570  break;
571 
572  case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
573 
574  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
576  M_SRA_IMM(s1, iptr->sx.val.i, d);
577  M_ADDZE(d, d);
578  emit_store_dst(jd, iptr, d);
579  break;
580 
581  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
582 
583  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
585  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586  M_IAND_IMM(s2, 0x1f, REG_ITMP3);
587  M_SLL(s1, REG_ITMP3, d);
588  emit_store_dst(jd, iptr, d);
589  break;
590 
591  case ICMD_ISHLCONST: /* ..., 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  M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
597  emit_store_dst(jd, iptr, d);
598  break;
599 
600  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
601 
602  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
603  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
604  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605  M_IAND_IMM(s2, 0x1f, REG_ITMP3);
606  M_SRA(s1, REG_ITMP3, d);
607  emit_store_dst(jd, iptr, d);
608  break;
609 
610  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
611  /* sx.val.i = constant */
612 
613  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615  M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
616  emit_store_dst(jd, iptr, d);
617  break;
618 
619  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
620 
621  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
623  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624  M_IAND_IMM(s2, 0x1f, REG_ITMP2);
625  M_SRL(s1, REG_ITMP2, d);
626  emit_store_dst(jd, iptr, d);
627  break;
628 
629  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
630  /* sx.val.i = constant */
631 
632  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634  if (iptr->sx.val.i & 0x1f)
635  M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
636  else {
637  M_INTMOVE(s1, d);
638  }
639  emit_store_dst(jd, iptr, d);
640  break;
641 
642  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
643 
644  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
646  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
647  M_IAND(s1, s2, d);
648  emit_store_dst(jd, iptr, d);
649  break;
650 
651  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
652  /* sx.val.i = constant */
653 
654  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
657  M_IAND_IMM(s1, iptr->sx.val.i, d);
658  /*
659  else if (iptr->sx.val.i == 0xffffff) {
660  M_RLWINM(s1, 0, 8, 31, d);
661  }
662  */
663  else {
664  ICONST(REG_ITMP3, iptr->sx.val.i);
665  M_IAND(s1, REG_ITMP3, d);
666  }
667  emit_store_dst(jd, iptr, d);
668  break;
669 
670  case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
671 
672  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
673  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
674  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
675  M_IAND(s1, s2, GET_LOW_REG(d));
676  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
677  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
678  M_IAND(s1, s2, GET_HIGH_REG(d));
679  emit_store_dst(jd, iptr, d);
680  break;
681 
682  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
683  /* sx.val.l = constant */
684 
685  s3 = iptr->sx.val.l & 0xffffffff;
686  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
687  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
688  if ((s3 >= 0) && (s3 <= 65535))
689  M_IAND_IMM(s1, s3, GET_LOW_REG(d));
690  else {
691  ICONST(REG_ITMP3, s3);
692  M_IAND(s1, REG_ITMP3, GET_LOW_REG(d));
693  }
694  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
695  s3 = iptr->sx.val.l >> 32;
696  if ((s3 >= 0) && (s3 <= 65535))
697  M_IAND_IMM(s1, s3, GET_HIGH_REG(d));
698  else {
699  ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
700  M_IAND(s1, REG_ITMP3, GET_HIGH_REG(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 
708  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710  M_MOV(s1, REG_ITMP2);
711  M_CMPI(s1, 0);
712  M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
713  if (iptr->sx.val.i >= 32768) {
714  M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
715  M_IOR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
716  M_IADD(s1, REG_ITMP2, REG_ITMP2);
717  }
718  else {
719  M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
720  }
721  {
722  int b=0, m = iptr->sx.val.i;
723  while (m >>= 1)
724  ++b;
725  M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
726  }
727  M_ISUB(s1, REG_ITMP2, d);
728  emit_store_dst(jd, iptr, d);
729  break;
730 
731  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
732 
733  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
735  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736  M_IOR(s1, s2, d);
737  emit_store_dst(jd, iptr, d);
738  break;
739 
740  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
741  /* sx.val.i = constant */
742 
743  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
744  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
745  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
746  M_IOR_IMM(s1, iptr->sx.val.i, d);
747  else {
748  ICONST(REG_ITMP3, iptr->sx.val.i);
749  M_IOR(s1, REG_ITMP3, d);
750  }
751  emit_store_dst(jd, iptr, d);
752  break;
753 
754  case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
755 
756  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
757  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
758  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
759  M_IOR(s1, s2, GET_LOW_REG(d));
760  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
761  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
762  M_IOR(s1, s2, GET_HIGH_REG(d));
763  emit_store_dst(jd, iptr, d);
764  break;
765 
766  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
767  /* sx.val.l = constant */
768 
769  s3 = iptr->sx.val.l & 0xffffffff;
770  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
771  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
772  if ((s3 >= 0) && (s3 <= 65535))
773  M_IOR_IMM(s1, s3, GET_LOW_REG(d));
774  else {
775  ICONST(REG_ITMP3, s3);
776  M_IOR(s1, REG_ITMP3, GET_LOW_REG(d));
777  }
778  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
779  s3 = iptr->sx.val.l >> 32;
780  if ((s3 >= 0) && (s3 <= 65535))
781  M_IOR_IMM(s1, s3, GET_HIGH_REG(d));
782  else {
783  ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
784  M_IOR(s1, REG_ITMP3, GET_HIGH_REG(d));
785  }
786  emit_store_dst(jd, iptr, d);
787  break;
788 
789  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
790 
791  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
792  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
793  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794  M_XOR(s1, s2, d);
795  emit_store_dst(jd, iptr, d);
796  break;
797 
798  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
799  /* sx.val.i = constant */
800 
801  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
804  M_XOR_IMM(s1, iptr->sx.val.i, d);
805  else {
806  ICONST(REG_ITMP3, iptr->sx.val.i);
807  M_XOR(s1, REG_ITMP3, d);
808  }
809  emit_store_dst(jd, iptr, d);
810  break;
811 
812  case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
813 
814  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
815  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
816  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
817  M_XOR(s1, s2, GET_LOW_REG(d));
818  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
819  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
820  M_XOR(s1, s2, GET_HIGH_REG(d));
821  emit_store_dst(jd, iptr, d);
822  break;
823 
824  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
825  /* sx.val.l = constant */
826 
827  s3 = iptr->sx.val.l & 0xffffffff;
828  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
829  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
830  if ((s3 >= 0) && (s3 <= 65535))
831  M_XOR_IMM(s1, s3, GET_LOW_REG(d));
832  else {
833  ICONST(REG_ITMP3, s3);
834  M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
835  }
836  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
837  s3 = iptr->sx.val.l >> 32;
838  if ((s3 >= 0) && (s3 <= 65535))
839  M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
840  else {
841  ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
842  M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
843  }
844  emit_store_dst(jd, iptr, d);
845  break;
846 
847  case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
848 
849  s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
850  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
851  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
852  vm_abort("codegen: implement ICMD_LCMP!");
853  emit_store_dst(jd, iptr, d);
854  break;
855 
856 
857  /* floating operations ************************************************/
858 
859  case ICMD_FNEG: /* ..., value ==> ..., - value */
860 
861  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
862  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
863  M_FMOVN(s1, d);
864  emit_store_dst(jd, iptr, d);
865  break;
866 
867  case ICMD_DNEG: /* ..., value ==> ..., - value */
868 
869  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
870  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
871  M_FMOVN(s1, d);
872  emit_store_dst(jd, iptr, d);
873  break;
874 
875  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
876 
877  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
878  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
879  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
880  M_FADD(s1, s2, d);
881  emit_store_dst(jd, iptr, d);
882  break;
883 
884  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
885 
886  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
887  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
888  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
889  M_DADD(s1, s2, d);
890  emit_store_dst(jd, iptr, d);
891  break;
892 
893  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
894 
895  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
896  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
897  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
898  M_FSUB(s1, s2, d);
899  emit_store_dst(jd, iptr, d);
900  break;
901 
902  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
903 
904  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
905  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
906  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
907  M_DSUB(s1, s2, d);
908  emit_store_dst(jd, iptr, d);
909  break;
910 
911  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
912 
913  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
914  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
915  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
916  M_FMUL(s1, s2, d);
917  emit_store_dst(jd, iptr, d);
918  break;
919 
920  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
921 
922  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
923  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
924  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
925  M_DMUL(s1, s2, d);
926  emit_store_dst(jd, iptr, d);
927  break;
928 
929  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
930 
931  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
932  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
933  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
934  M_FDIV(s1, s2, d);
935  emit_store_dst(jd, iptr, d);
936  break;
937 
938  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
939 
940  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
941  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
942  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
943  M_DDIV(s1, s2, d);
944  emit_store_dst(jd, iptr, d);
945  break;
946 
947  case ICMD_F2I: /* ..., value ==> ..., (int) value */
948  case ICMD_D2I:
949 
950  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
951  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
952  M_CLR(d);
953  disp = dseg_add_float(cd, 0.0);
954  M_FLD(REG_FTMP2, REG_PV, disp);
955  M_FCMPU(s1, REG_FTMP2);
956  M_BNAN(4);
957  disp = dseg_add_unique_s4(cd, 0);
958  M_CVTDL_C(s1, REG_FTMP1);
959  M_LDA(REG_ITMP1, REG_PV, disp);
961  M_ILD(d, REG_PV, disp);
962  emit_store_dst(jd, iptr, d);
963  break;
964 
965  case ICMD_F2D: /* ..., value ==> ..., (double) value */
966 
967  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
968  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
969  emit_fmove(cd, s1, d);
970  emit_store_dst(jd, iptr, d);
971  break;
972 
973  case ICMD_D2F: /* ..., value ==> ..., (double) value */
974 
975  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
976  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
977  M_CVTDF(s1, d);
978  emit_store_dst(jd, iptr, d);
979  break;
980 
981  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
982  case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
983 
984  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
985  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
986  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
987  M_FCMPU(s2, s1);
988  M_IADD_IMM(REG_ZERO, -1, d);
989  M_BNAN(4);
990  M_BGT(3);
991  M_IADD_IMM(REG_ZERO, 0, d);
992  M_BGE(1);
993  M_IADD_IMM(REG_ZERO, 1, d);
994  emit_store_dst(jd, iptr, d);
995  break;
996 
997  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
998  case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
999 
1000  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1001  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1002  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1003  M_FCMPU(s1, s2);
1004  M_IADD_IMM(REG_ZERO, 1, d);
1005  M_BNAN(4);
1006  M_BGT(3);
1007  M_IADD_IMM(REG_ZERO, 0, d);
1008  M_BGE(1);
1009  M_IADD_IMM(REG_ZERO, -1, d);
1010  emit_store_dst(jd, iptr, d);
1011  break;
1012 
1013 
1014  /* memory operations **************************************************/
1015 
1016  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1017 
1018  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1019  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1020  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1022  M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1023  /* implicit null-pointer check */
1024  M_LBZX(d, s1, REG_ITMP2);
1025  M_BSEXT(d, d);
1026  emit_store_dst(jd, iptr, d);
1027  break;
1028 
1029  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1030 
1031  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1033  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1035  M_SLL_IMM(s2, 1, REG_ITMP2);
1037  /* implicit null-pointer check */
1038  M_LHZX(d, s1, REG_ITMP2);
1039  emit_store_dst(jd, iptr, d);
1040  break;
1041 
1042  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1043 
1044  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1045  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1046  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1048  M_SLL_IMM(s2, 1, REG_ITMP2);
1050  /* implicit null-pointer check */
1051  M_LHAX(d, s1, REG_ITMP2);
1052  emit_store_dst(jd, iptr, d);
1053  break;
1054 
1055  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1056 
1057  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1058  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1059  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1060  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1061  M_SLL_IMM(s2, 2, REG_ITMP2);
1063  /* implicit null-pointer check */
1064  M_LWZX(d, s1, REG_ITMP2);
1065  emit_store_dst(jd, iptr, d);
1066  break;
1067 
1068  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1069 
1070  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1071  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1072  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1073  /* implicit null-pointer check */
1074  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1075  M_SLL_IMM(s2, 3, REG_ITMP2);
1076  M_IADD(s1, REG_ITMP2, REG_ITMP2);
1078  emit_store_dst(jd, iptr, d);
1079  break;
1080 
1081  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1082 
1083  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1085  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1086  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1087  M_SLL_IMM(s2, 2, REG_ITMP2);
1089  /* implicit null-pointer check */
1090  M_LFSX(d, s1, REG_ITMP2);
1091  emit_store_dst(jd, iptr, d);
1092  break;
1093 
1094  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1095 
1096  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1097  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1098  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1099  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1100  M_SLL_IMM(s2, 3, REG_ITMP2);
1102  /* implicit null-pointer check */
1103  M_LFDX(d, s1, REG_ITMP2);
1104  emit_store_dst(jd, iptr, d);
1105  break;
1106 
1107  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1108 
1109  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1111  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1112  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1113  M_SLL_IMM(s2, 2, REG_ITMP2);
1115  /* implicit null-pointer check */
1116  M_LWZX(d, s1, REG_ITMP2);
1117  emit_store_dst(jd, iptr, d);
1118  break;
1119 
1120 
1121  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1122 
1123  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1124  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1125  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1126  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1127  M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1128  /* implicit null-pointer check */
1129  M_STBX(s3, s1, REG_ITMP2);
1130  break;
1131 
1132  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1133 
1134  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1135  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1136  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1137  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1138  M_SLL_IMM(s2, 1, REG_ITMP2);
1140  /* implicit null-pointer check */
1141  M_STHX(s3, s1, REG_ITMP2);
1142  break;
1143 
1144  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1145 
1146  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1147  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1148  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1149  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1150  M_SLL_IMM(s2, 1, REG_ITMP2);
1152  /* implicit null-pointer check */
1153  M_STHX(s3, s1, REG_ITMP2);
1154  break;
1155 
1156  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1157 
1158  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1159  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1160  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1161  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1162  M_SLL_IMM(s2, 2, REG_ITMP2);
1164  /* implicit null-pointer check */
1165  M_STWX(s3, s1, REG_ITMP2);
1166  break;
1167 
1168  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1169 
1170  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1171  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1172  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1173  s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1174  M_SLL_IMM(s2, 3, REG_ITMP2);
1176  /* implicit null-pointer check */
1177  M_STWX(s3, s1, REG_ITMP2);
1179  s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1180  M_STWX(s3, s1, REG_ITMP2);
1181  break;
1182 
1183  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1184 
1185  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1186  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1187  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1188  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1189  M_SLL_IMM(s2, 2, REG_ITMP2);
1191  /* implicit null-pointer check */
1192  M_STFSX(s3, s1, REG_ITMP2);
1193  break;
1194 
1195  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1196 
1197  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1198  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1199  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1200  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1201  M_SLL_IMM(s2, 3, REG_ITMP2);
1203  /* implicit null-pointer check */
1204  M_STFDX(s3, s1, REG_ITMP2);
1205  break;
1206 
1207  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1208 
1209  s1 = emit_load_s1(jd, iptr, REG_A0);
1210  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1211  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1212  s3 = emit_load_s3(jd, iptr, REG_A1);
1213 
1214  /* XXX what if array is NULL */
1216  M_ALD(REG_ITMP3, REG_PV, disp);
1217  M_MTCTR(REG_ITMP3);
1218 
1219  M_INTMOVE(s1, REG_A0);
1220  M_INTMOVE(s3, REG_A1);
1221 
1222  M_JSR;
1223  emit_arraystore_check(cd, iptr);
1224 
1225  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1226  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1227  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1228  M_SLL_IMM(s2, 2, REG_ITMP2);
1230  /* implicit null-pointer check */
1231  M_STWX(s3, s1, REG_ITMP2);
1232  break;
1233 
1234 #if 0
1235  case ICMD_GETSTATIC: /* ... ==> ..., value */
1236 
1237  case TYPE_LNG:
1238  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1239  M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1240  M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1241  break;
1242  break;
1243 #endif
1244 
1245  case ICMD_GETFIELD: /* ... ==> ..., value */
1246 
1247  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 
1249  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1250  uf = iptr->sx.s23.s3.uf;
1251  fieldtype = uf->fieldref->parseddesc.fd->type;
1252  disp = 0;
1253 
1255  }
1256  else {
1257  fi = iptr->sx.s23.s3.fmiref->p.field;
1258  fieldtype = fi->type;
1259  disp = fi->offset;
1260  }
1261 
1262  /* implicit null-pointer check */
1263  switch (fieldtype) {
1264  case TYPE_INT:
1265  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1266  M_ILD(d, s1, disp);
1267  break;
1268  case TYPE_LNG:
1269  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1270  if (GET_HIGH_REG(d) == (unsigned)s1) {
1271  M_ILD(GET_LOW_REG(d), s1, disp + 4);
1272  M_ILD(GET_HIGH_REG(d), s1, disp);
1273  }
1274  else {
1275  M_ILD(GET_HIGH_REG(d), s1, disp);
1276  M_ILD(GET_LOW_REG(d), s1, disp + 4);
1277  }
1278  break;
1279  case TYPE_ADR:
1280  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1281  M_ALD(d, s1, disp);
1282  break;
1283  case TYPE_FLT:
1284  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1285  M_FLD(d, s1, disp);
1286  break;
1287  case TYPE_DBL:
1288  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1289  M_DLD(d, s1, disp);
1290  break;
1291  default:
1292  assert(false);
1293  break;
1294  }
1295  emit_store_dst(jd, iptr, d);
1296  break;
1297 
1298  case ICMD_PUTFIELD: /* ..., value ==> ... */
1299 
1300  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1301 
1302  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1303  uf = iptr->sx.s23.s3.uf;
1304  fieldtype = uf->fieldref->parseddesc.fd->type;
1305  disp = 0;
1306  }
1307  else {
1308  fi = iptr->sx.s23.s3.fmiref->p.field;
1309  fieldtype = fi->type;
1310  disp = fi->offset;
1311  }
1312 
1313  if (IS_INT_LNG_TYPE(fieldtype)) {
1314  if (IS_2_WORD_TYPE(fieldtype))
1315  s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1316  else
1317  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1318  }
1319  else
1320  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1321 
1322  if (INSTRUCTION_IS_UNRESOLVED(iptr))
1324 
1325  /* implicit null-pointer check */
1326  switch (fieldtype) {
1327  case TYPE_INT:
1328  M_IST(s2, s1, disp);
1329  break;
1330  case TYPE_LNG:
1331  M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
1332  M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
1333  break;
1334  case TYPE_ADR:
1335  M_AST(s2, s1, disp);
1336  break;
1337  case TYPE_FLT:
1338  M_FST(s2, s1, disp);
1339  break;
1340  case TYPE_DBL:
1341  M_DST(s2, s1, disp);
1342  break;
1343  default:
1344  assert(false);
1345  break;
1346  }
1347  break;
1348 
1349 
1350  /* branch operations **************************************************/
1351 
1352  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1353 
1355  break;
1356 
1357  case ICMD_IFNULL: /* ..., value ==> ... */
1358  case ICMD_IFNONNULL:
1359 
1360  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1361  M_TST(s1);
1362  emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1363  break;
1364 
1365  case ICMD_IF_LEQ: /* ..., value ==> ... */
1366 
1367  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1368  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1369  if (iptr->sx.val.l == 0) {
1370  M_IOR_TST(s1, s2, REG_ITMP3);
1371  }
1372  else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1373  M_XOR_IMM(s2, 0, REG_ITMP2);
1374  M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1376  }
1377  else {
1378  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1379  M_XOR(s1, REG_ITMP3, REG_ITMP1);
1380  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1381  M_XOR(s2, REG_ITMP3, REG_ITMP2);
1383  }
1384  emit_beq(cd, iptr->dst.block);
1385  break;
1386 
1387  case ICMD_IF_LLT: /* ..., value ==> ... */
1388 
1389  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1390  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1391  if (iptr->sx.val.l == 0) {
1392  /* if high word is less than zero, the whole long is too */
1393  M_CMPI(s2, 0);
1394  emit_blt(cd, iptr->dst.block);
1395  }
1396  else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1397  M_CMPI(s2, 0);
1398  emit_blt(cd, iptr->dst.block);
1399  emit_label_bgt(cd, BRANCH_LABEL_1);
1400  M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1401  emit_blt(cd, iptr->dst.block);
1403  }
1404  else {
1405  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1406  M_CMP(s2, REG_ITMP3);
1407  emit_blt(cd, iptr->dst.block);
1408  emit_label_bgt(cd, BRANCH_LABEL_1);
1409  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1410  M_CMPU(s1, REG_ITMP3);
1411  emit_blt(cd, iptr->dst.block);
1413  }
1414  break;
1415 
1416  case ICMD_IF_LLE: /* ..., value ==> ... */
1417 
1418  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1419  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1420 /* if (iptr->sx.val.l == 0) { */
1421 /* M_IOR(s1, s2, REG_ITMP3); */
1422 /* M_CMPI(REG_ITMP3, 0); */
1423 
1424 /* } else */
1425  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1426  M_CMPI(s2, 0);
1427  emit_blt(cd, iptr->dst.block);
1428  emit_label_bgt(cd, BRANCH_LABEL_1);
1429  M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1430  }
1431  else {
1432  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1433  M_CMP(s2, REG_ITMP3);
1434  emit_blt(cd, iptr->dst.block);
1435  emit_label_bgt(cd, BRANCH_LABEL_1);
1436  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1437  M_CMPU(s1, REG_ITMP3);
1438  }
1439  emit_ble(cd, iptr->dst.block);
1441  break;
1442 
1443  case ICMD_IF_LNE: /* ..., value ==> ... */
1444 
1445  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1446  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1447  if (iptr->sx.val.l == 0) {
1448  M_IOR_TST(s1, s2, REG_ITMP3);
1449  }
1450  else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1451  M_XOR_IMM(s2, 0, REG_ITMP2);
1452  M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1454  }
1455  else {
1456  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1457  M_XOR(s1, REG_ITMP3, REG_ITMP1);
1458  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1459  M_XOR(s2, REG_ITMP3, REG_ITMP2);
1461  }
1462  emit_bne(cd, iptr->dst.block);
1463  break;
1464 
1465  case ICMD_IF_LGT: /* ..., value ==> ... */
1466 
1467  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1468  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1469 /* if (iptr->sx.val.l == 0) { */
1470 /* M_IOR(s1, s2, REG_ITMP3); */
1471 /* M_CMPI(REG_ITMP3, 0); */
1472 
1473 /* } else */
1474  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1475  M_CMPI(s2, 0);
1476  emit_bgt(cd, iptr->dst.block);
1477  emit_label_blt(cd, BRANCH_LABEL_1);
1478  M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1479  }
1480  else {
1481  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1482  M_CMP(s2, REG_ITMP3);
1483  emit_bgt(cd, iptr->dst.block);
1484  emit_label_blt(cd, BRANCH_LABEL_1);
1485  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1486  M_CMPU(s1, REG_ITMP3);
1487  }
1488  emit_bgt(cd, iptr->dst.block);
1490  break;
1491 
1492  case ICMD_IF_LGE: /* ..., value ==> ... */
1493 
1494  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1495  s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1496  if (iptr->sx.val.l == 0) {
1497  /* if high word is greater equal zero, the whole long is too */
1498  M_CMPI(s2, 0);
1499  emit_bge(cd, iptr->dst.block);
1500  }
1501  else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1502  M_CMPI(s2, 0);
1503  emit_bgt(cd, iptr->dst.block);
1504  emit_label_blt(cd, BRANCH_LABEL_1);
1505  M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1506  emit_bge(cd, iptr->dst.block);
1508  }
1509  else {
1510  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1511  M_CMP(s2, REG_ITMP3);
1512  emit_bgt(cd, iptr->dst.block);
1513  emit_label_blt(cd, BRANCH_LABEL_1);
1514  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1515  M_CMPU(s1, REG_ITMP3);
1516  emit_bge(cd, iptr->dst.block);
1518  }
1519  break;
1520 
1521  case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1522 
1523  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1524  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1525  M_CMP(s1, s2);
1526  emit_label_bne(cd, BRANCH_LABEL_1);
1527  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1528  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1529  M_CMP(s1, s2);
1530  emit_beq(cd, iptr->dst.block);
1532  break;
1533 
1534  case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1535 
1536  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1537  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1538  M_CMP(s1, s2);
1539  emit_bne(cd, iptr->dst.block);
1540  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1541  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1542  M_CMP(s1, s2);
1543  emit_bne(cd, iptr->dst.block);
1544  break;
1545 
1546  case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1547 
1548  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1549  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1550  M_CMP(s1, s2);
1551  emit_blt(cd, iptr->dst.block);
1552  emit_label_bgt(cd, BRANCH_LABEL_1);
1553  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1554  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1555  M_CMPU(s1, s2);
1556  emit_blt(cd, iptr->dst.block);
1558  break;
1559 
1560  case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1561 
1562  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1563  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1564  M_CMP(s1, s2);
1565  emit_bgt(cd, iptr->dst.block);
1566  emit_label_blt(cd, BRANCH_LABEL_1);
1567  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1568  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1569  M_CMPU(s1, s2);
1570  emit_bgt(cd, iptr->dst.block);
1572  break;
1573 
1574  case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1575 
1576  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1577  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1578  M_CMP(s1, s2);
1579  emit_blt(cd, iptr->dst.block);
1580  emit_label_bgt(cd, BRANCH_LABEL_1);
1581  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1582  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1583  M_CMPU(s1, s2);
1584  emit_ble(cd, iptr->dst.block);
1586  break;
1587 
1588  case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1589 
1590  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1591  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1592  M_CMP(s1, s2);
1593  emit_bgt(cd, iptr->dst.block);
1594  emit_label_blt(cd, BRANCH_LABEL_1);
1595  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1596  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1597  M_CMPU(s1, s2);
1598  emit_bge(cd, iptr->dst.block);
1600  break;
1601 
1602  case ICMD_TABLESWITCH: /* ..., index ==> ... */
1603  {
1604  s4 i, l;
1605  branch_target_t *table;
1606 
1607  table = iptr->dst.table;
1608 
1609  l = iptr->sx.s23.s2.tablelow;
1610  i = iptr->sx.s23.s3.tablehigh;
1611 
1612  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1613  if (l == 0)
1614  M_INTMOVE(s1, REG_ITMP1);
1615  else if (l <= 32768)
1616  M_LDA(REG_ITMP1, s1, -l);
1617  else {
1618  ICONST(REG_ITMP2, l);
1619  M_ISUB(s1, REG_ITMP2, REG_ITMP1);
1620  }
1621 
1622  i = i - l + 1;
1623 
1624  /* range check */
1625 
1626  M_CMPUI(REG_ITMP1, i - 1);
1627  emit_bgt(cd, table[0].block);
1628 
1629  /* build jump table top down and use address of lowest entry */
1630 
1631  table += i;
1632 
1633  while (--i >= 0) {
1634  dseg_add_target(cd, table->block);
1635  --table;
1636  }
1637 
1638  /* length of dataseg after last dseg_add_target is used by load */
1639 
1642  M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1643  M_MTCTR(REG_ITMP2);
1644  M_RTS;
1645  ALIGNCODENOP;
1646  }
1647  break;
1648 
1649 
1650  case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1651  bte = iptr->sx.s23.s3.bte;
1652  if (bte->stub == NULL)
1653  disp = dseg_add_functionptr(cd, bte->fp);
1654  else
1655  disp = dseg_add_functionptr(cd, bte->stub);
1656 
1657  M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
1658 
1659  /* generate the actual call */
1660 
1661  M_MTCTR(REG_PV);
1662  M_JSR;
1663  break;
1664 
1665  case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1666  emit_nullpointer_check(cd, iptr, REG_A0);
1667  /* fall-through */
1668 
1669  case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1670  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1671  um = iptr->sx.s23.s3.um;
1672  disp = dseg_add_unique_address(cd, um);
1673 
1675  um, disp);
1676  }
1677  else {
1678  lm = iptr->sx.s23.s3.fmiref->p.method;
1679  disp = dseg_add_address(cd, lm->stubroutine);
1680  }
1681 
1682  M_ALD(REG_PV, REG_PV, disp);
1683 
1684  /* generate the actual call */
1685 
1686  M_MTCTR(REG_PV);
1687  M_JSR;
1688  break;
1689 
1690  case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1691  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1692  um = iptr->sx.s23.s3.um;
1694 
1695  s1 = 0;
1696  }
1697  else {
1698  lm = iptr->sx.s23.s3.fmiref->p.method;
1699  s1 = OFFSET(vftbl_t, table[0]) +
1700  sizeof(methodptr) * lm->vftblindex;
1701  }
1702 
1703  /* implicit null-pointer check */
1705  M_ALD(REG_PV, REG_METHODPTR, s1);
1706 
1707  /* generate the actual call */
1708 
1709  M_MTCTR(REG_PV);
1710  M_JSR;
1711  break;
1712 
1713  case ICMD_INVOKEINTERFACE:
1714  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1715  um = iptr->sx.s23.s3.um;
1717 
1718  s1 = 0;
1719  s2 = 0;
1720  }
1721  else {
1722  lm = iptr->sx.s23.s3.fmiref->p.method;
1723  s1 = OFFSET(vftbl_t, interfacetable[0]) -
1724  sizeof(methodptr*) * lm->clazz->index;
1725 
1726  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1727  }
1728 
1729  /* implicit null-pointer check */
1732  M_ALD(REG_PV, REG_METHODPTR, s2);
1733 
1734  /* generate the actual call */
1735 
1736  M_MTCTR(REG_PV);
1737  M_JSR;
1738  break;
1739 
1740  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1741 
1742  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1743  /* object type cast-check */
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 
1759  /* if class is not resolved, check which code to call */
1760 
1761  if (super == NULL) {
1762  M_TST(s1);
1763  emit_label_beq(cd, BRANCH_LABEL_1);
1764 
1765  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
1766 
1769  iptr->sx.s23.s3.c.ref,
1770  disp);
1771 
1772  M_ILD(REG_ITMP2, REG_PV, disp);
1774  emit_label_beq(cd, BRANCH_LABEL_2);
1775  }
1776 
1777  /* interface checkcast code */
1778 
1779  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1780  if (super == NULL) {
1783  iptr->sx.s23.s3.c.ref,
1784  0);
1785  }
1786  else {
1787  M_TST(s1);
1788  emit_label_beq(cd, BRANCH_LABEL_3);
1789  }
1790 
1791  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1792  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1793  M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
1794  emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1795 
1797  OFFSET(vftbl_t, interfacetable[0]) -
1798  superindex * sizeof(methodptr*));
1799  M_TST(REG_ITMP3);
1800  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1801 
1802  if (super == NULL)
1804  else
1806  }
1807 
1808  /* class checkcast code */
1809 
1810  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1811  if (super == NULL) {
1813 
1814  disp = dseg_add_unique_address(cd, NULL);
1815 
1817  iptr->sx.s23.s3.c.ref,
1818  disp);
1819  }
1820  else {
1821  disp = dseg_add_address(cd, super->vftbl);
1822 
1823  M_TST(s1);
1824  emit_label_beq(cd, BRANCH_LABEL_5);
1825  }
1826 
1827  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1828  M_ALD(REG_ITMP3, REG_PV, disp);
1829 
1830  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1831  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1833  M_ALD(REG_ITMP1, REG_ITMP1, 0);
1835  emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1836 
1837  if (super == NULL) {
1838  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1839  M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
1840  emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1841  }
1842 
1843  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1844  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
1846  emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1847  /* reload */
1848  M_ALD(REG_ITMP3, REG_PV, disp);
1849  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1850 
1852  M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*4, REG_ITMP2);
1855  emit_label_beq(cd, BRANCH_LABEL_7); /* good */
1856 
1858  if (super == NULL)
1860 
1861  /* reload s1, might have been destroyed */
1862  emit_load_s1(jd, iptr, REG_ITMP1);
1864 
1867  /* reload s1, might have been destroyed */
1868  emit_load_s1(jd, iptr, REG_ITMP1);
1869  }
1870  else {
1871  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
1873  emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP2, s1);
1874  }
1875 
1876  if (super != NULL)
1878  }
1879 
1880  if (super == NULL) {
1883  }
1884 
1885  d = codegen_reg_of_dst(jd, iptr, s1);
1886  }
1887  else {
1888  /* array type cast-check */
1889 
1890  s1 = emit_load_s1(jd, iptr, REG_A0);
1891  M_INTMOVE(s1, REG_A0);
1892 
1893  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1894  disp = dseg_add_unique_address(cd, NULL);
1895 
1897  iptr->sx.s23.s3.c.ref,
1898  disp);
1899  }
1900  else
1901  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
1902 
1903  M_ALD(REG_A1, REG_PV, disp);
1905  M_ALD(REG_ITMP2, REG_PV, disp);
1906  M_MTCTR(REG_ITMP2);
1907  M_JSR;
1908  M_TST(REG_RESULT);
1909  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1910 
1911  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1912  d = codegen_reg_of_dst(jd, iptr, s1);
1913  }
1914  M_INTMOVE(s1, d);
1915  emit_store_dst(jd, iptr, d);
1916  break;
1917 
1918  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1919 
1920  {
1921  classinfo *super;
1922  s4 superindex;
1923 
1924  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1925  super = NULL;
1926  superindex = 0;
1927  }
1928  else {
1929  super = iptr->sx.s23.s3.c.cls;
1930  superindex = super->index;
1931  }
1932 
1933  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1934 
1935  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1936  if (s1 == d) {
1937  M_MOV(s1, REG_ITMP1);
1938  s1 = REG_ITMP1;
1939  }
1940 
1941  /* if class is not resolved, check which code to call */
1942 
1943  if (super == NULL) {
1944  M_TST(s1);
1945  M_CLR(d);
1946  emit_label_beq(cd, BRANCH_LABEL_1);
1947 
1948  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
1949 
1951  iptr->sx.s23.s3.c.ref, disp);
1952 
1953  M_ILD(REG_ITMP3, REG_PV, disp);
1955  emit_label_beq(cd, BRANCH_LABEL_2);
1956  }
1957 
1958  /* interface instanceof code */
1959 
1960  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1961  if (super == NULL) {
1962  /* If d == REG_ITMP2, then it's destroyed in check
1963  code above. */
1964  if (d == REG_ITMP2)
1965  M_CLR(d);
1966 
1969  iptr->sx.s23.s3.c.ref, 0);
1970  }
1971  else {
1972  M_TST(s1);
1973  M_CLR(d);
1974  emit_label_beq(cd, BRANCH_LABEL_3);
1975  }
1976 
1977  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
1978  M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
1979  M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
1980  M_BLE(3);
1982  OFFSET(vftbl_t, interfacetable[0]) -
1983  superindex * sizeof(methodptr*));
1984 
1985  M_ADDIC(REG_ITMP1, -1, d);
1986  M_SUBE(REG_ITMP1, d, d);
1987 
1988  if (super == NULL)
1990  else
1992  }
1993 
1994  /* class instanceof code */
1995 
1996  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1997  if (super == NULL) {
1999 
2000  disp = dseg_add_unique_address(cd, NULL);
2001 
2003  iptr->sx.s23.s3.c.ref,
2004  disp);
2005  }
2006  else {
2007  disp = dseg_add_address(cd, super->vftbl);
2008 
2009  M_TST(s1);
2010  M_CLR(d);
2011  emit_label_beq(cd, BRANCH_LABEL_5);
2012  }
2013 
2014  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2015  M_ALD(REG_ITMP3, REG_PV, disp);
2016 
2017  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2018  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2020  M_ALD(REG_ITMP1, REG_ITMP1, 0);
2022  emit_label_bne(cd, BRANCH_LABEL_8);
2023  ICONST(d, 1);
2024  emit_label_br(cd, BRANCH_LABEL_6); /* true */
2026 
2027  if (super == NULL) {
2028  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2029  M_CMPI(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]));
2030  emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2031  }
2032 
2033  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2034 
2035  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2037  emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2038  /* reload */
2039  M_ALD(REG_ITMP3, REG_PV, disp);
2040  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2041 
2043  M_IADD_IMM(REG_ITMP2, -DISPLAY_SIZE*4, REG_ITMP2);
2045  /* This seems to be the canonical sequence to emulate
2046  * the Alpha instruction M_CMPEQ. */
2047  M_XOR(REG_ITMP1, REG_ITMP3, d);
2048  M_CNTLZ(d, d);
2049  M_RLWINM(d, 27, 5, 31, d);
2050 
2051  if (d == REG_ITMP2)
2054  if (super == NULL)
2056  if (d == REG_ITMP2) {
2057  M_CLR(d);
2058 
2060  }
2062  }
2063  else {
2064  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2065  M_XOR(REG_ITMP2, REG_ITMP3, d);
2066  M_CNTLZ(d, d);
2067  M_RLWINM(d, 27, 5, 31, d);
2068  }
2069 
2070  if (super != NULL)
2072  }
2073 
2074  if (super == NULL) {
2077  }
2078 
2079  emit_store_dst(jd, iptr, d);
2080  }
2081  break;
2082 
2083  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2084 
2085  /* check for negative sizes and copy sizes to stack if necessary */
2086 
2087  MCODECHECK((iptr->s1.argcount << 1) + 64);
2088 
2089  for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2090  var = VAR(iptr->sx.s23.s2.args[s1]);
2091 
2092  /* copy SAVEDVAR sizes to stack */
2093 
2094  /* Already Preallocated? */
2095  if (!(var->flags & PREALLOC)) {
2096  s2 = emit_load(jd, iptr, var, REG_ITMP1);
2097 #if defined(__DARWIN__)
2098  M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
2099 #else
2100  M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
2101 #endif
2102  }
2103  }
2104 
2105  /* a0 = dimension count */
2106 
2107  ICONST(REG_A0, iptr->s1.argcount);
2108 
2109  /* is patcher function set? */
2110 
2111  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2112  disp = dseg_add_unique_address(cd, NULL);
2113 
2115  iptr->sx.s23.s3.c.ref, disp);
2116  }
2117  else
2118  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2119 
2120  /* a1 = arraydescriptor */
2121 
2122  M_ALD(REG_A1, REG_PV, disp);
2123 
2124  /* a2 = pointer to dimensions = stack pointer */
2125 
2126 #if defined(__DARWIN__)
2128 #else
2129  M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
2130 #endif
2131 
2133  M_ALD(REG_ITMP3, REG_PV, disp);
2134  M_MTCTR(REG_ITMP3);
2135  M_JSR;
2136 
2137  /* check for exception before result assignment */
2138 
2139  emit_exception_check(cd, iptr);
2140 
2141  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2142  M_INTMOVE(REG_RESULT, d);
2143  emit_store_dst(jd, iptr, d);
2144  break;
2145 
2146  default:
2147  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2148  } /* switch */
2149 }
2150 
2151 
2152 /* codegen_emit_stub_native ****************************************************
2153 
2154  Emits a stub routine which calls a native method.
2155 
2156 *******************************************************************************/
2157 
2158 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2159 {
2160  methodinfo *m;
2161  codeinfo *code;
2162  codegendata *cd;
2163  methoddesc *md;
2164  s4 i, j; /* count variables */
2165  s4 t;
2166  s4 s1, s2;
2167  int disp;
2168 
2169  /* Sanity check. */
2170 
2171  assert(f != NULL);
2172 
2173  /* Get required compiler data. */
2174 
2175  m = jd->m;
2176  code = jd->code;
2177  cd = jd->cd;
2178 
2179  /* set some variables */
2180 
2181  md = m->parseddesc;
2182 
2183  /* calculate stackframe size */
2184 
2185  cd->stackframesize =
2186  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2187  sizeof(localref_table) / SIZEOF_VOID_P +
2188  4 + /* 4 stackframeinfo arguments (darwin) */
2189  nmd->paramcount +
2190  nmd->memuse;
2191 
2192  /* keep stack 16-byte aligned */
2193 
2194  ALIGN_2(cd->stackframesize);
2195 
2196  /* create method header */
2197 
2198  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2199  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2200  (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2201  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2202  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2203  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2204 
2205  /* generate code */
2206 
2207  M_MFLR(REG_ZERO);
2209  M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2210 
2211 #if defined(ENABLE_GC_CACAO)
2212  /* Save callee saved integer registers in stackframeinfo (GC may
2213  need to recover them during a collection). */
2214 
2215  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2216  OFFSET(stackframeinfo_t, intregs);
2217 
2218  for (i = 0; i < INT_SAV_CNT; i++)
2219  M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2220 #endif
2221 
2222  /* save integer and float argument registers */
2223 
2224  for (i = 0; i < md->paramcount; i++) {
2225  if (!md->params[i].inmemory) {
2226  s1 = md->params[i].regoff;
2227 
2228  switch (md->paramtypes[i].type) {
2229  case TYPE_INT:
2230  case TYPE_ADR:
2231  M_IST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2232  break;
2233  case TYPE_LNG:
2234  M_LST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2235  break;
2236  case TYPE_FLT:
2237  case TYPE_DBL:
2238  M_DST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2239  break;
2240  default:
2241  assert(false);
2242  break;
2243  }
2244  }
2245  }
2246 
2247  /* create native stack info */
2248 
2249  M_MOV(REG_SP, REG_A0);
2250  M_MOV(REG_PV, REG_A1);
2252  M_ALD(REG_ITMP1, REG_PV, disp);
2253  M_MTCTR(REG_ITMP1);
2254  M_JSR;
2255 
2256  /* remember class argument */
2257 
2258  if (m->flags & ACC_STATIC)
2260 
2261  /* restore integer and float argument registers */
2262 
2263  for (i = 0; i < md->paramcount; i++) {
2264  if (!md->params[i].inmemory) {
2265  s1 = md->params[i].regoff;
2266 
2267  switch (md->paramtypes[i].type) {
2268  case TYPE_INT:
2269  case TYPE_ADR:
2270  M_ILD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2271  break;
2272  case TYPE_LNG:
2273  M_LLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2274  break;
2275  case TYPE_FLT:
2276  case TYPE_DBL:
2277  M_DLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2278  break;
2279  default:
2280  assert(false);
2281  break;
2282  }
2283  }
2284  }
2285 
2286  /* copy or spill arguments to new locations */
2287 
2288  for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2289  t = md->paramtypes[i].type;
2290 
2291  if (!md->params[i].inmemory) {
2292  s1 = md->params[i].regoff;
2293  s2 = nmd->params[j].regoff;
2294 
2295  switch (t) {
2296  case TYPE_INT:
2297  case TYPE_ADR:
2298  if (!nmd->params[j].inmemory)
2299  M_INTMOVE(s1, s2);
2300  else
2301  M_IST(s1, REG_SP, s2);
2302  break;
2303 
2304  case TYPE_LNG:
2305  if (!nmd->params[j].inmemory)
2306  M_LNGMOVE(s1, s2);
2307  else
2308  M_LST(s1, REG_SP, s2);
2309  break;
2310 
2311  case TYPE_FLT:
2312  case TYPE_DBL:
2313  /* We only copy spilled float arguments, as the float
2314  argument registers keep unchanged. */
2315  break;
2316 
2317  default:
2318  assert(false);
2319  break;
2320  }
2321  }
2322  else {
2323  s1 = md->params[i].regoff + cd->stackframesize * 8;
2324  s2 = nmd->params[j].regoff;
2325 
2326  switch (t) {
2327  case TYPE_INT:
2328  case TYPE_ADR:
2329  M_ILD(REG_ITMP1, REG_SP, s1);
2330  M_IST(REG_ITMP1, REG_SP, s2);
2331  break;
2332 
2333  case TYPE_LNG:
2336  break;
2337 
2338  case TYPE_FLT:
2339  M_FLD(REG_FTMP1, REG_SP, s1);
2340  M_FST(REG_FTMP1, REG_SP, s2);
2341  break;
2342 
2343  case TYPE_DBL:
2344  M_DLD(REG_FTMP1, REG_SP, s1);
2345  M_DST(REG_FTMP1, REG_SP, s2);
2346  break;
2347 
2348  default:
2349  assert(false);
2350  break;
2351  }
2352  }
2353  }
2354 
2355  /* Handle native Java methods. */
2356 
2357  if (m->flags & ACC_NATIVE) {
2358  /* put class into second argument register */
2359 
2360  if (m->flags & ACC_STATIC)
2362 
2363  /* put env into first argument register */
2364 
2365  disp = dseg_add_address(cd, VM::get_current()->get_jnienv());
2366  M_ALD(REG_A0, REG_PV, disp);
2367  }
2368 
2369  /* Call the native function. */
2370 
2371  disp = dseg_add_functionptr(cd, f);
2372  M_ALD(REG_ITMP3, REG_PV, disp);
2373  M_MTCTR(REG_ITMP3);
2374  M_JSR;
2375 
2376  /* save return value */
2377 
2378  switch (md->returntype.type) {
2379  case TYPE_INT:
2380  case TYPE_ADR:
2381  M_IST(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
2382  break;
2383  case TYPE_LNG:
2385  break;
2386  case TYPE_FLT:
2387  case TYPE_DBL:
2388  M_DST(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
2389  break;
2390  case TYPE_VOID:
2391  break;
2392  default:
2393  assert(false);
2394  break;
2395  }
2396 
2397  /* remove native stackframe info */
2398 
2399  M_MOV(REG_SP, REG_A0);
2400  M_MOV(REG_PV, REG_A1);
2402  M_ALD(REG_ITMP1, REG_PV, disp);
2403  M_MTCTR(REG_ITMP1);
2404  M_JSR;
2406 
2407  /* restore return value */
2408 
2409  switch (md->returntype.type) {
2410  case TYPE_INT:
2411  case TYPE_ADR:
2412  M_ILD(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
2413  break;
2414  case TYPE_LNG:
2416  break;
2417  case TYPE_FLT:
2418  case TYPE_DBL:
2419  M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
2420  break;
2421  case TYPE_VOID:
2422  break;
2423  default:
2424  assert(false);
2425  break;
2426  }
2427 
2428 #if defined(ENABLE_GC_CACAO)
2429  /* Restore callee saved integer registers from stackframeinfo (GC
2430  might have modified them during a collection). */
2431 
2432  disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2433  OFFSET(stackframeinfo_t, intregs);
2434 
2435  for (i = 0; i < INT_SAV_CNT; i++)
2436  M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2437 #endif
2438 
2441  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */
2442 
2443  /* check for exception */
2444 
2446  M_BNE(1); /* if no exception then return */
2447 
2448  M_RET;
2449 
2450  /* handle exception */
2451 
2453 }
2454 
2455 
2456 /*
2457  * These are local overrides for various environment variables in Emacs.
2458  * Please do not remove this and leave it at the end of the file, where
2459  * Emacs will automagically detect them.
2460  * ---------------------------------------------------------------------
2461  * Local variables:
2462  * mode: c
2463  * indent-tabs-mode: t
2464  * c-basic-offset: 4
2465  * tab-width: 4
2466  * End:
2467  * vim:noexpandtab:sw=4:ts=4:
2468  */
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
#define GET_HIGH_REG(a)
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
#define M_ADDE(a, b, c)
Definition: codegen.hpp:187
#define M_CMPU(a, b)
Definition: codegen.hpp:209
#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 REG_A0_A1_PACKED
Definition: md-abi.hpp:135
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
#define M_DMUL(a, b, c)
Definition: codegen.hpp:378
#define ALIGN_2(a)
Definition: global.hpp:72
#define BRANCH_OPT_NONE
#define PATCHER_invokeinterface
#define REG_A1
Definition: md-abi.hpp:36
Definition: jit.hpp:126
#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
#define M_SUBC(a, b, c)
Definition: codegen.hpp:248
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 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_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
#define M_IOR(a, b, d)
Definition: codegen.hpp:177
#define M_IOR_TST(a, b, d)
Definition: codegen.hpp:179
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define REG_ITMP12_PACKED
Definition: md-abi.hpp:131
#define REG_FRESULT
Definition: md-abi.hpp:59
int32_t argcount
Definition: instruction.hpp:64
void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
#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_SUBFIC(a, b, c)
Definition: codegen.hpp:250
#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 LA_LR_OFFSET
Definition: md-abi.hpp:97
#define REG_A2
Definition: md-abi.hpp:37
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
#define M_ISUB(a, b, c)
Definition: codegen.hpp:265
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 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_IAND(a, b, d)
Definition: codegen.hpp:174
#define M_TST(a, b)
Definition: codegen.hpp:428
const s4 abi_registers_integer_saved[]
Definition: md-abi.cpp:75
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define REG_A2_A3_PACKED
Definition: md-abi.hpp:136
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define M_ADDC(a, b, c)
Definition: codegen.hpp:186
#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
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#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 GET_LOW_REG(a)
#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 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 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_IDIV(a)
Definition: codegen.hpp:207
#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_LNGMOVE(a, b)
#define M_STWU(a, b, disp)
Definition: codegen.hpp:338
#define REG_ITMP23_PACKED
Definition: md-abi.hpp:132
#define M_BSEXT(b, c)
Definition: codegen.hpp:247
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define M_ADDME(a, b)
Definition: codegen.hpp:191
#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
#define M_IMUL(a, b, c)
Definition: codegen.hpp:267
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 M_LWZX(a, b, c)
Definition: codegen.hpp:222
#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)
s1_operand_t s1
#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_FDIV(a, b, c)
Definition: codegen.hpp:379
#define REG_FTMP1
Definition: md-abi.hpp:65
#define PATCHER_invokevirtual
Definition: builtin.hpp:60
#define M_SLL_IMM(a, b, c)
Definition: codegen.hpp:310
#define M_IMUL_IMM(a, b, c)
Definition: codegen.hpp:274
#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_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
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_IAND_IMM(a, b, d)
Definition: codegen.hpp:175
#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 M_IOR_IMM(a, b, d)
Definition: codegen.hpp:178
#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
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
#define M_LDAH(a, b, disp)
Definition: codegen.hpp:175
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 REG_RESULT_PACKED
Definition: md-abi.hpp:133
#define M_ILD_INTERN(a, b, disp)
Definition: codegen.hpp:180
#define M_SUBFZE(a, b)
Definition: codegen.hpp:251
#define M_DADD(a, b, c)
Definition: codegen.hpp:374