CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/mips/codegen.cpp - machine code generator for MIPS
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 <stdio.h>
30 
31 #include "vm/types.hpp"
32 
33 #include "md-abi.hpp"
34 #include "md-trap.hpp"
35 
36 #include "vm/jit/mips/arch.hpp"
37 #include "vm/jit/mips/codegen.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/class.hpp"
47 #include "vm/descriptor.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/field.hpp"
50 #include "vm/options.hpp"
51 #include "vm/vm.hpp"
52 
53 #include "vm/jit/abi.hpp"
54 #include "vm/jit/asmpart.hpp"
55 #include "vm/jit/builtin.hpp"
57 #include "vm/jit/dseg.hpp"
58 #include "vm/jit/emit-common.hpp"
59 #include "vm/jit/jit.hpp"
61 #include "vm/jit/parse.hpp"
63 #include "vm/jit/reg.hpp"
64 #include "vm/jit/stacktrace.hpp"
65 #include "vm/jit/trap.hpp"
66 
67 
68 /**
69  * Generates machine code for the method prolog.
70  */
72 {
73  varinfo* var;
74  methoddesc* md;
75  int32_t s1;
76  int32_t p, t, l;
77  int32_t varindex;
78  int i;
79 
80  // Get required compiler data.
81  methodinfo* m = jd->m;
82  codeinfo* code = jd->code;
83  codegendata* cd = jd->cd;
84  registerdata* rd = jd->rd;
85 
86  /* create stack frame (if necessary) */
87 
88  if (cd->stackframesize)
89  M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
90 
91  /* save return address and used callee saved registers */
92 
93  p = cd->stackframesize;
94  if (!code_is_leafmethod(code)) {
95  p--; M_AST(REG_RA, REG_SP, p * 8);
96  }
97  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
98  p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
99  }
100  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
101  p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
102  }
103 
104  /* take arguments out of register or stack frame */
105 
106  md = m->parseddesc;
107 
108  for (p = 0, l = 0; p < md->paramcount; p++) {
109  t = md->paramtypes[p].type;
110 
111  varindex = jd->local_map[l * 5 + t];
112 
113  l++;
114  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
115  l++;
116 
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)) { /* integer args */
124  if (!md->params[p].inmemory) { /* register arguments */
125 #if SIZEOF_VOID_P == 8
126  if (!(var->flags & INMEMORY))
127  M_INTMOVE(s1, var->vv.regoff);
128  else
129  M_LST(s1, REG_SP, var->vv.regoff);
130 #else
131  if (!(var->flags & INMEMORY)) {
132  if (IS_2_WORD_TYPE(t))
133  M_LNGMOVE(s1, var->vv.regoff);
134  else
135  M_INTMOVE(s1, var->vv.regoff);
136  }
137  else {
138  if (IS_2_WORD_TYPE(t))
139  M_LST(s1, REG_SP, var->vv.regoff);
140  else
141  M_IST(s1, REG_SP, var->vv.regoff);
142  }
143 #endif
144  }
145  else { /* stack arguments */
146  if (!(var->flags & INMEMORY)) {
147 #if SIZEOF_VOID_P == 8
148  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
149 #else
150  if (IS_2_WORD_TYPE(t))
151  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
152  else
153  M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
154 #endif
155  }
156  else
157  var->vv.regoff = cd->stackframesize * 8 + s1;
158  }
159  }
160  else { /* floating args */
161  if (!md->params[p].inmemory) {
162  if (!(var->flags & INMEMORY)) {
163  if (IS_2_WORD_TYPE(t))
164  emit_dmove(cd, s1, var->vv.regoff);
165  else
166  emit_fmove(cd, s1, var->vv.regoff);
167  }
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  }
175  else {
176  if (!(var->flags & INMEMORY)) {
177  if (IS_2_WORD_TYPE(t))
178  M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
179  else
180  M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
181  }
182  else
183  var->vv.regoff = cd->stackframesize * 8 + s1;
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  p--; M_ALD(REG_RA, REG_SP, p * 8);
209  }
210 
211  /* restore saved registers */
212 
213  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
214  p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
215  }
216  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
217  p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
218  }
219 
220  /* deallocate stack and return */
221 
222  if (cd->stackframesize) {
223  int32_t lo, hi, disp;
224 
225  disp = cd->stackframesize * 8;
226  lo = (short) (disp);
227  hi = (short) (((disp) - lo) >> 16);
228 
229  if (hi == 0) {
230  M_RET(REG_RA);
231  M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
232  } else {
233  M_LUI(REG_ITMP3,hi);
235  M_RET(REG_RA);
236  M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
237  }
238 
239  } else {
240  M_RET(REG_RA);
241  M_NOP;
242  }
243 }
244 
245 
246 /**
247  * Generates machine code for one ICMD.
248  */
250 {
251  varinfo* var;
252  builtintable_entry* bte;
253  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
254  unresolved_method* um;
255  fieldinfo* fi;
256  unresolved_field* uf = NULL;
257  int32_t fieldtype;
258  int32_t s1, s2, s3, d = 0;
259  int32_t disp;
260 
261  // Get required compiler data.
262  codegendata* cd = jd->cd;
263 
264  switch (iptr->opc) {
265 
266  /* constant operations ************************************************/
267 
268  case ICMD_LCONST: /* ... ==> ..., constant */
269 
270 #if SIZEOF_VOID_P == 8
271  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
272 #else
273  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
274 #endif
275  LCONST(d, iptr->sx.val.l);
276  emit_store_dst(jd, iptr, d);
277  break;
278 
279  case ICMD_FCONST: /* ... ==> ..., constant */
280 
281  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
282  disp = dseg_add_float(cd, iptr->sx.val.f);
283  M_FLD(d, REG_PV, disp);
284  emit_store_dst(jd, iptr, d);
285  break;
286 
287  case ICMD_DCONST: /* ... ==> ..., constant */
288 
289  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
290  disp = dseg_add_double(cd, iptr->sx.val.d);
291  M_DLD(d, REG_PV, disp);
292  emit_store_dst(jd, iptr, d);
293  break;
294 
295  case ICMD_ACONST: /* ... ==> ..., constant */
296 
297  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
298 
299  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
300  constant_classref *cr = iptr->sx.val.c.ref;
301  disp = dseg_add_unique_address(cd, cr);
302 
304  cr, disp);
305 
306  M_ALD(d, REG_PV, disp);
307  }
308  else {
309  if (iptr->sx.val.anyptr == NULL)
310  M_INTMOVE(REG_ZERO, d);
311  else {
312  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
313  M_ALD(d, REG_PV, disp);
314  }
315  }
316  emit_store_dst(jd, iptr, d);
317  break;
318 
319 
320  /* integer operations *************************************************/
321 
322  case ICMD_INEG: /* ..., value ==> ..., - value */
323 
324  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
325  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
326  M_ISUB(REG_ZERO, s1, d);
327  emit_store_dst(jd, iptr, d);
328  break;
329 
330  case ICMD_LNEG: /* ..., value ==> ..., - value */
331 
332 #if SIZEOF_VOID_P == 8
333  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
334  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
335  M_LSUB(REG_ZERO, s1, d);
336 #else
337  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
338  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
343 #endif
344  emit_store_dst(jd, iptr, d);
345  break;
346 
347  case ICMD_I2L: /* ..., value ==> ..., value */
348 
349  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
350 #if SIZEOF_VOID_P == 8
351  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
352  M_INTMOVE(s1, d);
353 #else
354  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
355  M_INTMOVE(s1, GET_LOW_REG(d));
356  M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
357 #endif
358  emit_store_dst(jd, iptr, d);
359  break;
360 
361  case ICMD_L2I: /* ..., value ==> ..., value */
362 
363 #if SIZEOF_VOID_P == 8
364  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
365  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
366  M_ISLL_IMM(s1, 0, d);
367 #else
368  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
369  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
370  M_INTMOVE(GET_LOW_REG(s1), d);
371 #endif
372  emit_store_dst(jd, iptr, d);
373  break;
374 
375  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
376 
377  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
378  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
379 #if SIZEOF_VOID_P == 8
380  M_LSLL_IMM(s1, 56, d);
381  M_LSRA_IMM( d, 56, d);
382 #else
383  M_ISLL_IMM(s1, 24, d);
384  M_ISRA_IMM( d, 24, d);
385 #endif
386  emit_store_dst(jd, iptr, d);
387  break;
388 
389  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
390 
391  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
392  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
393  M_AND_IMM(s1, 0xffff, d);
394  emit_store_dst(jd, iptr, d);
395  break;
396 
397  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
398 
399  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
400  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
401 #if SIZEOF_VOID_P == 8
402  M_LSLL_IMM(s1, 48, d);
403  M_LSRA_IMM( d, 48, d);
404 #else
405  M_ISLL_IMM(s1, 16, d);
406  M_ISRA_IMM( d, 16, d);
407 #endif
408  emit_store_dst(jd, iptr, d);
409  break;
410 
411 
412  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
413 
414  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
415  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
416  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
417  M_IADD(s1, s2, d);
418  emit_store_dst(jd, iptr, d);
419  break;
420 
421  case ICMD_IINC:
422  case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
423  /* sx.val.i = constant */
424 
425  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
426  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
427  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
428  M_IADD_IMM(s1, iptr->sx.val.i, d);
429  else {
430  ICONST(REG_ITMP2, iptr->sx.val.i);
431  M_IADD(s1, REG_ITMP2, d);
432  }
433  emit_store_dst(jd, iptr, d);
434  break;
435 
436  case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
437 
438 #if SIZEOF_VOID_P == 8
439  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
440  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
441  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
442  M_LADD(s1, s2, d);
443 #else
444  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
445  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
446  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
447  M_IADD(s1, s2, GET_HIGH_REG(d));
448  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
449  s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
450  if (s1 == GET_LOW_REG(d)) {
451  M_MOV(s1, REG_ITMP3);
452  s1 = REG_ITMP3;
453  }
454  M_IADD(s1, s2, GET_LOW_REG(d));
455  M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
457 #endif
458  emit_store_dst(jd, iptr, d);
459  break;
460 
461  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
462  /* sx.val.l = constant */
463 
464 #if SIZEOF_VOID_P == 8
465  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
466  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
467  if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
468  M_LADD_IMM(s1, iptr->sx.val.l, d);
469  else {
470  LCONST(REG_ITMP2, iptr->sx.val.l);
471  M_LADD(s1, REG_ITMP2, d);
472  }
473 #else
474  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
475  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
476  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
477  M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
480  }
481  else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
482  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
483  M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
485  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
486  M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
488  }
489  else {
490  ICONST(REG_ITMP1, iptr->sx.val.l & 0xffffffff);
491  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
492  M_IADD(s1, REG_ITMP1, GET_LOW_REG(d));
493  M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
494  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
495  M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
496  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
498  }
499 #endif
500  emit_store_dst(jd, iptr, d);
501  break;
502 
503  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
504 
505  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
507  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
508  M_ISUB(s1, s2, d);
509  emit_store_dst(jd, iptr, d);
510  break;
511 
512  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
513  /* sx.val.i = constant */
514 
515  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
516  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517  if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
518  M_IADD_IMM(s1, -iptr->sx.val.i, d);
519  else {
520  ICONST(REG_ITMP2, iptr->sx.val.i);
521  M_ISUB(s1, REG_ITMP2, d);
522  }
523  emit_store_dst(jd, iptr, d);
524  break;
525 
526  case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
527 
528 #if SIZEOF_VOID_P == 8
529  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
531  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
532  M_LSUB(s1, s2, d);
533 #else
534  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
535  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
536  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
537  M_ISUB(s1, s2, GET_HIGH_REG(d));
538  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
539  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
540  M_CMPULT(s1, s2, REG_ITMP3);
542  /* if s1 is equal to REG_ITMP3 we have to reload it, since
543  the CMPULT instruction destroyed it */
544  if (s1 == REG_ITMP3)
545  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
546  M_ISUB(s1, s2, GET_LOW_REG(d));
547 
548 #endif
549  emit_store_dst(jd, iptr, d);
550  break;
551 
552  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
553  /* sx.val.l = constant */
554 
555 #if SIZEOF_VOID_P == 8
556  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
558  if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
559  M_LADD_IMM(s1, -iptr->sx.val.l, d);
560  else {
561  LCONST(REG_ITMP2, iptr->sx.val.l);
562  M_LSUB(s1, REG_ITMP2, d);
563  }
564 #else
565  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
566  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
567  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
568  M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
569  M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
570  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
571  M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
573  }
574  else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
575  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
576  M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
577  M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
579  }
580  else {
581  ICONST(REG_ITMP1, iptr->sx.val.l & 0xffffffff);
582  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
583  M_ISUB(s1, REG_ITMP1, GET_LOW_REG(d));
585  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
586  M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
587  ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
589  }
590 #endif
591  emit_store_dst(jd, iptr, d);
592  break;
593 
594  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
595 
596  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
599  M_IMUL(s1, s2);
600  M_MFLO(d);
601  M_NOP;
602  M_NOP;
603  emit_store_dst(jd, iptr, d);
604  break;
605 
606  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
607  /* sx.val.i = constant */
608 
609  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611  ICONST(REG_ITMP2, iptr->sx.val.i);
612  M_IMUL(s1, REG_ITMP2);
613  M_MFLO(d);
614  M_NOP;
615  M_NOP;
616  emit_store_dst(jd, iptr, d);
617  break;
618 
619  case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
620 
621 #if SIZEOF_VOID_P == 8
622  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
624  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625  M_LMUL(s1, s2);
626  M_MFLO(d);
627  M_NOP;
628  M_NOP;
629 #else
630  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
631  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
632  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
633  M_IMUL(s2, s1);
634  M_MFLO(REG_ITMP3);
635  M_NOP;
636  M_NOP;
637  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
638  M_IMULU(s2, s1);
639  M_MFHI(GET_HIGH_REG(d));
640  M_MFLO(GET_LOW_REG(d));
641  M_NOP;
642  M_NOP;
644 
645  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
646  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
647  M_IMUL(s1, s2);
648  M_MFLO(s2);
649  /* XXX do we need nops here? */
650 #endif
651  emit_store_dst(jd, iptr, d);
652  break;
653 
654  case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
655  /* sx.val.l = constant */
656 
657  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
659  LCONST(REG_ITMP2, iptr->sx.val.l);
660  M_LMUL(s1, REG_ITMP2);
661  M_MFLO(d);
662  M_NOP;
663  M_NOP;
664  emit_store_dst(jd, iptr, d);
665  break;
666 
667  case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
668 
669  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
671  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672  emit_arithmetic_check(cd, iptr, s2);
673  M_IDIV(s1, s2);
674  M_MFLO(d);
675  M_NOP;
676  M_NOP;
677  emit_store_dst(jd, iptr, d);
678  break;
679 
680  case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
681 
682  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
684  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685  emit_arithmetic_check(cd, iptr, s2);
686  M_IDIV(s1, s2);
687  M_MFHI(d);
688  M_NOP;
689  M_NOP;
690  emit_store_dst(jd, iptr, d);
691  break;
692 
693 #if SIZEOF_VOID_P == 8
694 
695  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
696 
697  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
699  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700  emit_arithmetic_check(cd, iptr, s2);
701  M_LDIV(s1, s2);
702  M_MFLO(d);
703  M_NOP;
704  M_NOP;
705  emit_store_dst(jd, iptr, d);
706  break;
707 
708  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
709 
710  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
712  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
713  emit_arithmetic_check(cd, iptr, s2);
714  M_LDIV(s1, s2);
715  M_MFHI(d);
716  M_NOP;
717  M_NOP;
718  emit_store_dst(jd, iptr, d);
719  break;
720 
721 #else /* SIZEOF_VOID_P == 8 */
722 
723  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
724  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
725 
726  s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
727  s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
728 
729  /* XXX TODO: only do this if arithmetic check is really done! */
731  emit_arithmetic_check(cd, iptr, REG_ITMP3);
732 
735 
736  bte = iptr->sx.s23.s3.bte;
737  disp = dseg_add_functionptr(cd, bte->fp);
738  M_ALD(REG_ITMP3, REG_PV, disp);
740  M_NOP;
741 
742  d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
744  emit_store_dst(jd, iptr, d);
745  break;
746 
747 #endif /* SIZEOF_VOID_P == 8 */
748 
749  case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
750  /* val.i = constant */
751 
752  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 #if SIZEOF_VOID_P == 8
755  M_LSRA_IMM(s1, 63, REG_ITMP2);
756  M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
757  M_LADD(s1, REG_ITMP2, REG_ITMP2);
758  M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
759 #else
760  M_ISRA_IMM(s1, 31, REG_ITMP2);
761  M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
762  M_IADD(s1, REG_ITMP2, REG_ITMP2);
763  M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
764 #endif
765  emit_store_dst(jd, iptr, d);
766  break;
767 
768  case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
769  /* val.i = constant */
770 
771  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
772  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773  if (s1 == d) {
774  M_MOV(s1, REG_ITMP1);
775  s1 = REG_ITMP1;
776  }
777  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
778  M_AND_IMM(s1, iptr->sx.val.i, d);
779  M_BGEZ(s1, 4);
780  M_NOP;
781  M_ISUB(REG_ZERO, s1, d);
782  M_AND_IMM(d, iptr->sx.val.i, d);
783  }
784  else {
785  ICONST(REG_ITMP3, iptr->sx.val.i);
786  M_AND(s1, REG_ITMP3, d);
787  M_BGEZ(s1, 4);
788  M_NOP;
789  M_ISUB(REG_ZERO, s1, d);
790  M_AND(d, REG_ITMP3, d);
791  }
792  M_ISUB(REG_ZERO, d, d);
793  emit_store_dst(jd, iptr, d);
794  break;
795 
796 #if SIZEOF_VOID_P == 8
797 
798  case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
799  /* val.i = constant */
800 
801  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803  M_LSRA_IMM(s1, 63, REG_ITMP2);
804  M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
805  M_LADD(s1, REG_ITMP2, REG_ITMP2);
806  M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
807  emit_store_dst(jd, iptr, d);
808  break;
809 
810  case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
811  /* val.l = constant */
812 
813  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815  if (s1 == d) {
816  M_MOV(s1, REG_ITMP1);
817  s1 = REG_ITMP1;
818  }
819  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
820  M_AND_IMM(s1, iptr->sx.val.l, d);
821  M_BGEZ(s1, 4);
822  M_NOP;
823  M_LSUB(REG_ZERO, s1, d);
824  M_AND_IMM(d, iptr->sx.val.l, d);
825  }
826  else {
827  LCONST(REG_ITMP2, iptr->sx.val.l);
828  M_AND(s1, REG_ITMP2, d);
829  M_BGEZ(s1, 4);
830  M_NOP;
831  M_LSUB(REG_ZERO, s1, d);
832  M_AND(d, REG_ITMP2, d);
833  }
834  M_LSUB(REG_ZERO, d, d);
835  emit_store_dst(jd, iptr, d);
836  break;
837 
838 #endif /* SIZEOF_VOID_P == 8 */
839 
840  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
841 
842  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
843  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
844  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845  M_ISLL(s1, s2, d);
846  emit_store_dst(jd, iptr, d);
847  break;
848 
849  case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
850  /* sx.val.i = constant */
851 
852  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
853  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
854  M_ISLL_IMM(s1, iptr->sx.val.i, d);
855  emit_store_dst(jd, iptr, d);
856  break;
857 
858  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
859 
860  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
862  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863  M_ISRA(s1, s2, d);
864  emit_store_dst(jd, iptr, d);
865  break;
866 
867  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
868  /* sx.val.i = constant */
869 
870  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
871  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
872  M_ISRA_IMM(s1, iptr->sx.val.i, d);
873  emit_store_dst(jd, iptr, d);
874  break;
875 
876  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
877 
878  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
879  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
880  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
881  M_ISRL(s1, s2, d);
882  emit_store_dst(jd, iptr, d);
883  break;
884 
885  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
886  /* sx.val.i = constant */
887 
888  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
889  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890  M_ISRL_IMM(s1, iptr->sx.val.i, d);
891  emit_store_dst(jd, iptr, d);
892  break;
893 
894  case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
895 
896 #if SIZEOF_VOID_P == 8
897  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
898  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
899  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900  M_LSLL(s1, s2, d);
901 #else
902  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
903  s2 = emit_load_s2(jd, iptr, REG_ITMP3);
904  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
905 
906  M_ISLL(s2, 26, REG_ITMP1);
907  M_BGEZ(REG_ITMP1, 3);
908  M_NOP;
909 
910  M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
911  M_BR(7);
912  M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
913 
914 #if 1
915  M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
916 #endif
917  M_BEQZ(REG_ITMP1, 4);
918  M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
919 
920  M_ISUB(s2, REG_ZERO, REG_ITMP3);
923 
924 #if 0
925  M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
926 #endif
927 #endif
928  emit_store_dst(jd, iptr, d);
929  break;
930 
931 #if SIZEOF_VOID_P == 8
932 
933  case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
934  /* sx.val.i = constant */
935 
936  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
937  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
938  M_LSLL_IMM(s1, iptr->sx.val.i, d);
939  emit_store_dst(jd, iptr, d);
940  break;
941 
942  case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
943 
944  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
945  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
946  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
947  M_LSRA(s1, s2, d);
948  emit_store_dst(jd, iptr, d);
949  break;
950 
951  case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
952  /* sx.val.i = constant */
953 
954  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
955  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
956  M_LSRA_IMM(s1, iptr->sx.val.i, d);
957  emit_store_dst(jd, iptr, d);
958  break;
959 
960  case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
961 
962  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
963  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
964  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
965  M_LSRL(s1, s2, d);
966  emit_store_dst(jd, iptr, d);
967  break;
968 
969  case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
970  /* sx.val.i = constant */
971 
972  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974  M_LSRL_IMM(s1, iptr->sx.val.i, d);
975  emit_store_dst(jd, iptr, d);
976  break;
977 
978 #endif /* SIZEOF_VOID_P == 8 */
979 
980  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
981 
982  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
983  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
984  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
985  M_AND(s1, s2, d);
986  emit_store_dst(jd, iptr, d);
987  break;
988 
989  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
990  /* sx.val.i = constant */
991 
992  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
993  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
994  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
995  M_AND_IMM(s1, iptr->sx.val.i, d);
996  else {
997  ICONST(REG_ITMP2, iptr->sx.val.i);
998  M_AND(s1, REG_ITMP2, d);
999  }
1000  emit_store_dst(jd, iptr, d);
1001  break;
1002 
1003  case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1004 
1005 #if SIZEOF_VOID_P == 8
1006  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1007  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1008  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1009  M_AND(s1, s2, d);
1010 #else
1011  s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1012  s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1013  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1014  M_AND(s1, s2, GET_LOW_REG(d));
1015  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1016  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1017  M_AND(s1, s2, GET_HIGH_REG(d));
1018 #endif
1019  emit_store_dst(jd, iptr, d);
1020  break;
1021 
1022  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1023  /* sx.val.l = constant */
1024 
1025 #if SIZEOF_VOID_P == 8
1026  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1027  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1028  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1029  M_AND_IMM(s1, iptr->sx.val.l, d);
1030  else {
1031  LCONST(REG_ITMP2, iptr->sx.val.l);
1032  M_AND(s1, REG_ITMP2, d);
1033  }
1034 #else
1035  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1036  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1037  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1038  M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1039  M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1040  }
1041  else {
1042  LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1043  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1045  s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1047  }
1048 #endif
1049  emit_store_dst(jd, iptr, d);
1050  break;
1051 
1052  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1053 
1054  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1056  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057  M_OR(s1, s2, d);
1058  emit_store_dst(jd, iptr, d);
1059  break;
1060 
1061  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1062  /* sx.val.i = constant */
1063 
1064  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1067  M_OR_IMM(s1, iptr->sx.val.i, d);
1068  else {
1069  ICONST(REG_ITMP2, iptr->sx.val.i);
1070  M_OR(s1, REG_ITMP2, d);
1071  }
1072  emit_store_dst(jd, iptr, d);
1073  break;
1074 
1075  case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1076 
1077 #if SIZEOF_VOID_P == 8
1078  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1080  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1081  M_OR(s1, s2, d);
1082 #else
1083  s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1084  s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1085  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1086  M_OR(s1, s2, GET_LOW_REG(d));
1087  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1088  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1089  M_OR(s1, s2, GET_HIGH_REG(d));
1090 #endif
1091  emit_store_dst(jd, iptr, d);
1092  break;
1093 
1094  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1095  /* sx.val.l = constant */
1096 
1097 #if SIZEOF_VOID_P == 8
1098  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1099  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1100  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1101  M_OR_IMM(s1, iptr->sx.val.l, d);
1102  else {
1103  LCONST(REG_ITMP2, iptr->sx.val.l);
1104  M_OR(s1, REG_ITMP2, d);
1105  }
1106 #else
1107  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1108  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1109  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1110  M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1111  M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1112  }
1113  else {
1114  LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1115  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1117  s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1119  }
1120 #endif
1121  emit_store_dst(jd, iptr, d);
1122  break;
1123 
1124  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1125 
1126  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1127  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1129  M_XOR(s1, s2, d);
1130  emit_store_dst(jd, iptr, d);
1131  break;
1132 
1133  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1134  /* sx.val.i = constant */
1135 
1136  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1137  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1138  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1139  M_XOR_IMM(s1, iptr->sx.val.i, d);
1140  else {
1141  ICONST(REG_ITMP2, iptr->sx.val.i);
1142  M_XOR(s1, REG_ITMP2, d);
1143  }
1144  emit_store_dst(jd, iptr, d);
1145  break;
1146 
1147  case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1148 
1149 #if SIZEOF_VOID_P == 8
1150  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1152  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1153  M_XOR(s1, s2, d);
1154 #else
1155  s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1156  s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1157  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1158  M_XOR(s1, s2, GET_LOW_REG(d));
1159  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1160  s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1161  M_XOR(s1, s2, GET_HIGH_REG(d));
1162 #endif
1163  emit_store_dst(jd, iptr, d);
1164  break;
1165 
1166  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1167  /* sx.val.l = constant */
1168 
1169 #if SIZEOF_VOID_P == 8
1170  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1171  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1172  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1173  M_XOR_IMM(s1, iptr->sx.val.l, d);
1174  else {
1175  LCONST(REG_ITMP2, iptr->sx.val.l);
1176  M_XOR(s1, REG_ITMP2, d);
1177  }
1178 #else
1179  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1180  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1181  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1182  M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1183  M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1184  }
1185  else {
1186  LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1187  s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1189  s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1191  }
1192 #endif
1193  emit_store_dst(jd, iptr, d);
1194  break;
1195 
1196 
1197  case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1198 
1199 #if SIZEOF_VOID_P == 8
1200  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1202  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1203  M_CMPLT(s1, s2, REG_ITMP3);
1204  M_CMPLT(s2, s1, REG_ITMP1);
1205  M_LSUB(REG_ITMP1, REG_ITMP3, d);
1206 #else
1207  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1208  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1209  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1210  M_CMPLT(s1, s2, REG_ITMP3);
1211  M_CMPLT(s2, s1, REG_ITMP1);
1212  M_ISUB(REG_ITMP1, REG_ITMP3, d);
1213  emit_label_bnez(cd, BRANCH_LABEL_1, d);
1214  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1215  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1216  M_CMPULT(s1, s2, REG_ITMP3);
1217  M_CMPULT(s2, s1, REG_ITMP1);
1218  M_ISUB(REG_ITMP1, REG_ITMP3, d);
1220 #endif
1221  emit_store_dst(jd, iptr, d);
1222  break;
1223 
1224 
1225  /* floating operations ************************************************/
1226 
1227  case ICMD_FNEG: /* ..., value ==> ..., - value */
1228 
1229  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1230  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1231  M_FNEG(s1, d);
1232  emit_store_dst(jd, iptr, d);
1233  break;
1234 
1235  case ICMD_DNEG: /* ..., value ==> ..., - value */
1236 
1237  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1238  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1239  M_DNEG(s1, d);
1240  emit_store_dst(jd, iptr, d);
1241  break;
1242 
1243  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1244 
1245  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1247  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1248  M_FADD(s1, s2, d);
1249  emit_store_dst(jd, iptr, d);
1250  break;
1251 
1252  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1253 
1254  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1255  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1256  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1257  M_DADD(s1, s2, d);
1258  emit_store_dst(jd, iptr, d);
1259  break;
1260 
1261  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1262 
1263  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1265  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1266  M_FSUB(s1, s2, d);
1267  emit_store_dst(jd, iptr, d);
1268  break;
1269 
1270  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1271 
1272  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1273  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1274  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1275  M_DSUB(s1, s2, d);
1276  emit_store_dst(jd, iptr, d);
1277  break;
1278 
1279  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1280 
1281  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1282  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1283  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1284  M_FMUL(s1, s2, d);
1285  emit_store_dst(jd, iptr, d);
1286  break;
1287 
1288  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1289 
1290  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1291  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1292  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1293  M_DMUL(s1, s2, d);
1294  emit_store_dst(jd, iptr, d);
1295  break;
1296 
1297  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1298 
1299  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1300  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1301  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1302  M_FDIV(s1, s2, d);
1303  emit_store_dst(jd, iptr, d);
1304  break;
1305 
1306  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1307 
1308  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1309  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1310  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1311  M_DDIV(s1, s2, d);
1312  emit_store_dst(jd, iptr, d);
1313  break;
1314 
1315 #if 0
1316  case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1317 
1318  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1319  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1320  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1321  M_FDIV(s1,s2, REG_FTMP3);
1324  M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1325  M_FSUB(s1, REG_FTMP3, d);
1326  emit_store_dst(jd, iptr, d);
1327  break;
1328 
1329  case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1330 
1331  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1332  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1333  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1334  M_DDIV(s1,s2, REG_FTMP3);
1337  M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1338  M_DSUB(s1, REG_FTMP3, d);
1339  emit_store_dst(jd, iptr, d);
1340  break;
1341 #endif
1342 
1343  case ICMD_I2F: /* ..., value ==> ..., (float) value */
1344  case ICMD_L2F:
1345  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1346  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1347  M_MOVLD(s1, d);
1348  M_CVTLF(d, d);
1349  emit_store_dst(jd, iptr, d);
1350  break;
1351 
1352  case ICMD_I2D: /* ..., value ==> ..., (double) value */
1353  case ICMD_L2D:
1354  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1356  M_MOVLD(s1, d);
1357  M_CVTLD(d, d);
1358  emit_store_dst(jd, iptr, d);
1359  break;
1360 
1361 #if 0
1362  /* XXX these do not work correctly */
1363 
1364  case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1365 
1366  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368  M_TRUNCFI(s1, REG_FTMP1);
1369  M_MOVDI(REG_FTMP1, d);
1370  M_NOP;
1371  emit_store_dst(jd, iptr, d);
1372  break;
1373 
1374  case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1375 
1376  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1377  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1378  M_TRUNCDI(s1, REG_FTMP1);
1379  M_MOVDI(REG_FTMP1, d);
1380  M_NOP;
1381  emit_store_dst(jd, iptr, d);
1382  break;
1383 
1384  case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1385 
1386  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1387  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1388  M_TRUNCFL(s1, REG_FTMP1);
1389  M_MOVDL(REG_FTMP1, d);
1390  M_NOP;
1391  emit_store_dst(jd, iptr, d);
1392  break;
1393 
1394  case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1395 
1396  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1397  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1398  M_TRUNCDL(s1, REG_FTMP1);
1399  M_MOVDL(REG_FTMP1, d);
1400  M_NOP;
1401  emit_store_dst(jd, iptr, d);
1402  break;
1403 #endif
1404 
1405  case ICMD_F2D: /* ..., value ==> ..., (double) value */
1406 
1407  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1408  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1409  M_CVTFD(s1, d);
1410  emit_store_dst(jd, iptr, d);
1411  break;
1412 
1413  case ICMD_D2F: /* ..., value ==> ..., (double) value */
1414 
1415  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1416  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1417  M_CVTDF(s1, d);
1418  emit_store_dst(jd, iptr, d);
1419  break;
1420 
1421 #if SUPPORT_FLOAT_CMP
1422  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1423 
1424  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1425  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1426  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1427  M_FCMPULEF(s1, s2);
1428  M_FBT(3);
1429  M_AADD_IMM(REG_ZERO, 1, d);
1430  M_BR(4);
1431  M_NOP;
1432  M_FCMPEQF(s1, s2);
1433  M_ASUB_IMM(REG_ZERO, 1, d);
1434  M_CMOVT(REG_ZERO, d);
1435  emit_store_dst(jd, iptr, d);
1436  break;
1437 
1438  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1439 
1440  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1441  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1442  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1443  M_FCMPOLTF(s1, s2);
1444  M_FBF(3);
1445  M_ASUB_IMM(REG_ZERO, 1, d);
1446  M_BR(4);
1447  M_NOP;
1448  M_FCMPEQF(s1, s2);
1449  M_AADD_IMM(REG_ZERO, 1, d);
1450  M_CMOVT(REG_ZERO, d);
1451  emit_store_dst(jd, iptr, d);
1452  break;
1453 #endif
1454 
1455 #if SUPPORT_DOUBLE_CMP
1456  case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1457 
1458  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1459  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1460  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1461  M_FCMPULED(s1, s2);
1462  M_FBT(3);
1463  M_AADD_IMM(REG_ZERO, 1, d);
1464  M_BR(4);
1465  M_NOP;
1466  M_FCMPEQD(s1, s2);
1467  M_ASUB_IMM(REG_ZERO, 1, d);
1468  M_CMOVT(REG_ZERO, d);
1469  emit_store_dst(jd, iptr, d);
1470  break;
1471 
1472  case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1473 
1474  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1475  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1476  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1477  M_FCMPOLTD(s1, s2);
1478  M_FBF(3);
1479  M_ASUB_IMM(REG_ZERO, 1, d);
1480  M_BR(4);
1481  M_NOP;
1482  M_FCMPEQD(s1, s2);
1483  M_AADD_IMM(REG_ZERO, 1, d);
1484  M_CMOVT(REG_ZERO, d);
1485  emit_store_dst(jd, iptr, d);
1486  break;
1487 #endif
1488 
1489 
1490  /* memory operations **************************************************/
1491 
1492  case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1493 
1494  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1495  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1496  /* implicit null-pointer check */
1497  M_ILD(d, s1, OFFSET(java_array_t, size));
1498  emit_store_dst(jd, iptr, d);
1499  break;
1500 
1501  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1502 
1503  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1504  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1505  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1506  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1507  M_AADD(s2, s1, REG_ITMP3);
1508  /* implicit null-pointer check */
1509  M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1510  emit_store_dst(jd, iptr, d);
1511  break;
1512 
1513  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1514 
1515  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1518  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1519  M_AADD(s2, s1, REG_ITMP3);
1520  M_AADD(s2, REG_ITMP3, REG_ITMP3);
1521  /* implicit null-pointer check */
1522  M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1523  emit_store_dst(jd, iptr, d);
1524  break;
1525 
1526  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1527 
1528  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1529  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1530  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1531  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1532  M_AADD(s2, s1, REG_ITMP3);
1533  M_AADD(s2, REG_ITMP3, REG_ITMP3);
1534  /* implicit null-pointer check */
1535  M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1536  emit_store_dst(jd, iptr, d);
1537  break;
1538 
1539  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1540 
1541  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1544  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1545  M_ASLL_IMM(s2, 2, REG_ITMP3);
1546  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1547  /* implicit null-pointer check */
1549  emit_store_dst(jd, iptr, d);
1550  break;
1551 
1552  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1553 
1554  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 #if SIZEOF_VOID_P == 8
1557  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1558 #else
1559  d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1560 #endif
1561  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1562  M_ASLL_IMM(s2, 3, REG_ITMP3);
1563  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1564  /* implicit null-pointer check */
1566  emit_store_dst(jd, iptr, d);
1567  break;
1568 
1569  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1570 
1571  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1572  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1573  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1574  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1575  M_ASLL_IMM(s2, 2, REG_ITMP3);
1576  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1577  /* implicit null-pointer check */
1579  emit_store_dst(jd, iptr, d);
1580  break;
1581 
1582  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1583 
1584  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1585  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1587  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1588  M_ASLL_IMM(s2, 3, REG_ITMP3);
1589  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1590  /* implicit null-pointer check */
1592  emit_store_dst(jd, iptr, d);
1593  break;
1594 
1595  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1596 
1597  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1598  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1599  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1600  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1602  M_AADD(REG_ITMP3, s1, REG_ITMP3);
1603  /* implicit null-pointer check */
1605  emit_store_dst(jd, iptr, d);
1606  break;
1607 
1608 
1609  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1610 
1611  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1612  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1613  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1614  M_AADD(s2, s1, REG_ITMP1);
1615  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1616  /* implicit null-pointer check */
1617  M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1618  break;
1619 
1620  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1621  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1622 
1623  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1624  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1625  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1626  M_AADD(s2, s1, REG_ITMP1);
1627  M_AADD(s2, REG_ITMP1, REG_ITMP1);
1628  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1629  /* implicit null-pointer check */
1630  M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1631  break;
1632 
1633  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1634 
1635  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1637  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1638  M_ASLL_IMM(s2, 2, REG_ITMP2);
1639  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1640  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1641  /* implicit null-pointer check */
1642  M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1643  break;
1644 
1645  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1646 
1647  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1649  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1650  M_ASLL_IMM(s2, 3, REG_ITMP2);
1651  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1652 #if SIZEOF_VOID_P == 8
1653  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1654 #else
1655  s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1656 #endif
1657  /* implicit null-pointer check */
1659  break;
1660 
1661  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1662 
1663  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1664  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1665  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1666  M_ASLL_IMM(s2, 2, REG_ITMP2);
1667  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1668  s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1669  /* implicit null-pointer check */
1671  break;
1672 
1673  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1674 
1675  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1676  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1677  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1678  M_ASLL_IMM(s2, 3, REG_ITMP2);
1679  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1680  s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1681  /* implicit null-pointer check */
1683  break;
1684 
1685 
1686  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1687 
1688  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1689  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1690  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1691  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1692 
1693  M_INTMOVE(s1, REG_A0);
1694  M_INTMOVE(s3, REG_A1);
1696  M_ALD(REG_ITMP3, REG_PV, disp);
1698  M_NOP;
1699  emit_arraystore_check(cd, iptr);
1700 
1701  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1704  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1705  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1706  /* implicit null-pointer check */
1708  break;
1709 
1710 
1711  case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1712 
1713  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1714  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1715  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1716  M_AADD(s2, s1, REG_ITMP1);
1717  /* implicit null-pointer check */
1719  break;
1720 
1721  case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1722  case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1723 
1724  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1725  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1726  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1727  M_AADD(s2, s1, REG_ITMP1);
1728  M_AADD(s2, REG_ITMP1, REG_ITMP1);
1729  /* implicit null-pointer check */
1731  break;
1732 
1733  case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1734 
1735  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1737  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1738  M_ASLL_IMM(s2, 2, REG_ITMP2);
1739  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1740  /* implicit null-pointer check */
1742  break;
1743 
1744  case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1745 
1746  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1747  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1748  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1749  M_ASLL_IMM(s2, 3, REG_ITMP2);
1750  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1751  /* implicit null-pointer check */
1752 #if SIZEOF_VOID_P == 8
1754 #else
1756 #endif
1757  break;
1758 
1759  case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1760 
1761  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1762  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1763  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1765  M_AADD(REG_ITMP2, s1, REG_ITMP1);
1766  /* implicit null-pointer check */
1768  break;
1769 
1770 
1771  case ICMD_GETSTATIC: /* ... ==> ..., value */
1772 
1773  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1774  uf = iptr->sx.s23.s3.uf;
1775  fieldtype = uf->fieldref->parseddesc.fd->type;
1776  disp = dseg_add_unique_address(cd, uf);
1777 
1779  }
1780  else {
1781  fi = iptr->sx.s23.s3.fmiref->p.field;
1782  fieldtype = fi->type;
1783  disp = dseg_add_address(cd, fi->value);
1784 
1787  fi->clazz, disp);
1788  }
1789 
1790  M_ALD(REG_ITMP1, REG_PV, disp);
1791 
1792  switch (fieldtype) {
1793  case TYPE_INT:
1794  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1795  M_ILD_INTERN(d, REG_ITMP1, 0);
1796  break;
1797  case TYPE_LNG:
1798 #if SIZEOF_VOID_P == 8
1799  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1800 #else
1801  d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1802 #endif
1803  M_LLD_INTERN(d, REG_ITMP1, 0);
1804  break;
1805  case TYPE_ADR:
1806  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1807  M_ALD_INTERN(d, REG_ITMP1, 0);
1808  break;
1809  case TYPE_FLT:
1810  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1811  M_FLD_INTERN(d, REG_ITMP1, 0);
1812  break;
1813  case TYPE_DBL:
1814  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1815  M_DLD_INTERN(d, REG_ITMP1, 0);
1816  break;
1817  default:
1818  assert(false);
1819  break;
1820  }
1821  emit_store_dst(jd, iptr, d);
1822  break;
1823 
1824  case ICMD_PUTSTATIC: /* ..., value ==> ... */
1825 
1826  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1827  uf = iptr->sx.s23.s3.uf;
1828  fieldtype = uf->fieldref->parseddesc.fd->type;
1829  disp = dseg_add_unique_address(cd, uf);
1830 
1832  }
1833  else {
1834  fi = iptr->sx.s23.s3.fmiref->p.field;
1835  fieldtype = fi->type;
1836  disp = dseg_add_address(cd, fi->value);
1837 
1840  fi->clazz, disp);
1841  }
1842 
1843  M_ALD(REG_ITMP1, REG_PV, disp);
1844 
1845  switch (fieldtype) {
1846  case TYPE_INT:
1847  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1848  M_IST_INTERN(s1, REG_ITMP1, 0);
1849  break;
1850  case TYPE_LNG:
1851 #if SIZEOF_VOID_P == 8
1852  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1853 #else
1854  s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1855 #endif
1856  M_LST_INTERN(s1, REG_ITMP1, 0);
1857  break;
1858  case TYPE_ADR:
1859  s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1860  M_AST_INTERN(s1, REG_ITMP1, 0);
1861  break;
1862  case TYPE_FLT:
1863  s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1864  M_FST_INTERN(s1, REG_ITMP1, 0);
1865  break;
1866  case TYPE_DBL:
1867  s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1868  M_DST_INTERN(s1, REG_ITMP1, 0);
1869  break;
1870  default:
1871  assert(false);
1872  break;
1873  }
1874  break;
1875 
1876  case ICMD_PUTSTATICCONST: /* ... ==> ... */
1877 
1878  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1879  uf = iptr->sx.s23.s3.uf;
1880  fieldtype = uf->fieldref->parseddesc.fd->type;
1881  disp = dseg_add_unique_address(cd, uf);
1882 
1884  }
1885  else {
1886  fi = iptr->sx.s23.s3.fmiref->p.field;
1887  fieldtype = fi->type;
1888  disp = dseg_add_address(cd, fi->value);
1889 
1892  fi->clazz, disp);
1893  }
1894 
1895  M_ALD(REG_ITMP1, REG_PV, disp);
1896 
1897  switch (fieldtype) {
1898  case TYPE_INT:
1900  break;
1901  case TYPE_LNG:
1903  break;
1904  case TYPE_ADR:
1906  break;
1907  case TYPE_FLT:
1909  break;
1910  case TYPE_DBL:
1912  break;
1913  default:
1914  assert(false);
1915  break;
1916  }
1917  break;
1918 
1919 
1920  case ICMD_GETFIELD: /* ... ==> ..., value */
1921 
1922  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1923  emit_nullpointer_check(cd, iptr, s1);
1924 
1925  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1926  uf = iptr->sx.s23.s3.uf;
1927  fieldtype = uf->fieldref->parseddesc.fd->type;
1928  disp = 0;
1929 
1931  }
1932  else {
1933  fi = iptr->sx.s23.s3.fmiref->p.field;
1934  fieldtype = fi->type;
1935  disp = fi->offset;
1936  }
1937 
1938  switch (fieldtype) {
1939  case TYPE_INT:
1940  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1941  M_ILD(d, s1, disp);
1942  break;
1943  case TYPE_LNG:
1944 #if SIZEOF_VOID_P == 8
1945  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1946  M_LLD(d, s1, disp);
1947 #else
1948  d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1949  M_LLD_GETFIELD(d, s1, disp);
1950 #endif
1951  break;
1952  case TYPE_ADR:
1953  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1954  M_ALD(d, s1, disp);
1955  break;
1956  case TYPE_FLT:
1957  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1958  M_FLD(d, s1, disp);
1959  break;
1960  case TYPE_DBL:
1961  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1962  M_DLD(d, s1, disp);
1963  break;
1964  default:
1965  assert(false);
1966  break;
1967  }
1968  emit_store_dst(jd, iptr, d);
1969  break;
1970 
1971  case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1972 
1973  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1974  emit_nullpointer_check(cd, iptr, s1);
1975 
1976  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1977  uf = iptr->sx.s23.s3.uf;
1978  fieldtype = uf->fieldref->parseddesc.fd->type;
1979  disp = 0;
1980  }
1981  else {
1982  fi = iptr->sx.s23.s3.fmiref->p.field;
1983  fieldtype = fi->type;
1984  disp = fi->offset;
1985  }
1986 
1987 #if SIZEOF_VOID_P == 8
1988  if (IS_INT_LNG_TYPE(fieldtype))
1989  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1990  else
1991  s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1992 #else
1993  if (IS_INT_LNG_TYPE(fieldtype)) {
1994  if (IS_2_WORD_TYPE(fieldtype))
1995  s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1996  else
1997  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1998  }
1999  else
2000  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2001 #endif
2002 
2003  if (INSTRUCTION_IS_UNRESOLVED(iptr))
2005 
2006  switch (fieldtype) {
2007  case TYPE_INT:
2008  M_IST(s2, s1, disp);
2009  break;
2010  case TYPE_LNG:
2011  M_LST(s2, s1, disp);
2012  break;
2013  case TYPE_ADR:
2014  M_AST(s2, s1, disp);
2015  break;
2016  case TYPE_FLT:
2017  M_FST(s2, s1, disp);
2018  break;
2019  case TYPE_DBL:
2020  M_DST(s2, s1, disp);
2021  break;
2022  default:
2023  assert(false);
2024  break;
2025  }
2026  break;
2027 
2028  case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2029 
2030  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2031  emit_nullpointer_check(cd, iptr, s1);
2032 
2033  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2034  uf = iptr->sx.s23.s3.uf;
2035  fieldtype = uf->fieldref->parseddesc.fd->type;
2036  disp = 0;
2037 
2039  }
2040  else {
2041  fi = iptr->sx.s23.s3.fmiref->p.field;
2042  fieldtype = fi->type;
2043  disp = fi->offset;
2044  }
2045 
2046  switch (fieldtype) {
2047  case TYPE_INT:
2048  M_IST(REG_ZERO, s1, disp);
2049  break;
2050  case TYPE_LNG:
2051  M_LST(REG_ZERO, s1, disp);
2052  break;
2053  case TYPE_ADR:
2054  M_AST(REG_ZERO, s1, disp);
2055  break;
2056  case TYPE_FLT:
2057  M_FST(REG_ZERO, s1, disp);
2058  break;
2059  case TYPE_DBL:
2060  M_DST(REG_ZERO, s1, disp);
2061  break;
2062  default:
2063  assert(false);
2064  break;
2065  }
2066  break;
2067 
2068 
2069  /* branch operations **************************************************/
2070 
2071  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2072 
2074  break;
2075 
2076  case ICMD_IFEQ: /* ..., value ==> ... */
2077 
2078  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2079  ICONST(REG_ITMP2, iptr->sx.val.i);
2080  emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2081  break;
2082 
2083  case ICMD_IFLT: /* ..., value ==> ... */
2084 
2085  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2087  M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2088  else {
2089  ICONST(REG_ITMP2, iptr->sx.val.i);
2090  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2091  }
2092  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2093  break;
2094 
2095  case ICMD_IFLE: /* ..., value ==> ... */
2096 
2097  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2098  if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2099  M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2100  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2101  }
2102  else {
2103  ICONST(REG_ITMP2, iptr->sx.val.i);
2104  M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2105  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2106  }
2107  break;
2108 
2109  case ICMD_IFNE: /* ..., value ==> ... */
2110 
2111  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2112  ICONST(REG_ITMP2, iptr->sx.val.i);
2113  emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2114  break;
2115 
2116  case ICMD_IFGT: /* ..., value ==> ... */
2117 
2118  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2119  if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2120  M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2121  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2122  }
2123  else {
2124  ICONST(REG_ITMP2, iptr->sx.val.i);
2125  M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2126  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2127  }
2128  break;
2129 
2130  case ICMD_IFGE: /* ..., value ==> ... */
2131 
2132  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2133  if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2134  M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2135  else {
2136  ICONST(REG_ITMP2, iptr->sx.val.i);
2137  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2138  }
2139  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2140  break;
2141 
2142  case ICMD_IF_LEQ: /* ..., value ==> ... */
2143 
2144 #if SIZEOF_VOID_P == 8
2145  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2146  if (iptr->sx.val.l == 0)
2147  emit_beqz(cd, iptr->dst.block, s1);
2148  else {
2149  LCONST(REG_ITMP2, iptr->sx.val.l);
2150  emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2151  }
2152 #else
2153  if (iptr->sx.val.l == 0) {
2154  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2156  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2157  }
2158  else {
2159  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2160  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2161  M_XOR(s1, REG_ITMP2, REG_ITMP2);
2162  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2163  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2164  M_XOR(s1, REG_ITMP3, REG_ITMP3);
2166  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2167  }
2168 #endif
2169  break;
2170 
2171  case ICMD_IF_LLT: /* ..., value ==> ... */
2172 
2173 #if SIZEOF_VOID_P == 8
2174  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175  if (iptr->sx.val.l == 0)
2176  emit_bltz(cd, iptr->dst.block, s1);
2177  else {
2178  if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2179  M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2180  else {
2181  LCONST(REG_ITMP2, iptr->sx.val.l);
2182  M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2183  }
2184  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2185  }
2186 #else
2187  if (iptr->sx.val.l == 0) {
2188  /* if high word is less than zero, the whole long is too */
2189  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2190  emit_bltz(cd, iptr->dst.block, s1);
2191  }
2192  else {
2193  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2194  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2195  M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2196  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2197  emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2198  s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2199  ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2201  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2203  }
2204 #endif
2205  break;
2206 
2207  case ICMD_IF_LLE: /* ..., value ==> ... */
2208 
2209 #if SIZEOF_VOID_P == 8
2210  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211  if (iptr->sx.val.l == 0)
2212  emit_blez(cd, iptr->dst.block, s1);
2213  else {
2214  if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2215  M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2216  emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2217  }
2218  else {
2219  LCONST(REG_ITMP2, iptr->sx.val.l);
2220  M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2221  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2222  }
2223  }
2224 #else
2225  if (iptr->sx.val.l == 0) {
2226  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2227  emit_label_bgtz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2228  emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2229  emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2231  }
2232  else {
2233  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2234  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2235  M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2236  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2237  emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2238  s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2239  ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2241  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2243  }
2244 #endif
2245  break;
2246 
2247  case ICMD_IF_LNE: /* ..., value ==> ... */
2248 
2249 #if SIZEOF_VOID_P == 8
2250  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251  if (iptr->sx.val.l == 0)
2252  emit_bnez(cd, iptr->dst.block, s1);
2253  else {
2254  LCONST(REG_ITMP2, iptr->sx.val.l);
2255  emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2256  }
2257 #else
2258  if (iptr->sx.val.l == 0) {
2259  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2261  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2262  }
2263  else {
2264  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2265  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2266  M_XOR(s1, REG_ITMP2, REG_ITMP2);
2267  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2268  ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2269  M_XOR(s1, REG_ITMP3, REG_ITMP3);
2271  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2272  }
2273 #endif
2274  break;
2275 
2276  case ICMD_IF_LGT: /* ..., value ==> ... */
2277 
2278 #if SIZEOF_VOID_P == 8
2279  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2280  if (iptr->sx.val.l == 0)
2281  emit_bgtz(cd, iptr->dst.block, s1);
2282  else {
2283  if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2284  M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2285  emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2286  }
2287  else {
2288  LCONST(REG_ITMP2, iptr->sx.val.l);
2289  M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2290  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2291  }
2292  }
2293 #else
2294  if (iptr->sx.val.l == 0) {
2295  s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2296  emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2297  emit_label_bltz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2298  emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2300  }
2301  else {
2302  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2303  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2304  M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2305  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2306  emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2307  s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2308  ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2310  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2312  }
2313 #endif
2314  break;
2315 
2316  case ICMD_IF_LGE: /* ..., value ==> ... */
2317 
2318 #if SIZEOF_VOID_P == 8
2319  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2320  if (iptr->sx.val.l == 0)
2321  emit_bgez(cd, iptr->dst.block, s1);
2322  else {
2323  if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2324  M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2325  }
2326  else {
2327  LCONST(REG_ITMP2, iptr->sx.val.l);
2328  M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2329  }
2330  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2331  }
2332 #else
2333  if (iptr->sx.val.l == 0) {
2334  /* if high word is greater equal zero, the whole long is too */
2335  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2336  emit_bgez(cd, iptr->dst.block, s1);
2337  }
2338  else {
2339  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2340  ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2341  M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2342  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2343  emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2344  s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2345  ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2347  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2349  }
2350 #endif
2351  break;
2352 
2353 #if SIZEOF_VOID_P == 8
2354  case ICMD_IF_LCMPEQ:
2355 #endif
2356 
2357  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2358  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2359  emit_beq(cd, iptr->dst.block, s1, s2);
2360  break;
2361 
2362 #if SIZEOF_VOID_P == 4
2363  case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2364  /* op1 = target JavaVM pc */
2365 
2366  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2367  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2368  emit_label_bne(cd, BRANCH_LABEL_1, s1, s2);
2369  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2370  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2371  emit_beq(cd, iptr->dst.block, s1, s2);
2373  break;
2374 #endif
2375 
2376 #if SIZEOF_VOID_P == 8
2377  case ICMD_IF_LCMPNE:
2378 #endif
2379 
2380  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2381  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2382  emit_bne(cd, iptr->dst.block, s1, s2);
2383  break;
2384 
2385 #if SIZEOF_VOID_P == 4
2386  case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2387 
2388  /* TODO: could be optimized (XOR or SUB) */
2389  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2390  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2391  emit_bne(cd, iptr->dst.block, s1, s2);
2392  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2393  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2394  emit_bne(cd, iptr->dst.block, s1, s2);
2395  break;
2396 #endif
2397 
2398  case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2399 #if SIZEOF_VOID_P == 8
2400  case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2401 #endif
2402 
2403  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2404  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2405  M_CMPLT(s1, s2, REG_ITMP3);
2406  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2407  break;
2408 
2409 #if SIZEOF_VOID_P == 4
2410  case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2411 
2412  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2413  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2414  M_CMPLT(s1, s2, REG_ITMP3);
2415  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2416  M_CMPGT(s1, s2, REG_ITMP3);
2417  emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2418  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2419  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2420  M_CMPULT(s1, s2, REG_ITMP3);
2421  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2423  break;
2424 #endif
2425 
2426  case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2427 #if SIZEOF_VOID_P == 8
2428  case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2429 #endif
2430 
2431  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2432  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2433  M_CMPGT(s1, s2, REG_ITMP3);
2434  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2435  break;
2436 
2437 #if SIZEOF_VOID_P == 4
2438  case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2439 
2440  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2441  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2442  M_CMPGT(s1, s2, REG_ITMP3);
2443  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2444  M_CMPLT(s1, s2, REG_ITMP3);
2445  emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2446  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2447  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2448  M_CMPUGT(s1, s2, REG_ITMP3);
2449  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2451  break;
2452 #endif
2453 
2454  case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2455 #if SIZEOF_VOID_P == 8
2456  case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2457 #endif
2458 
2459  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2460  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2461  M_CMPGT(s1, s2, REG_ITMP3);
2462  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2463  break;
2464 
2465 #if SIZEOF_VOID_P == 4
2466  case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2467 
2468  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2469  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2470  M_CMPLT(s1, s2, REG_ITMP3);
2471  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2472  M_CMPGT(s1, s2, REG_ITMP3);
2473  emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2474  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2475  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2476  M_CMPUGT(s1, s2, REG_ITMP3);
2477  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2479  break;
2480 #endif
2481 
2482  case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2483 #if SIZEOF_VOID_P == 8
2484  case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2485 #endif
2486 
2487  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2488  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2489  M_CMPLT(s1, s2, REG_ITMP3);
2490  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2491  break;
2492 
2493 #if SIZEOF_VOID_P == 4
2494  case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2495 
2496  s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2497  s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2498  M_CMPGT(s1, s2, REG_ITMP3);
2499  emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2500  M_CMPLT(s1, s2, REG_ITMP3);
2501  emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2502  s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2503  s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2504  M_CMPULT(s1, s2, REG_ITMP3);
2505  emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2507  break;
2508 #endif
2509 
2510  case ICMD_TABLESWITCH: /* ..., index ==> ... */
2511  {
2512  s4 i, l;
2513  branch_target_t *table;
2514 
2515  table = iptr->dst.table;
2516 
2517  l = iptr->sx.s23.s2.tablelow;
2518  i = iptr->sx.s23.s3.tablehigh;
2519 
2520  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2521  if (l == 0)
2522  {M_INTMOVE(s1, REG_ITMP1);}
2523  else if (l <= 32768) {
2524  M_IADD_IMM(s1, -l, REG_ITMP1);
2525  }
2526  else {
2527  ICONST(REG_ITMP2, l);
2528  M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2529  }
2530 
2531  /* number of targets */
2532  i = i - l + 1;
2533 
2534  /* range check */
2535 
2537  emit_beqz(cd, table[0].block, REG_ITMP2);
2538 
2539  /* build jump table top down and use address of lowest entry */
2540 
2541  table += i;
2542 
2543  while (--i >= 0) {
2544  dseg_add_target(cd, table->block);
2545  --table;
2546  }
2547  }
2548 
2549  /* length of dataseg after last dseg_add_target is used by load */
2550 
2553  M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2554  M_JMP(REG_ITMP2);
2555  M_NOP;
2556  ALIGNCODENOP;
2557  break;
2558 
2559  case ICMD_BUILTIN:
2560  bte = iptr->sx.s23.s3.bte;
2561  if (bte->stub == NULL) {
2562  disp = dseg_add_functionptr(cd, bte->fp);
2563  M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2564 
2565  /* generate the actual call */
2566 
2567  /* TWISTI: i actually don't know the reason for using
2568  REG_ITMP3 here instead of REG_PV. */
2569 
2571  M_NOP;
2572  }
2573  else {
2574  disp = dseg_add_functionptr(cd, bte->stub);
2575  M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2576 
2577  /* generate the actual call */
2578 
2579  M_JSR(REG_RA, REG_PV);
2580  M_NOP;
2581  }
2582  break;
2583 
2584  case ICMD_INVOKESPECIAL:
2585  emit_nullpointer_check(cd, iptr, REG_A0);
2586  /* fall through */
2587 
2588  case ICMD_INVOKESTATIC:
2589  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2590  um = iptr->sx.s23.s3.um;
2591  disp = dseg_add_unique_address(cd, um);
2592 
2594  disp);
2595  }
2596  else {
2597  lm = iptr->sx.s23.s3.fmiref->p.method;
2598  disp = dseg_add_address(cd, lm->stubroutine);
2599  }
2600 
2601  M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2602 
2603  /* generate the actual call */
2604 
2605  M_JSR(REG_RA, REG_PV);
2606  M_NOP;
2607  break;
2608 
2609  case ICMD_INVOKEVIRTUAL:
2610  emit_nullpointer_check(cd, iptr, REG_A0);
2611 
2612  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2613  um = iptr->sx.s23.s3.um;
2615 
2616  s1 = 0;
2617  }
2618  else {
2619  lm = iptr->sx.s23.s3.fmiref->p.method;
2620  s1 = OFFSET(vftbl_t, table[0]) +
2621  sizeof(methodptr) * lm->vftblindex;
2622  }
2623 
2624  /* implicit null-pointer check */
2626  M_ALD(REG_PV, REG_METHODPTR, s1);
2627 
2628  /* generate the actual call */
2629 
2630  M_JSR(REG_RA, REG_PV);
2631  M_NOP;
2632  break;
2633 
2634  case ICMD_INVOKEINTERFACE:
2635  emit_nullpointer_check(cd, iptr, REG_A0);
2636 
2637  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2638  um = iptr->sx.s23.s3.um;
2640 
2641  s1 = 0;
2642  s2 = 0;
2643  }
2644  else {
2645  lm = iptr->sx.s23.s3.fmiref->p.method;
2646  s1 = OFFSET(vftbl_t, interfacetable[0]) -
2647  sizeof(methodptr*) * lm->clazz->index;
2648 
2649  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2650  }
2651 
2652  /* implicit null-pointer check */
2655  M_ALD(REG_PV, REG_METHODPTR, s2);
2656 
2657  /* generate the actual call */
2658 
2659  M_JSR(REG_RA, REG_PV);
2660  M_NOP;
2661  break;
2662 
2663 
2664 
2665  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2666 
2667  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2668  classinfo *super;
2669  s4 superindex;
2670 
2671  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2672  super = NULL;
2673  superindex = 0;
2674  }
2675  else {
2676  super = iptr->sx.s23.s3.c.cls;
2677  superindex = super->index;
2678  }
2679 
2680  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2681 
2682  /* if class is not resolved, check which code to call */
2683 
2684  if (super == NULL) {
2685  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2686 
2687  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2688  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2689 
2691  cr, disp);
2692 
2693  M_ILD(REG_ITMP2, REG_PV, disp);
2695  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2696  }
2697 
2698  /* interface checkcast code */
2699 
2700  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2701  if (super == NULL) {
2702  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2703 
2705  cr, 0);
2706  }
2707  else {
2708  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2709  }
2710 
2711  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2713  OFFSET(vftbl_t, interfacetablelength));
2714  M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2715  emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2716 
2718  OFFSET(vftbl_t, interfacetable[0]) -
2719  superindex * sizeof(methodptr*));
2720  emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2721 
2722  if (super == NULL)
2724  else
2726  }
2727 
2728  /* class checkcast code */
2729 
2730  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2731  if (super == NULL) {
2733 
2734  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2735  disp = dseg_add_unique_address(cd, NULL);
2736 
2739  cr, disp);
2740  }
2741  else {
2742  disp = dseg_add_address(cd, super->vftbl);
2743 
2744  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2745  }
2746 
2747  // The following code checks whether object s is a subtype of class t.
2748  // Represents the following semantic:
2749  // if (!fast_subtype_check(s->vftbl, t->vftbl)) throw;
2750 
2751  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2752  M_ALD(REG_ITMP3, REG_PV, disp);
2753 
2754  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2755  // Represents the following semantic:
2756  // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) good;
2757  // Preconditions:
2758  // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2759  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2761  M_ALD(REG_ITMP1, REG_ITMP1, 0);
2762  emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP1, REG_ITMP3); /* good */
2763 
2764  // Represents the following semantic:
2765  // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) throw;
2766  // Preconditions:
2767  // REG_ITMP3==t->vftbl;
2768  if (super == NULL) {
2769  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2770  M_ISUB_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2771  emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP1); /* throw */
2772  }
2773 
2774  // Represents the following semantic:
2775  // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) throw;
2776  // Preconditions:
2777  // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2778  M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2779  M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2781  emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP1); /* throw */
2782 
2783  // Represents the following semantic:
2784  // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) throw;
2785  // Preconditions:
2786  // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
2787  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2790  M_ALD(REG_ITMP2, REG_ITMP2, -DISPLAY_SIZE * SIZEOF_VOID_P);
2791  M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
2792  emit_label_beq(cd, BRANCH_LABEL_7, REG_ITMP2, REG_ITMP3); /* good */
2793 
2794  // Throw case
2796  if (super == NULL)
2798  emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
2800 
2801  // Good case
2804  emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
2805  }
2806  else {
2807  // Represents the following semantic:
2808  // if (*(s->vftbl + t->vftbl->subtype_offset) != t->vftbl) throw;
2809  // Preconditions:
2810  // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2811  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2812  M_BEQ(REG_ITMP2, REG_ITMP3, 2);
2813  M_NOP; /* delay slot */
2815  }
2816 
2817  if (super != NULL)
2819  }
2820 
2821  if (super == NULL) {
2824  }
2825 
2826  d = codegen_reg_of_dst(jd, iptr, s1);
2827  }
2828  else {
2829  s1 = emit_load_s1(jd, iptr, REG_A0);
2830  M_INTMOVE(s1, REG_A0);
2831 
2832  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2833  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2834  disp = dseg_add_unique_address(cd, NULL);
2835 
2838  cr, disp);
2839  }
2840  else {
2841  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2842  }
2843 
2844  M_ALD(REG_A1, REG_PV, disp);
2846  M_ALD(REG_ITMP3, REG_PV, disp);
2848  M_NOP;
2849 
2850  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2851  emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
2852 
2853  d = codegen_reg_of_dst(jd, iptr, s1);
2854  }
2855 
2856  M_INTMOVE(s1, d);
2857  emit_store_dst(jd, iptr, d);
2858  break;
2859 
2860  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2861 
2862  {
2863  classinfo *super;
2864  s4 superindex;
2865 
2866  super = iptr->sx.s23.s3.c.cls;
2867 
2868  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2869  super = NULL;
2870  superindex = 0;
2871  }
2872  else {
2873  super = iptr->sx.s23.s3.c.cls;
2874  superindex = super->index;
2875  }
2876 
2877  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2878  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2879 
2880  if (s1 == d) {
2881  M_MOV(s1, REG_ITMP1);
2882  s1 = REG_ITMP1;
2883  }
2884 
2885  M_CLR(d);
2886 
2887  /* if class is not resolved, check which code to call */
2888 
2889  if (super == NULL) {
2890  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2891 
2892  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2893  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2894 
2896  cr, disp);
2897 
2898  M_ILD(REG_ITMP3, REG_PV, disp);
2900  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2901  }
2902 
2903  /* interface instanceof code */
2904 
2905  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2906  if (super == NULL) {
2908  iptr->sx.s23.s3.c.ref, 0);
2909  }
2910  else {
2911  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2912  }
2913 
2914  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2916  OFFSET(vftbl_t, interfacetablelength));
2917  M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2918  M_BLEZ(REG_ITMP3, 3);
2919  M_NOP;
2921  OFFSET(vftbl_t, interfacetable[0]) -
2922  superindex * sizeof(methodptr*));
2923  M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2924 
2925  if (super == NULL)
2927  else
2929  }
2930 
2931  /* class instanceof code */
2932 
2933  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2934  if (super == NULL) {
2936 
2937  constant_classref *cr = iptr->sx.s23.s3.c.ref;
2938  disp = dseg_add_unique_address(cd, NULL);
2939 
2941  cr, disp);
2942  }
2943  else {
2944  disp = dseg_add_address(cd, super->vftbl);
2945 
2946  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2947  }
2948 
2949  // The following code checks whether object s is a subtype of class t.
2950  // Represents the following semantic:
2951  // fast_subtype_check(s->vftbl, t->vftbl));
2952 
2953  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2954  M_ALD(REG_ITMP3, REG_PV, disp);
2955 
2956  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2957  // Represents the following semantic:
2958  // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) true;
2959  // Preconditions:
2960  // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
2961  M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2963  M_ALD(REG_ITMP2, REG_ITMP2, 0);
2964  emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP2, REG_ITMP3); /* true */
2965 
2966  // Represents the following semantic:
2967  // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) false;
2968  // Preconditions:
2969  // REG_ITMP3==t->vftbl;
2970  if (super == NULL) {
2971  M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2972  M_ISUB_IMM(REG_ITMP2, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP2);
2973  emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP2); /* false */
2974  }
2975 
2976  // Represents the following semantic:
2977  // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) false;
2978  // Preconditions:
2979  // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
2980  M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, subtype_depth));
2981  M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2983  emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP2); /* false */
2984 
2985  // Represents the following semantic:
2986  // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) false;
2987  // Preconditions:
2988  // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
2989  M_ALD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, subtype_overflow));
2992  M_ALD(REG_ITMP1, REG_ITMP1, -DISPLAY_SIZE * SIZEOF_VOID_P);
2993  M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
2994  emit_label_bne(cd, BRANCH_LABEL_7, REG_ITMP1, REG_ITMP3); /* false */
2995 
2996  // True case
2998  M_MOV(1, d);
2999  if (d == REG_ITMP2) {
3000  M_BR(2); /* branch over M_CLR */
3001  M_NOP; /* delay slot */
3002  }
3003 
3004  // False (fall-through) case
3007  if (super == NULL)
3009  if (d == REG_ITMP2)
3010  M_CLR(d); /* if d == REG_ITMP2, it was destroyed */
3011  }
3012  else {
3013  // Represents the following semantic:
3014  // *(s->vftbl + t->vftbl->subtype_offset) == t->vftbl;
3015  // Preconditions:
3016  // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3017  M_ALD(REG_ITMP1, REG_ITMP1, super->vftbl->subtype_offset);
3018  M_XOR(REG_ITMP1, REG_ITMP3, d);
3019  M_CMPULT_IMM(d, 1, d);
3020  }
3021 
3022  if (super != NULL)
3024  }
3025 
3026  if (super == NULL) {
3029  }
3030 
3031  emit_store_dst(jd, iptr, d);
3032  }
3033  break;
3034 
3035  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3036 
3037  /* check for negative sizes and copy sizes to stack if necessary */
3038 
3039  MCODECHECK((iptr->s1.argcount << 1) + 64);
3040 
3041  for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3042 
3043  var = VAR(iptr->sx.s23.s2.args[s1]);
3044 
3045  /* copy SAVEDVAR sizes to stack */
3046 
3047  if (!(var->flags & PREALLOC)) {
3048  s2 = emit_load(jd, iptr, var, REG_ITMP1);
3049 #if SIZEOF_VOID_P == 8
3050  M_LST(s2, REG_SP, s1 * 8);
3051 #else
3052  M_IST(s2, REG_SP, (s1 + 2) * 8);
3053 #endif
3054  }
3055  }
3056 
3057  /* a0 = dimension count */
3058 
3059  ICONST(REG_A0, iptr->s1.argcount);
3060 
3061  /* is patcher function set? */
3062 
3063  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3064  constant_classref *cr = iptr->sx.s23.s3.c.ref;
3065  disp = dseg_add_unique_address(cd, NULL);
3066 
3068  cr, disp);
3069  }
3070  else {
3071  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3072  }
3073 
3074  /* a1 = arraydescriptor */
3075 
3076  M_ALD(REG_A1, REG_PV, disp);
3077 
3078  /* a2 = pointer to dimensions = stack pointer */
3079 
3080 #if SIZEOF_VOID_P == 8
3081  M_MOV(REG_SP, REG_A2);
3082 #else
3083  M_AADD_IMM(REG_SP, 4*4, REG_A2);
3084 #endif
3085 
3087  M_ALD(REG_ITMP3, REG_PV, disp);
3089  M_NOP;
3090 
3091  /* check for exception before result assignment */
3092 
3093  emit_exception_check(cd, iptr);
3094 
3095  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3096  M_INTMOVE(REG_RESULT, d);
3097  emit_store_dst(jd, iptr, d);
3098  break;
3099 
3100  default:
3101  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
3102  } /* switch */
3103 }
3104 
3105 
3106 /* codegen_emit_stub_native ****************************************************
3107 
3108  Emits a stub routine which calls a native method.
3109 
3110 *******************************************************************************/
3111 
3112 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3113 {
3114  methodinfo *m;
3115  codeinfo *code;
3116  codegendata *cd;
3117  methoddesc *md;
3118  s4 i, j;
3119  s4 t;
3120  int s1, s2;
3121  int disp;
3122 
3123  /* get required compiler data */
3124 
3125  m = jd->m;
3126  code = jd->code;
3127  cd = jd->cd;
3128 
3129  /* initialize variables */
3130 
3131  md = m->parseddesc;
3132 
3133  /* calculate stack frame size */
3134 
3135  cd->stackframesize =
3136  1 + /* return address */
3137  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3138  sizeof(localref_table) / SIZEOF_VOID_P +
3139  md->paramcount + /* for saving arguments over calls */
3140 #if SIZEOF_VOID_P == 4
3141  5 + /* additional save space (MIPS32) */
3142 #endif
3143  1 + /* for saving return address */
3144  nmd->memuse;
3145 
3146  /* adjust stackframe size for 16-byte alignment */
3147 
3148  if (cd->stackframesize & 1)
3149  cd->stackframesize++;
3150 
3151  /* create method header */
3152 
3153  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3154  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3155  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3156  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3157  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3158 
3159  /* generate stub code */
3160 
3161  M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3162  M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3163 
3164  /* save integer and float argument registers */
3165 
3166 #if SIZEOF_VOID_P == 8
3167  for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3168  if (IS_INT_LNG_TYPE(md->params[i].type)) {
3169  s1 = md->params[i].regoff;
3170  M_AST(s1, REG_SP, j * 8);
3171  j++;
3172  }
3173  }
3174 #else
3175  for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3176  if (IS_INT_LNG_TYPE(md->params[i].type)) {
3177  if (!md->params[i].inmemory) {
3178  s1 = md->params[i].regoff;
3179 
3180  if (IS_2_WORD_TYPE(md->params[i].type))
3181  M_LST(s1, REG_SP, j * 8);
3182  else
3183  M_IST(s1, REG_SP, j * 8);
3184 
3185  j++;
3186  }
3187  }
3188  }
3189 #endif
3190 
3191  for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3192  if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3193  s1 = md->params[i].regoff;
3194 
3195  if (IS_2_WORD_TYPE(md->params[i].type))
3196  M_DST(s1, REG_SP, j * 8);
3197  else
3198  M_FST(s1, REG_SP, j * 8);
3199 
3200  j++;
3201  }
3202  }
3203 
3204  /* prepare data structures for native function call */
3205 
3206  M_MOV(REG_SP, REG_A0);
3207  M_MOV(REG_PV, REG_A1);
3209  M_ALD(REG_ITMP3, REG_PV, disp);
3211  M_NOP; /* XXX fill me! */
3212 
3213  /* remember class argument */
3214 
3215  if (m->flags & ACC_STATIC)
3217 
3218  /* restore integer and float argument registers */
3219 
3220 #if SIZEOF_VOID_P == 8
3221  for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3222  if (IS_INT_LNG_TYPE(md->params[i].type)) {
3223  s1 = md->params[i].regoff;
3224  M_LLD(s1, REG_SP, j * 8);
3225  j++;
3226  }
3227  }
3228 #else
3229  for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3230  if (IS_INT_LNG_TYPE(md->params[i].type)) {
3231  if (!md->params[i].inmemory) {
3232  s1 = md->params[i].regoff;
3233 
3234  if (IS_2_WORD_TYPE(md->params[i].type))
3235  M_LLD(s1, REG_SP, j * 8);
3236  else
3237  M_ILD(s1, REG_SP, j * 8);
3238 
3239  j++;
3240  }
3241  }
3242  }
3243 #endif
3244 
3245  for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3246  if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3247  s1 = md->params[i].regoff;
3248 
3249  if (IS_2_WORD_TYPE(md->params[i].type))
3250  M_DLD(s1, REG_SP, j * 8);
3251  else
3252  M_FLD(s1, REG_SP, j * 8);
3253 
3254  j++;
3255  }
3256  }
3257 
3258  /* copy or spill arguments to new locations */
3259 
3260  for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3261  t = md->params[i].type;
3262 
3263  if (IS_INT_LNG_TYPE(t)) {
3264  if (!md->params[i].inmemory) {
3265  s1 = md->params[i].regoff;
3266  s2 = nmd->params[j].regoff;
3267 
3268  if (!nmd->params[j].inmemory) {
3269 #if SIZEOF_VOID_P == 8
3270  M_INTMOVE(s1, s2);
3271 #else
3272  if (IS_2_WORD_TYPE(t))
3273  M_LNGMOVE(s1, s2);
3274  else
3275  M_INTMOVE(s1, s2);
3276 #endif
3277  }
3278  else {
3279 #if SIZEOF_VOID_P == 8
3280  M_LST(s1, REG_SP, s2);
3281 #else
3282  if (IS_2_WORD_TYPE(t))
3283  M_LST(s1, REG_SP, s2);
3284  else
3285  M_IST(s1, REG_SP, s2);
3286 #endif
3287  }
3288  }
3289  else {
3290  s1 = md->params[i].regoff + cd->stackframesize * 8;
3291  s2 = nmd->params[j].regoff;
3292 
3293 #if SIZEOF_VOID_P == 8
3294  M_LLD(REG_ITMP1, REG_SP, s1);
3295  M_LST(REG_ITMP1, REG_SP, s2);
3296 #else
3297  if (IS_2_WORD_TYPE(t)) {
3300  }
3301  else {
3302  M_ILD(REG_ITMP1, REG_SP, s1);
3303  M_IST(REG_ITMP1, REG_SP, s2);
3304  }
3305 #endif
3306  }
3307  }
3308  else {
3309  if (!md->params[i].inmemory) {
3310  s1 = md->params[i].regoff;
3311  s2 = nmd->params[j].regoff;
3312 
3313  if (!nmd->params[j].inmemory) {
3314 #if SIZEOF_VOID_P == 8
3315  if (IS_2_WORD_TYPE(t))
3316  M_DMOV(s1, s2);
3317  else
3318  M_FMOV(s1, s2);
3319 #else
3320  /* On MIPS32 float arguments for native functions
3321  can never be in float argument registers, since
3322  the first argument is _always_ an integer
3323  argument (JNIEnv) */
3324 
3325  if (IS_2_WORD_TYPE(t)) {
3326  /* double high/low order is endian
3327  independent: even numbered holds low
3328  32-bits, odd numbered high 32-bits */
3329 
3330  M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3331  M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3332  }
3333  else
3334  M_MFC1(s2, s1);
3335 #endif
3336  }
3337  else {
3338 #if SIZEOF_VOID_P == 8
3339  if (IS_2_WORD_TYPE(t))
3340  M_DST(s1, REG_SP, s2);
3341  else
3342  M_FST(s1, REG_SP, s2);
3343 #else
3344  /* s1 may have been originally in 2 int registers,
3345  but was moved out by the native function
3346  argument(s), just get low register */
3347 
3348  if (IS_2_WORD_TYPE(t))
3349  M_DST(GET_LOW_REG(s1), REG_SP, s2);
3350  else
3351  M_FST(GET_LOW_REG(s1), REG_SP, s2);
3352 #endif
3353  }
3354  }
3355  else {
3356  s1 = md->params[i].regoff + cd->stackframesize * 8;
3357  s2 = nmd->params[j].regoff;
3358 
3359 #if SIZEOF_VOID_P == 8
3360  if (IS_2_WORD_TYPE(t)) {
3361  M_DLD(REG_FTMP1, REG_SP, s1);
3362  M_DST(REG_FTMP1, REG_SP, s2);
3363  }
3364  else {
3365  M_FLD(REG_FTMP1, REG_SP, s1);
3366  M_FST(REG_FTMP1, REG_SP, s2);
3367  }
3368 #else
3369  if (IS_2_WORD_TYPE(t)) {
3370  M_DLD(REG_FTMP1, REG_SP, s1);
3371  M_DST(REG_FTMP1, REG_SP, s2);
3372  }
3373  else {
3374  M_FLD(REG_FTMP1, REG_SP, s1);
3375  M_FST(REG_FTMP1, REG_SP, s2);
3376  }
3377 #endif
3378  }
3379  }
3380  }
3381 
3382  /* Handle native Java methods. */
3383 
3384  if (m->flags & ACC_NATIVE) {
3385  /* put class into second argument register */
3386 
3387  if (m->flags & ACC_STATIC)
3389 
3390  /* put env into first argument register */
3391 
3392  disp = dseg_add_address(cd, VM::get_current()->get_jnienv());
3393  M_ALD(REG_A0, REG_PV, disp);
3394  }
3395 
3396  /* Call the native function. */
3397 
3398  disp = dseg_add_functionptr(cd, f);
3399  M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3400  M_JSR(REG_RA, REG_ITMP3); /* call native method */
3401  M_NOP; /* delay slot */
3402 
3403  /* save return value */
3404 
3405  switch (md->returntype.type) {
3406 #if SIZEOF_VOID_P == 8
3407  case TYPE_INT:
3408  case TYPE_LNG:
3409  case TYPE_ADR:
3410  M_LST(REG_RESULT, REG_SP, 0 * 8);
3411  break;
3412  case TYPE_FLT:
3413  case TYPE_DBL:
3414  M_DST(REG_FRESULT, REG_SP, 0 * 8);
3415  break;
3416 #else
3417  case TYPE_INT:
3418  case TYPE_ADR:
3419  M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3420  break;
3421  case TYPE_LNG:
3422  M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3423  break;
3424  case TYPE_FLT:
3425  case TYPE_DBL:
3426  M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3427  break;
3428 #endif
3429  case TYPE_VOID:
3430  break;
3431  default:
3432  assert(false);
3433  break;
3434  }
3435 
3436  /* remove native stackframe info */
3437 
3438  M_MOV(REG_SP, REG_A0);
3439  M_MOV(REG_PV, REG_A1);
3441  M_ALD(REG_ITMP3, REG_PV, disp);
3443  M_NOP; /* XXX fill me! */
3445 
3446  /* restore return value */
3447 
3448  switch (md->returntype.type) {
3449 #if SIZEOF_VOID_P == 8
3450  case TYPE_INT:
3451  case TYPE_LNG:
3452  case TYPE_ADR:
3453  M_LLD(REG_RESULT, REG_SP, 0 * 8);
3454  break;
3455  case TYPE_FLT:
3456  case TYPE_DBL:
3457  M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3458  break;
3459 #else
3460  case TYPE_INT:
3461  case TYPE_ADR:
3462  M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3463  break;
3464  case TYPE_LNG:
3465  M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3466  break;
3467  case TYPE_FLT:
3468  case TYPE_DBL:
3469  M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3470  break;
3471 #endif
3472  case TYPE_VOID:
3473  break;
3474  default:
3475  assert(false);
3476  break;
3477  }
3478 
3479  M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3480 
3481  /* check for exception */
3482 
3483  M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3484  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3485 
3486  M_RET(REG_RA); /* return to caller */
3487  M_NOP; /* DELAY SLOT */
3488 
3489  /* handle exception */
3490 
3492 
3493  /* Generate patcher traps. */
3494 
3495  emit_patcher_traps(jd);
3496 }
3497 
3498 
3499 /*
3500  * These are local overrides for various environment variables in Emacs.
3501  * Please do not remove this and leave it at the end of the file, where
3502  * Emacs will automagically detect them.
3503  * ---------------------------------------------------------------------
3504  * Local variables:
3505  * mode: c++
3506  * indent-tabs-mode: t
3507  * c-basic-offset: 4
3508  * tab-width: 4
3509  * End:
3510  * vim:noexpandtab:sw=4:ts=4:
3511  */
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)
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 PATCHER_invokeinterface
#define REG_A1
Definition: md-abi.hpp:36
Definition: jit.hpp:126
#define M_LST_INTERN(a, b, disp)
Definition: codegen.hpp:215
#define M_LST(a, b, disp)
Definition: codegen.hpp:349
#define REG_A0
Definition: md-abi.hpp:35
paramdesc * params
Definition: descriptor.hpp:164
#define M_CVTFD(a, b)
Definition: codegen.hpp:721
#define M_FCMPULED(a, b)
Definition: codegen.hpp:554
#define M_BEQ(off)
Definition: codegen.hpp:482
#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
#define M_DNEG(a, d)
Definition: codegen.hpp:715
methodinfo * methods
Definition: class.hpp:113
#define PATCHER_resolve_classref_to_vftbl
#define BUILTIN_multianewarray
Definition: builtin.hpp:201
#define IS_INT_LNG_TYPE(a)
Definition: global.hpp:130
#define M_AND(a, b, c)
Definition: codegen.hpp:294
#define M_IST(a, b, disp)
Definition: codegen.hpp:351
#define ICONST(d, c)
Definition: codegen.hpp:53
#define M_LDA(a, b, disp)
Definition: codegen.hpp:163
#define M_FCMPOLTF(a, b)
Definition: codegen.hpp:547
#define M_MFC1(l, f)
Definition: codegen.hpp:533
#define M_MOVDL(d, l)
Definition: codegen.hpp:529
#define M_TRUNCDI(a, c)
Definition: codegen.hpp:502
#define M_FNEG(a, d)
Definition: codegen.hpp:714
#define PATCHER_get_putfield
#define M_FLD_INTERN(a, b, disp)
Definition: codegen.hpp:314
#define M_AADD_IMM(a, b, c)
Definition: codegen.hpp:277
#define M_LSLL_IMM(a, b, c)
Definition: codegen.hpp:471
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_BEQZ(a, disp)
Definition: codegen.hpp:252
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define REG_ITMP12_PACKED
Definition: md-abi.hpp:131
#define M_MFLO(a)
Definition: codegen.hpp:434
#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
#define M_IST_INTERN(a, b, disp)
Definition: codegen.hpp:214
codegendata * cd
Definition: jit.hpp:129
#define M_ISRL(a, b, c)
Definition: codegen.hpp:462
void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
Definition: codegen.cpp:2010
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
#define M_TRUNCFI(a, c)
Definition: codegen.hpp:501
#define REG_ITMP1_XPTR
Definition: md-abi.hpp:50
#define REG_A2
Definition: md-abi.hpp:37
#define M_TRUNCDL(a, c)
Definition: codegen.hpp:511
#define POINTERSHIFT
Definition: codegen.hpp:571
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
#define M_CMPULT_IMM(a, b, c)
Definition: codegen.hpp:292
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
#define M_MFHI(a)
Definition: codegen.hpp:435
void dseg_add_target(codegendata *cd, basicblock *target)
Definition: dseg.cpp:565
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_FCMPEQF(a, b)
Definition: codegen.hpp:543
#define M_OR(a, b, c)
Definition: codegen.hpp:295
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define REG_A2_A3_PACKED
Definition: md-abi.hpp:136
#define M_CVTLD(b, c)
Definition: codegen.hpp:393
#define PATCHER_get_putstatic
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define M_FMOV(b, c)
Definition: codegen.hpp:341
#define BUILTIN_arraycheckcast
Definition: builtin.hpp:148
#define M_LUI(a, imm)
Definition: codegen.hpp:442
#define M_CVTLF(b, c)
Definition: codegen.hpp:392
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
#define ALIGNCODENOP
Definition: codegen.hpp:47
#define M_LSUB(a, b, c)
Definition: codegen.hpp:266
s4 regoff
Definition: reg.hpp:47
void(* functionptr)(void)
Definition: global.hpp:39
#define M_BGEZ(a, disp)
Definition: codegen.hpp:256
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 M_CMOVT(a, b)
Definition: codegen.hpp:562
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
#define M_ISRA(a, b, c)
Definition: codegen.hpp:463
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define GET_LOW_REG(a)
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
#define M_ISLL(a, b, c)
Definition: codegen.hpp:461
BeginInst *& block
#define M_CMPULT(a, b, c)
Definition: codegen.hpp:285
#define M_FSUB(a, b, c)
Definition: codegen.hpp:375
classref_or_classinfo c
#define M_ISRA_IMM(a, b, c)
Definition: codegen.hpp:470
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
#define M_ISUB_IMM(a, b, c)
Definition: codegen.hpp:272
void emit_patcher_traps(jitdata *jd)
#define M_LSRA_IMM(a, b, c)
Definition: codegen.hpp:473
dst_operand_t dst
flags_operand_t flags
#define M_FBT(disp)
Definition: codegen.hpp:557
#define M_XOR_IMM(a, b, c)
Definition: codegen.hpp:300
#define M_XOR(a, b, c)
Definition: codegen.hpp:296
#define M_SST(a, b, disp)
Definition: codegen.hpp:212
constant_FMIref * fieldref
Definition: resolve.hpp:88
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
#define M_JMP(a, b)
Definition: codegen.hpp:259
void emit_label_br(codegendata *cd, s4 label)
#define M_IDIV(a)
Definition: codegen.hpp:207
#define BRANCH_LABEL_3
Definition: emit-common.hpp:49
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
#define M_LNGMOVE(a, b)
#define REG_ITMP23_PACKED
Definition: md-abi.hpp:132
imm_union * value
Definition: field.hpp:67
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
#define M_MOVLD(l, d)
Definition: codegen.hpp:531
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define M_BLEZ(a, disp)
Definition: codegen.hpp:254
#define INT_ARG_CNT
Definition: md-abi.hpp:74
#define M_LSRL_IMM(a, b, c)
Definition: codegen.hpp:472
#define M_CMPLT_IMM(a, b, c)
Definition: codegen.hpp:288
#define M_FCMPEQD(a, b)
Definition: codegen.hpp:544
#define M_FADD(a, b, c)
Definition: codegen.hpp:373
s4 flags
Definition: class.hpp:90
#define M_FCMPOLTD(a, b)
Definition: codegen.hpp:548
#define M_IMUL(a, b, c)
Definition: codegen.hpp:267
#define M_ASUB_IMM(a, b, c)
Definition: codegen.hpp:278
typedesc * fd
Definition: references.hpp:74
s4 * local_map
Definition: jit.hpp:153
#define REG_FTMP2
Definition: md-abi.hpp:66
#define M_IMULU(a, b)
Definition: codegen.hpp:429
#define M_LSRL(a, b, c)
Definition: codegen.hpp:465
MIIterator i
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
typedesc returntype
Definition: descriptor.hpp:166
#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
classinfo * clazz
Definition: field.hpp:55
registerdata * rd
Definition: jit.hpp:130
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
#define M_CMPLT(a, b, c)
Definition: codegen.hpp:281
s4 index
Definition: class.hpp:116
union instruction::@12 sx
#define REG_RA
Definition: md-abi.hpp:41
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:346
#define PACK_REGS(low, high)
#define PATCHER_checkcast_interface
#define M_ASLL_IMM(a, b, c)
Definition: codegen.hpp:581
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_LSRA(a, b, c)
Definition: codegen.hpp:466
basicblock * block
Definition: instruction.hpp:50
#define PATCHER_invokestatic_special
#define M_BST(a, b, disp)
Definition: codegen.hpp:211
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
#define BRANCH_LABEL_1
Definition: emit-common.hpp:47
vftbl_t * vftbl
Definition: class.hpp:121
#define M_FST_INTERN(a, b, disp)
Definition: codegen.hpp:341
methoddesc * parseddesc
Definition: method.hpp:78
#define M_FDIV(a, b, c)
Definition: codegen.hpp:379
#define REG_FTMP1
Definition: md-abi.hpp:65
#define M_FLOORDL(a, c)
Definition: codegen.hpp:515
#define M_AND_IMM(a, b, c)
Definition: codegen.hpp:298
#define PATCHER_invokevirtual
#define M_LSLL(a, b, c)
Definition: codegen.hpp:464
Definition: builtin.hpp:60
#define M_DSUB(a, b, c)
Definition: codegen.hpp:376
methodinfo * m
Definition: jit.hpp:127
s4 type
Definition: field.hpp:60
#define M_ISRL_IMM(a, b, c)
Definition: codegen.hpp:469
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 FLT_ARG_CNT
Definition: md-abi.hpp:81
s4 flags
Definition: reg.hpp:45
#define M_FLOORFL(a, c)
Definition: codegen.hpp:514
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_BLDS(a, b, disp)
Definition: codegen.hpp:149
#define M_ISLL_IMM(a, b, c)
Definition: codegen.hpp:468
#define M_DLD_INTERN(a, b, disp)
Definition: codegen.hpp:315
int8_t s1
Definition: types.hpp:39
#define LCONST(d, c)
Definition: codegen.hpp:54
static bool class_is_or_almost_initialized(classinfo *c)
Definition: class.hpp:433
int16_t s2
Definition: types.hpp:42
#define PATCHER_initialize_class
#define M_IADD(a, b, c)
Definition: codegen.hpp:263
#define M_CMPUGT(a, b, c)
Definition: codegen.hpp:448
#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
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
functionptr fp
Definition: builtin.hpp:63
void emit_label(codegendata *cd, s4 label)
#define M_CLR(c)
Definition: codegen.hpp:303
s4 flags
Definition: method.hpp:70
#define M_SLDU(a, b, disp)
Definition: codegen.hpp:178
#define M_IADD_IMM(a, b, c)
Definition: codegen.hpp:270
#define M_CMPGT(a, b, c)
Definition: codegen.hpp:445
#define M_FCMPULEF(a, b)
Definition: codegen.hpp:553
#define M_NOP
Definition: codegen.hpp:338
#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
static void emit_dmove(codegendata *cd, int s, int d)
Generates an double-move from register s to d.
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
#define M_LMUL(a, b, c)
Definition: codegen.hpp:268
#define M_DDIV(a, b, c)
Definition: codegen.hpp:380
uint32_t regoff
Definition: descriptor.hpp:153
#define M_AADD(a, b, c)
Definition: codegen.hpp:578
s4 dseg_add_float(codegendata *cd, float value)
Definition: dseg.cpp:392
#define M_LDIV(a, b)
Definition: codegen.hpp:432
#define M_BNEZ(a, disp)
Definition: codegen.hpp:255
#define OFFSET(s, el)
Definition: memory.hpp:90
#define M_SLDS(a, b, disp)
Definition: codegen.hpp:151
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)
#define M_TRUNCFL(a, c)
Definition: codegen.hpp:510
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define REG_ITMP1
Definition: md-abi.hpp:46
#define M_DMOV(b, c)
Definition: codegen.hpp:342
static VM * get_current()
Definition: vm.hpp:99
#define REG_RESULT_PACKED
Definition: md-abi.hpp:133
#define M_DST_INTERN(a, b, disp)
Definition: codegen.hpp:342
#define M_ILD_INTERN(a, b, disp)
Definition: codegen.hpp:180
#define M_DADD(a, b, c)
Definition: codegen.hpp:374
#define M_MOVDI(d, i)
Definition: codegen.hpp:528
#define M_FBF(disp)
Definition: codegen.hpp:556