CACAO
codegen.cpp
Go to the documentation of this file.
1 /* src/vm/jit/alpha/codegen.cpp - machine code generator for Alpha
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <cassert>
29 #include <cstdio>
30 
31 #include "vm/types.hpp"
32 
33 #include "md.hpp"
34 #include "md-abi.hpp"
35 
36 #include "vm/jit/alpha/arch.hpp"
37 #include "vm/jit/alpha/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/descriptor.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/field.hpp"
49 #include "vm/global.hpp"
50 #include "vm/loader.hpp"
51 #include "vm/options.hpp"
52 #include "vm/vm.hpp"
53 
54 #include "vm/jit/abi.hpp"
55 #include "vm/jit/asmpart.hpp"
56 #include "vm/jit/builtin.hpp"
58 #include "vm/jit/dseg.hpp"
59 #include "vm/jit/emit-common.hpp"
60 #include "vm/jit/jit.hpp"
62 #include "vm/jit/parse.hpp"
64 #include "vm/jit/reg.hpp"
65 #include "vm/jit/stacktrace.hpp"
66 #include "vm/jit/trap.hpp"
67 
68 
69 /**
70  * Generates machine code for the method prolog.
71  */
73 {
74  varinfo* var;
75  methoddesc* md;
76  int32_t s1;
77  int32_t p, t, l;
78  int32_t varindex;
79  int i;
80 
81  // Get required compiler data.
82  methodinfo* m = jd->m;
83  codeinfo* code = jd->code;
84  codegendata* cd = jd->cd;
85  registerdata* rd = jd->rd;
86 
87  /* create stack frame (if necessary) */
88 
89  if (cd->stackframesize)
90  M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
91 
92  /* save return address and used callee saved registers */
93 
94  p = cd->stackframesize;
95  if (!code_is_leafmethod(code)) {
96  p--; M_AST(REG_RA, REG_SP, p * 8);
97  }
98  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
99  p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
100  }
101  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
102  p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
103  }
104 
105  /* take arguments out of register or stack frame */
106 
107  md = m->parseddesc;
108 
109  for (p = 0, l = 0; p < md->paramcount; p++) {
110  t = md->paramtypes[p].type;
111 
112  varindex = jd->local_map[l * 5 + t];
113 
114  l++;
115  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
116  l++;
117 
118  if (varindex == jitdata::UNUSED)
119  continue;
120 
121  var = VAR(varindex);
122 
123  s1 = md->params[p].regoff;
124 
125  if (IS_INT_LNG_TYPE(t)) { /* integer args */
126  if (!md->params[p].inmemory) { /* register arguments */
127  if (!IS_INMEMORY(var->flags))
128  M_INTMOVE(s1, var->vv.regoff);
129  else
130  M_LST(s1, REG_SP, var->vv.regoff);
131  }
132  else { /* stack arguments */
133  if (!IS_INMEMORY(var->flags))
134  M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
135  else
136  var->vv.regoff = cd->stackframesize * 8 + s1;
137  }
138  }
139  else { /* floating args */
140  if (!md->params[p].inmemory) { /* register arguments */
141  if (!IS_INMEMORY(var->flags))
142  emit_fmove(cd, s1, var->vv.regoff);
143  else
144  if (IS_2_WORD_TYPE(t))
145  M_DST(s1, REG_SP, var->vv.regoff);
146  else
147  M_FST(s1, REG_SP, var->vv.regoff);
148  }
149  else { /* stack arguments */
150  if (!(var->flags & INMEMORY))
151  if (IS_2_WORD_TYPE(t))
152  M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
153  else
154  M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
155  else
156  var->vv.regoff = cd->stackframesize * 8 + s1;
157  }
158  }
159  }
160 }
161 
162 
163 /**
164  * Generates machine code for the method epilog.
165  */
167 {
168  int32_t p;
169  int i;
170 
171  // Get required compiler data.
172  codeinfo* code = jd->code;
173  codegendata* cd = jd->cd;
174  registerdata* rd = jd->rd;
175 
176  p = cd->stackframesize;
177 
178  /* restore return address */
179 
180  if (!code_is_leafmethod(code)) {
181  p--; M_LLD(REG_RA, REG_SP, p * 8);
182  }
183 
184  /* restore saved registers */
185 
186  for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187  p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
188  }
189  for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190  p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
191  }
192 
193  /* deallocate stack */
194 
195  if (cd->stackframesize)
196  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
197 
199 }
200 
201 
202 /**
203  * Generates machine code for one ICMD.
204  */
206 {
207  varinfo* var;
208  builtintable_entry* bte;
209  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
210  unresolved_method* um;
211  fieldinfo* fi;
212  unresolved_field* uf;
213  int32_t fieldtype;
214  int32_t s1, s2, s3, d = 0;
215  int32_t disp;
216 
217  // Get required compiler data.
218  codegendata* cd = jd->cd;
219 
220  switch (iptr->opc) {
221 
222  /* constant operations ************************************************/
223 
224  case ICMD_FCONST: /* ... ==> ..., constant */
225 
226  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
227  disp = dseg_add_float(cd, iptr->sx.val.f);
228  M_FLD(d, REG_PV, disp);
229  emit_store_dst(jd, iptr, d);
230  break;
231 
232  case ICMD_DCONST: /* ... ==> ..., constant */
233 
234  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
235  disp = dseg_add_double(cd, iptr->sx.val.d);
236  M_DLD(d, REG_PV, disp);
237  emit_store_dst(jd, iptr, d);
238  break;
239 
240  case ICMD_ACONST: /* ... ==> ..., constant */
241 
242  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
243 
244  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
245  constant_classref *cr = iptr->sx.val.c.ref;
246 
247  disp = dseg_add_unique_address(cd, cr);
248 
249  /* XXX Only add the patcher, if this position needs to
250  be patched. If there was a previous position which
251  resolved the same class, the returned displacement
252  of dseg_add_address is ok to use. */
253 
255  cr, disp);
256 
257  M_ALD(d, REG_PV, disp);
258  }
259  else {
260  if (iptr->sx.val.anyptr == NULL)
261  M_INTMOVE(REG_ZERO, d);
262  else {
263  disp = dseg_add_address(cd, iptr->sx.val.anyptr);
264  M_ALD(d, REG_PV, disp);
265  }
266  }
267  emit_store_dst(jd, iptr, d);
268  break;
269 
270 
271  /* integer operations *************************************************/
272 
273  case ICMD_INEG: /* ..., value ==> ..., - value */
274 
275  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
276  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
277  M_ISUB(REG_ZERO, s1, d);
278  emit_store_dst(jd, iptr, d);
279  break;
280 
281  case ICMD_LNEG: /* ..., value ==> ..., - value */
282 
283  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
284  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
285  M_LSUB(REG_ZERO, s1, d);
286  emit_store_dst(jd, iptr, d);
287  break;
288 
289  case ICMD_I2L: /* ..., value ==> ..., value */
290 
291  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
292  d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
293  M_INTMOVE(s1, d);
294  emit_store_dst(jd, iptr, d);
295  break;
296 
297  case ICMD_L2I: /* ..., value ==> ..., value */
298 
299  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
300  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
301  M_IADD(s1, REG_ZERO, d);
302  emit_store_dst(jd, iptr, d);
303  break;
304 
305  case ICMD_INT2BYTE: /* ..., value ==> ..., value */
306 
307  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
308  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
309  if (has_ext_instr_set) {
310  M_BSEXT(s1, d);
311  } else {
312  M_SLL_IMM(s1, 56, d);
313  M_SRA_IMM( d, 56, d);
314  }
315  emit_store_dst(jd, iptr, d);
316  break;
317 
318  case ICMD_INT2CHAR: /* ..., value ==> ..., value */
319 
320  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
321  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
322  M_CZEXT(s1, d);
323  emit_store_dst(jd, iptr, d);
324  break;
325 
326  case ICMD_INT2SHORT: /* ..., value ==> ..., value */
327 
328  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
329  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
330  if (has_ext_instr_set) {
331  M_SSEXT(s1, d);
332  } else {
333  M_SLL_IMM(s1, 48, d);
334  M_SRA_IMM( d, 48, d);
335  }
336  emit_store_dst(jd, iptr, d);
337  break;
338 
339 
340  case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
341 
342  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
343  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
344  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
345  M_IADD(s1, s2, d);
346  emit_store_dst(jd, iptr, d);
347  break;
348 
349  case ICMD_IINC:
350  case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
351  /* sx.val.i = constant */
352 
353  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
354  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
355  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
356  M_IADD_IMM(s1, iptr->sx.val.i, d);
357  } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
358  M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
359  } else {
360  /* XXX maybe use M_LDA? */
361  ICONST(REG_ITMP2, iptr->sx.val.i);
362  M_IADD(s1, REG_ITMP2, d);
363  }
364  emit_store_dst(jd, iptr, d);
365  break;
366 
367  case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
368 
369  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
370  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
371  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
372  M_LADD(s1, s2, d);
373  emit_store_dst(jd, iptr, d);
374  break;
375 
376  case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
377  /* sx.val.l = constant */
378 
379  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
380  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
381  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
382  M_LADD_IMM(s1, iptr->sx.val.l, d);
383  } else {
384  LCONST(REG_ITMP2, iptr->sx.val.l);
385  M_LADD(s1, REG_ITMP2, d);
386  }
387  emit_store_dst(jd, iptr, d);
388  break;
389 
390  case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
391 
392  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
393  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
394  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
395  M_ISUB(s1, s2, d);
396  emit_store_dst(jd, iptr, d);
397  break;
398 
399  case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
400  /* sx.val.i = constant */
401 
402  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
403  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
404  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
405  M_ISUB_IMM(s1, iptr->sx.val.i, d);
406  } else {
407  ICONST(REG_ITMP2, iptr->sx.val.i);
408  M_ISUB(s1, REG_ITMP2, d);
409  }
410  emit_store_dst(jd, iptr, d);
411  break;
412 
413  case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
414 
415  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
416  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
417  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
418  M_LSUB(s1, s2, d);
419  emit_store_dst(jd, iptr, d);
420  break;
421 
422  case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
423  /* sx.val.l = 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.l >= 0) && (iptr->sx.val.l <= 255)) {
428  M_LSUB_IMM(s1, iptr->sx.val.l, d);
429  } else {
430  LCONST(REG_ITMP2, iptr->sx.val.l);
431  M_LSUB(s1, REG_ITMP2, d);
432  }
433  emit_store_dst(jd, iptr, d);
434  break;
435 
436  case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
437 
438  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
439  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
440  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
441  M_IMUL(s1, s2, d);
442  emit_store_dst(jd, iptr, d);
443  break;
444 
445  case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
446  /* sx.val.i = constant */
447 
448  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
449  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
450  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
451  M_IMUL_IMM(s1, iptr->sx.val.i, d);
452  } else {
453  ICONST(REG_ITMP2, iptr->sx.val.i);
454  M_IMUL(s1, REG_ITMP2, d);
455  }
456  emit_store_dst(jd, iptr, d);
457  break;
458 
459  case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
460 
461  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
462  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
463  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
464  M_LMUL(s1, s2, d);
465  emit_store_dst(jd, iptr, d);
466  break;
467 
468  case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
469  /* sx.val.l = constant */
470 
471  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
472  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
473  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
474  M_LMUL_IMM(s1, iptr->sx.val.l, d);
475  } else {
476  LCONST(REG_ITMP2, iptr->sx.val.l);
477  M_LMUL(s1, REG_ITMP2, d);
478  }
479  emit_store_dst(jd, iptr, d);
480  break;
481 
482  case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
483  case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
484 
485  s1 = emit_load_s1(jd, iptr, REG_A0);
486  s2 = emit_load_s2(jd, iptr, REG_A1);
487  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
488  emit_arithmetic_check(cd, iptr, s2);
489 
490  M_INTMOVE(s1, REG_A0);
491  M_INTMOVE(s2, REG_A1);
492  bte = iptr->sx.s23.s3.bte;
493  disp = dseg_add_functionptr(cd, bte->fp);
494  M_ALD(REG_PV, REG_PV, disp);
495  M_JSR(REG_RA, REG_PV);
496  disp = (s4) (cd->mcodeptr - cd->mcodebase);
497  M_LDA(REG_PV, REG_RA, -disp);
498 
499  M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
500  emit_store_dst(jd, iptr, d);
501  break;
502 
503  case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
504  case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
505 
506  s1 = emit_load_s1(jd, iptr, REG_A0);
507  s2 = emit_load_s2(jd, iptr, REG_A1);
508  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
509  emit_arithmetic_check(cd, iptr, s2);
510 
511  M_INTMOVE(s1, REG_A0);
512  M_INTMOVE(s2, REG_A1);
513  bte = iptr->sx.s23.s3.bte;
514  disp = dseg_add_functionptr(cd, bte->fp);
515  M_ALD(REG_PV, REG_PV, disp);
516  M_JSR(REG_RA, REG_PV);
517  disp = (s4) (cd->mcodeptr - cd->mcodebase);
518  M_LDA(REG_PV, REG_RA, -disp);
519 
520  M_INTMOVE(REG_RESULT, d);
521  emit_store_dst(jd, iptr, d);
522  break;
523 
524  case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
525  case ICMD_LDIVPOW2: /* val.i = constant */
526 
527  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
528  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
529  if (iptr->sx.val.i <= 15) {
530  M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
531  M_CMOVGE(s1, s1, REG_ITMP2);
532  } else {
533  M_SRA_IMM(s1, 63, REG_ITMP2);
534  M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
535  M_LADD(s1, REG_ITMP2, REG_ITMP2);
536  }
537  M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
538  emit_store_dst(jd, iptr, d);
539  break;
540 
541  case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
542 
543  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
545  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
546  M_AND_IMM(s2, 0x1f, REG_ITMP3);
547  M_SLL(s1, REG_ITMP3, d);
548  M_IADD(d, REG_ZERO, d);
549  emit_store_dst(jd, iptr, d);
550  break;
551 
552  case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
553  /* sx.val.i = constant */
554 
555  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557  M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
558  M_IADD(d, REG_ZERO, d);
559  emit_store_dst(jd, iptr, d);
560  break;
561 
562  case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
563 
564  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
566  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
567  M_AND_IMM(s2, 0x1f, REG_ITMP3);
568  M_SRA(s1, REG_ITMP3, d);
569  emit_store_dst(jd, iptr, d);
570  break;
571 
572  case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
573  /* sx.val.i = constant */
574 
575  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577  M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
578  emit_store_dst(jd, iptr, d);
579  break;
580 
581  case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
582 
583  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
585  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586  M_AND_IMM(s2, 0x1f, REG_ITMP3);
587  M_IZEXT(s1, d);
588  M_SRL(d, REG_ITMP3, d);
589  M_IADD(d, REG_ZERO, d);
590  emit_store_dst(jd, iptr, d);
591  break;
592 
593  case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
594  /* sx.val.i = constant */
595 
596  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598  M_IZEXT(s1, d);
599  M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
600  M_IADD(d, REG_ZERO, d);
601  emit_store_dst(jd, iptr, d);
602  break;
603 
604  case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
605 
606  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
608  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
609  M_SLL(s1, s2, d);
610  emit_store_dst(jd, iptr, d);
611  break;
612 
613  case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
614  /* sx.val.i = constant */
615 
616  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618  M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
619  emit_store_dst(jd, iptr, d);
620  break;
621 
622  case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
623 
624  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
626  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627  M_SRA(s1, s2, d);
628  emit_store_dst(jd, iptr, d);
629  break;
630 
631  case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
632  /* sx.val.i = constant */
633 
634  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
636  M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
637  emit_store_dst(jd, iptr, d);
638  break;
639 
640  case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
641 
642  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
644  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
645  M_SRL(s1, s2, d);
646  emit_store_dst(jd, iptr, d);
647  break;
648 
649  case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
650  /* sx.val.i = constant */
651 
652  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
654  M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
655  emit_store_dst(jd, iptr, d);
656  break;
657 
658  case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
659  case ICMD_LAND:
660 
661  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
663  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664  M_AND(s1, s2, d);
665  emit_store_dst(jd, iptr, d);
666  break;
667 
668  case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
669  /* sx.val.i = constant */
670 
671  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
673  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
674  M_AND_IMM(s1, iptr->sx.val.i, d);
675  } else if (iptr->sx.val.i == 0xffff) {
676  M_CZEXT(s1, d);
677  } else if (iptr->sx.val.i == 0xffffff) {
678  M_ZAPNOT_IMM(s1, 0x07, d);
679  } else {
680  ICONST(REG_ITMP2, iptr->sx.val.i);
681  M_AND(s1, REG_ITMP2, d);
682  }
683  emit_store_dst(jd, iptr, d);
684  break;
685 
686  case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
687  /* sx.val.i = constant */
688 
689  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
691  if (s1 == d) {
692  M_MOV(s1, REG_ITMP1);
693  s1 = REG_ITMP1;
694  }
695  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
696  M_AND_IMM(s1, iptr->sx.val.i, d);
697  M_BGEZ(s1, 3);
698  M_ISUB(REG_ZERO, s1, d);
699  M_AND_IMM(d, iptr->sx.val.i, d);
700  } else if (iptr->sx.val.i == 0xffff) {
701  M_CZEXT(s1, d);
702  M_BGEZ(s1, 3);
703  M_ISUB(REG_ZERO, s1, d);
704  M_CZEXT(d, d);
705  } else if (iptr->sx.val.i == 0xffffff) {
706  M_ZAPNOT_IMM(s1, 0x07, d);
707  M_BGEZ(s1, 3);
708  M_ISUB(REG_ZERO, s1, d);
709  M_ZAPNOT_IMM(d, 0x07, d);
710  } else {
711  ICONST(REG_ITMP3, iptr->sx.val.i);
712  M_AND(s1, REG_ITMP3, d);
713  M_BGEZ(s1, 3);
714  M_ISUB(REG_ZERO, s1, d);
715  M_AND(d, REG_ITMP3, d);
716  }
717  M_ISUB(REG_ZERO, d, d);
718  emit_store_dst(jd, iptr, d);
719  break;
720 
721  case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
722  /* sx.val.l = constant */
723 
724  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
726  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
727  M_AND_IMM(s1, iptr->sx.val.l, d);
728  } else if (iptr->sx.val.l == 0xffffL) {
729  M_CZEXT(s1, d);
730  } else if (iptr->sx.val.l == 0xffffffL) {
731  M_ZAPNOT_IMM(s1, 0x07, d);
732  } else if (iptr->sx.val.l == 0xffffffffL) {
733  M_IZEXT(s1, d);
734  } else if (iptr->sx.val.l == 0xffffffffffL) {
735  M_ZAPNOT_IMM(s1, 0x1f, d);
736  } else if (iptr->sx.val.l == 0xffffffffffffL) {
737  M_ZAPNOT_IMM(s1, 0x3f, d);
738  } else if (iptr->sx.val.l == 0xffffffffffffffL) {
739  M_ZAPNOT_IMM(s1, 0x7f, d);
740  } else {
741  LCONST(REG_ITMP2, iptr->sx.val.l);
742  M_AND(s1, REG_ITMP2, d);
743  }
744  emit_store_dst(jd, iptr, d);
745  break;
746 
747  case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
748  /* sx.val.l = constant */
749 
750  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752  if (s1 == d) {
753  M_MOV(s1, REG_ITMP1);
754  s1 = REG_ITMP1;
755  }
756  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
757  M_AND_IMM(s1, iptr->sx.val.l, d);
758  M_BGEZ(s1, 3);
759  M_LSUB(REG_ZERO, s1, d);
760  M_AND_IMM(d, iptr->sx.val.l, d);
761  } else if (iptr->sx.val.l == 0xffffL) {
762  M_CZEXT(s1, d);
763  M_BGEZ(s1, 3);
764  M_LSUB(REG_ZERO, s1, d);
765  M_CZEXT(d, d);
766  } else if (iptr->sx.val.l == 0xffffffL) {
767  M_ZAPNOT_IMM(s1, 0x07, d);
768  M_BGEZ(s1, 3);
769  M_LSUB(REG_ZERO, s1, d);
770  M_ZAPNOT_IMM(d, 0x07, d);
771  } else if (iptr->sx.val.l == 0xffffffffL) {
772  M_IZEXT(s1, d);
773  M_BGEZ(s1, 3);
774  M_LSUB(REG_ZERO, s1, d);
775  M_IZEXT(d, d);
776  } else if (iptr->sx.val.l == 0xffffffffffL) {
777  M_ZAPNOT_IMM(s1, 0x1f, d);
778  M_BGEZ(s1, 3);
779  M_LSUB(REG_ZERO, s1, d);
780  M_ZAPNOT_IMM(d, 0x1f, d);
781  } else if (iptr->sx.val.l == 0xffffffffffffL) {
782  M_ZAPNOT_IMM(s1, 0x3f, d);
783  M_BGEZ(s1, 3);
784  M_LSUB(REG_ZERO, s1, d);
785  M_ZAPNOT_IMM(d, 0x3f, d);
786  } else if (iptr->sx.val.l == 0xffffffffffffffL) {
787  M_ZAPNOT_IMM(s1, 0x7f, d);
788  M_BGEZ(s1, 3);
789  M_LSUB(REG_ZERO, s1, d);
790  M_ZAPNOT_IMM(d, 0x7f, d);
791  } else {
792  LCONST(REG_ITMP3, iptr->sx.val.l);
793  M_AND(s1, REG_ITMP3, d);
794  M_BGEZ(s1, 3);
795  M_LSUB(REG_ZERO, s1, d);
796  M_AND(d, REG_ITMP3, d);
797  }
798  M_LSUB(REG_ZERO, d, d);
799  emit_store_dst(jd, iptr, d);
800  break;
801 
802  case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
803  case ICMD_LOR:
804 
805  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
807  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808  M_OR( s1,s2, d);
809  emit_store_dst(jd, iptr, d);
810  break;
811 
812  case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
813  /* sx.val.i = constant */
814 
815  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
818  M_OR_IMM(s1, iptr->sx.val.i, d);
819  } else {
820  ICONST(REG_ITMP2, iptr->sx.val.i);
821  M_OR(s1, REG_ITMP2, d);
822  }
823  emit_store_dst(jd, iptr, d);
824  break;
825 
826  case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
827  /* sx.val.l = constant */
828 
829  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
831  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
832  M_OR_IMM(s1, iptr->sx.val.l, d);
833  } else {
834  LCONST(REG_ITMP2, iptr->sx.val.l);
835  M_OR(s1, REG_ITMP2, d);
836  }
837  emit_store_dst(jd, iptr, d);
838  break;
839 
840  case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
841  case ICMD_LXOR:
842 
843  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
845  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
846  M_XOR(s1, s2, d);
847  emit_store_dst(jd, iptr, d);
848  break;
849 
850  case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
851  /* sx.val.i = constant */
852 
853  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855  if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
856  M_XOR_IMM(s1, iptr->sx.val.i, d);
857  } else {
858  ICONST(REG_ITMP2, iptr->sx.val.i);
859  M_XOR(s1, REG_ITMP2, d);
860  }
861  emit_store_dst(jd, iptr, d);
862  break;
863 
864  case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
865  /* sx.val.l = constant */
866 
867  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869  if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
870  M_XOR_IMM(s1, iptr->sx.val.l, d);
871  } else {
872  LCONST(REG_ITMP2, iptr->sx.val.l);
873  M_XOR(s1, REG_ITMP2, d);
874  }
875  emit_store_dst(jd, iptr, d);
876  break;
877 
878 
879  case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
880 
881  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
883  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
884  M_CMPLT(s1, s2, REG_ITMP3);
885  M_CMPLT(s2, s1, REG_ITMP1);
887  emit_store_dst(jd, iptr, d);
888  break;
889 
890 
891  /* floating operations ************************************************/
892 
893  case ICMD_FNEG: /* ..., value ==> ..., - value */
894 
895  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
896  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
897  M_FMOVN(s1, d);
898  emit_store_dst(jd, iptr, d);
899  break;
900 
901  case ICMD_DNEG: /* ..., value ==> ..., - value */
902 
903  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
904  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
905  M_FMOVN(s1, d);
906  emit_store_dst(jd, iptr, d);
907  break;
908 
909  case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
910 
911  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
912  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
913  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
914  if (d == s1 || d == s2) {
915  M_FADDS(s1, s2, REG_FTMP3);
916  M_TRAPB;
917  M_FMOV(REG_FTMP3, d);
918  } else {
919  M_FADDS(s1, s2, d);
920  M_TRAPB;
921  }
922  emit_store_dst(jd, iptr, d);
923  break;
924 
925  case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
926 
927  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
928  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
929  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
930  if (d == s1 || d == s2) {
931  M_DADDS(s1, s2, REG_FTMP3);
932  M_TRAPB;
933  M_FMOV(REG_FTMP3, d);
934  } else {
935  M_DADDS(s1, s2, d);
936  M_TRAPB;
937  }
938  emit_store_dst(jd, iptr, d);
939  break;
940 
941  case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
942 
943  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
944  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
945  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
946  if (d == s1 || d == s2) {
947  M_FSUBS(s1, s2, REG_FTMP3);
948  M_TRAPB;
949  M_FMOV(REG_FTMP3, d);
950  } else {
951  M_FSUBS(s1, s2, d);
952  M_TRAPB;
953  }
954  emit_store_dst(jd, iptr, d);
955  break;
956 
957  case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
958 
959  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
960  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
961  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
962  if (d == s1 || d == s2) {
963  M_DSUBS(s1, s2, REG_FTMP3);
964  M_TRAPB;
965  M_FMOV(REG_FTMP3, d);
966  } else {
967  M_DSUBS(s1, s2, d);
968  M_TRAPB;
969  }
970  emit_store_dst(jd, iptr, d);
971  break;
972 
973  case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
974 
975  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
976  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
977  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
978  if (d == s1 || d == s2) {
979  M_FMULS(s1, s2, REG_FTMP3);
980  M_TRAPB;
981  M_FMOV(REG_FTMP3, d);
982  } else {
983  M_FMULS(s1, s2, d);
984  M_TRAPB;
985  }
986  emit_store_dst(jd, iptr, d);
987  break;
988 
989  case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
990 
991  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
992  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
993  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
994  if (d == s1 || d == s2) {
995  M_DMULS(s1, s2, REG_FTMP3);
996  M_TRAPB;
997  M_FMOV(REG_FTMP3, d);
998  } else {
999  M_DMULS(s1, s2, d);
1000  M_TRAPB;
1001  }
1002  emit_store_dst(jd, iptr, d);
1003  break;
1004 
1005  case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1006 
1007  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1008  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1009  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1010  if (d == s1 || d == s2) {
1011  M_FDIVS(s1, s2, REG_FTMP3);
1012  M_TRAPB;
1013  M_FMOV(REG_FTMP3, d);
1014  } else {
1015  M_FDIVS(s1, s2, d);
1016  M_TRAPB;
1017  }
1018  emit_store_dst(jd, iptr, d);
1019  break;
1020 
1021  case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1022 
1023  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1024  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1025  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1026  if (d == s1 || d == s2) {
1027  M_DDIVS(s1, s2, REG_FTMP3);
1028  M_TRAPB;
1029  M_FMOV(REG_FTMP3, d);
1030  } else {
1031  M_DDIVS(s1, s2, d);
1032  M_TRAPB;
1033  }
1034  emit_store_dst(jd, iptr, d);
1035  break;
1036 
1037  case ICMD_I2F: /* ..., value ==> ..., (float) value */
1038  case ICMD_L2F:
1039  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1041  disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1042  M_LST(s1, REG_PV, disp);
1043  M_DLD(d, REG_PV, disp);
1044  M_CVTLF(d, d);
1045  emit_store_dst(jd, iptr, d);
1046  break;
1047 
1048  case ICMD_I2D: /* ..., value ==> ..., (double) value */
1049  case ICMD_L2D:
1050  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1052  disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1053  M_LST(s1, REG_PV, disp);
1054  M_DLD(d, REG_PV, disp);
1055  M_CVTLD(d, d);
1056  emit_store_dst(jd, iptr, d);
1057  break;
1058 
1059  case ICMD_F2I: /* ..., value ==> ..., (int) value */
1060  case ICMD_D2I:
1061  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1062  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1063  disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1064  M_CVTDL_C(s1, REG_FTMP2);
1066  M_DST(REG_FTMP3, REG_PV, disp);
1067  M_ILD(d, REG_PV, disp);
1068  emit_store_dst(jd, iptr, d);
1069  break;
1070 
1071  case ICMD_F2L: /* ..., value ==> ..., (long) value */
1072  case ICMD_D2L:
1073  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1074  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1075  disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1076  M_CVTDL_C(s1, REG_FTMP2);
1077  M_DST(REG_FTMP2, REG_PV, disp);
1078  M_LLD(d, REG_PV, disp);
1079  emit_store_dst(jd, iptr, d);
1080  break;
1081 
1082  case ICMD_F2D: /* ..., value ==> ..., (double) value */
1083 
1084  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1085  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1086  M_CVTFDS(s1, d);
1087  M_TRAPB;
1088  emit_store_dst(jd, iptr, d);
1089  break;
1090 
1091  case ICMD_D2F: /* ..., value ==> ..., (float) value */
1092 
1093  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1094  d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1095  M_CVTDFS(s1, d);
1096  M_TRAPB;
1097  emit_store_dst(jd, iptr, d);
1098  break;
1099 
1100  case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1101  case ICMD_DCMPL:
1102  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1104  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1105  M_LSUB_IMM(REG_ZERO, 1, d);
1106  M_FCMPEQS(s1, s2, REG_FTMP3);
1107  M_TRAPB;
1108  M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1109  M_CLR (d);
1110  M_FCMPLTS(s2, s1, REG_FTMP3);
1111  M_TRAPB;
1112  M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1113  M_LADD_IMM(REG_ZERO, 1, d);
1114  emit_store_dst(jd, iptr, d);
1115  break;
1116 
1117  case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1118  case ICMD_DCMPG:
1119  s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1120  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1121  d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1122  M_LADD_IMM(REG_ZERO, 1, d);
1123  M_FCMPEQS(s1, s2, REG_FTMP3);
1124  M_TRAPB;
1125  M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1126  M_CLR (d);
1127  M_FCMPLTS(s1, s2, REG_FTMP3);
1128  M_TRAPB;
1129  M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1130  M_LSUB_IMM(REG_ZERO, 1, d);
1131  emit_store_dst(jd, iptr, d);
1132  break;
1133 
1134 
1135  /* memory operations **************************************************/
1136 
1137  case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1138 
1139  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1141  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1142  /* implicit null-pointer check */
1143  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1144  if (has_ext_instr_set) {
1145  M_LADD(s2, s1, REG_ITMP1);
1146  M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1147  M_BSEXT(d, d);
1148  }
1149  else {
1150  M_LADD(s2, s1, REG_ITMP1);
1154  M_SRA_IMM(d, 56, d);
1155  }
1156  emit_store_dst(jd, iptr, d);
1157  break;
1158 
1159  case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1160 
1161  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1162  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1164  /* implicit null-pointer check */
1165  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1166  if (has_ext_instr_set) {
1167  M_LADD(s2, s1, REG_ITMP1);
1168  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1169  M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1170  }
1171  else {
1172  M_LADD (s2, s1, REG_ITMP1);
1173  M_LADD (s2, REG_ITMP1, REG_ITMP1);
1177  }
1178  emit_store_dst(jd, iptr, d);
1179  break;
1180 
1181  case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1182 
1183  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1184  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1185  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1186  /* implicit null-pointer check */
1187  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1188  if (has_ext_instr_set) {
1189  M_LADD(s2, s1, REG_ITMP1);
1190  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1191  M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1192  M_SSEXT(d, d);
1193  } else {
1194  M_LADD(s2, s1, REG_ITMP1);
1195  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1199  M_SRA_IMM(d, 48, d);
1200  }
1201  emit_store_dst(jd, iptr, d);
1202  break;
1203 
1204  case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1205 
1206  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1207  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1208  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1209  /* implicit null-pointer check */
1210  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1211  M_S4ADDQ(s2, s1, REG_ITMP1);
1212  M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1213  emit_store_dst(jd, iptr, d);
1214  break;
1215 
1216  case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1217 
1218  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1220  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221  /* implicit null-pointer check */
1222  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1223  M_S8ADDQ(s2, s1, REG_ITMP1);
1224  M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1225  emit_store_dst(jd, iptr, d);
1226  break;
1227 
1228  case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1229 
1230  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1231  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1232  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1233  /* implicit null-pointer check */
1234  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1235  M_S4ADDQ(s2, s1, REG_ITMP1);
1236  M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1237  emit_store_dst(jd, iptr, d);
1238  break;
1239 
1240  case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1241 
1242  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1243  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1244  d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1245  /* implicit null-pointer check */
1246  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1247  M_S8ADDQ(s2, s1, REG_ITMP1);
1248  M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1249  emit_store_dst(jd, iptr, d);
1250  break;
1251 
1252  case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1253 
1254  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1255  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1256  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1257  /* implicit null-pointer check */
1258  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1259  M_SAADDQ(s2, s1, REG_ITMP1);
1260  M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1261  emit_store_dst(jd, iptr, d);
1262  break;
1263 
1264 
1265  case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1266 
1267  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1268  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1269  /* implicit null-pointer check */
1270  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1271  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1272  if (has_ext_instr_set) {
1273  M_LADD(s2, s1, REG_ITMP1);
1274  M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1275  }
1276  else {
1277  M_LADD(s2, s1, REG_ITMP1);
1280  M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1284  }
1285  break;
1286 
1287  case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1288 
1289  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1290  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1291  /* implicit null-pointer check */
1292  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1293  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1294  if (has_ext_instr_set) {
1295  M_LADD(s2, s1, REG_ITMP1);
1296  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1297  M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1298  }
1299  else {
1300  M_LADD(s2, s1, REG_ITMP1);
1301  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1304  M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1308  }
1309  break;
1310 
1311  case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1312 
1313  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1314  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1315  /* implicit null-pointer check */
1316  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1317  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1318  if (has_ext_instr_set) {
1319  M_LADD(s2, s1, REG_ITMP1);
1320  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1321  M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1322  }
1323  else {
1324  M_LADD(s2, s1, REG_ITMP1);
1325  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1328  M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1332  }
1333  break;
1334 
1335  case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1336 
1337  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1338  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1339  /* implicit null-pointer check */
1340  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1341  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1342  M_S4ADDQ(s2, s1, REG_ITMP1);
1343  M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1344  break;
1345 
1346  case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1347 
1348  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1349  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1350  /* implicit null-pointer check */
1351  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1352  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1353  M_S8ADDQ(s2, s1, REG_ITMP1);
1354  M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1355  break;
1356 
1357  case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1358 
1359  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1360  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1361  /* implicit null-pointer check */
1362  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1363  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1364  M_S4ADDQ(s2, s1, REG_ITMP1);
1365  M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1366  break;
1367 
1368  case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1369 
1370  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1371  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1372  /* implicit null-pointer check */
1373  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1374  s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1375  M_S8ADDQ(s2, s1, REG_ITMP1);
1376  M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1377  break;
1378 
1379  case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1380 
1381  s1 = emit_load_s1(jd, iptr, REG_A0);
1382  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1383  /* implicit null-pointer check */
1384  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1385  s3 = emit_load_s3(jd, iptr, REG_A1);
1386 
1387  M_INTMOVE(s1, REG_A0);
1388  M_INTMOVE(s3, REG_A1);
1389 
1391  M_ALD(REG_PV, REG_PV, disp);
1392  M_JSR(REG_RA, REG_PV);
1393  disp = (s4) (cd->mcodeptr - cd->mcodebase);
1394  M_LDA(REG_PV, REG_RA, -disp);
1395  emit_arraystore_check(cd, iptr);
1396 
1397  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1398  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1399  s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1400  M_SAADDQ(s2, s1, REG_ITMP1);
1401  M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1402  break;
1403 
1404 
1405  case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1406 
1407  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1408  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1409  /* implicit null-pointer check */
1410  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1411  if (has_ext_instr_set) {
1412  M_LADD(s2, s1, REG_ITMP1);
1414  }
1415  else {
1416  M_LADD(s2, s1, REG_ITMP1);
1423  }
1424  break;
1425 
1426  case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1427 
1428  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430  /* implicit null-pointer check */
1431  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1432  if (has_ext_instr_set) {
1433  M_LADD(s2, s1, REG_ITMP1);
1434  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1436  }
1437  else {
1438  M_LADD(s2, s1, REG_ITMP1);
1439  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1446  }
1447  break;
1448 
1449  case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1450 
1451  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1452  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1453  /* implicit null-pointer check */
1454  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1455  if (has_ext_instr_set) {
1456  M_LADD(s2, s1, REG_ITMP1);
1457  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1459  }
1460  else {
1461  M_LADD(s2, s1, REG_ITMP1);
1462  M_LADD(s2, REG_ITMP1, REG_ITMP1);
1469  }
1470  break;
1471 
1472  case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1473 
1474  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1475  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1476  /* implicit null-pointer check */
1477  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1478  M_S4ADDQ(s2, s1, REG_ITMP1);
1480  break;
1481 
1482  case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1483 
1484  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486  /* implicit null-pointer check */
1487  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488  M_S8ADDQ(s2, s1, REG_ITMP1);
1490  break;
1491 
1492  case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1493 
1494  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1495  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1496  /* implicit null-pointer check */
1497  emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1498  M_SAADDQ(s2, s1, REG_ITMP1);
1500  break;
1501 
1502  case ICMD_PUTSTATICCONST: /* ... ==> ... */
1503  /* val = value (in current instruction) */
1504  /* following NOP) */
1505 
1506  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1507  uf = iptr->sx.s23.s3.uf;
1508  fieldtype = uf->fieldref->parseddesc.fd->type;
1509  disp = dseg_add_unique_address(cd, uf);
1510 
1512  }
1513  else {
1514  fi = iptr->sx.s23.s3.fmiref->p.field;
1515  fieldtype = fi->type;
1516  disp = dseg_add_address(cd, fi->value);
1517 
1520  0);
1521  }
1522 
1523  M_ALD(REG_ITMP1, REG_PV, disp);
1524  switch (fieldtype) {
1525  case TYPE_INT:
1526  M_IST(REG_ZERO, REG_ITMP1, 0);
1527  break;
1528  case TYPE_LNG:
1529  M_LST(REG_ZERO, REG_ITMP1, 0);
1530  break;
1531  case TYPE_ADR:
1532  M_AST(REG_ZERO, REG_ITMP1, 0);
1533  break;
1534  case TYPE_FLT:
1535  M_FST(REG_ZERO, REG_ITMP1, 0);
1536  break;
1537  case TYPE_DBL:
1538  M_DST(REG_ZERO, REG_ITMP1, 0);
1539  break;
1540  }
1541  break;
1542 
1543 
1544  case ICMD_GETFIELD: /* ... ==> ..., value */
1545 
1546  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1547 
1548  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1549  uf = iptr->sx.s23.s3.uf;
1550  fieldtype = uf->fieldref->parseddesc.fd->type;
1551  disp = 0;
1552 
1554  }
1555  else {
1556  fi = iptr->sx.s23.s3.fmiref->p.field;
1557  fieldtype = fi->type;
1558  disp = fi->offset;
1559  }
1560 
1561  /* implicit null-pointer check */
1562  switch (fieldtype) {
1563  case TYPE_INT:
1564  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1565  M_ILD(d, s1, disp);
1566  break;
1567  case TYPE_LNG:
1568  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1569  M_LLD(d, s1, disp);
1570  break;
1571  case TYPE_ADR:
1572  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1573  M_ALD(d, s1, disp);
1574  break;
1575  case TYPE_FLT:
1576  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1577  M_FLD(d, s1, disp);
1578  break;
1579  case TYPE_DBL:
1580  d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1581  M_DLD(d, s1, disp);
1582  break;
1583  }
1584  emit_store_dst(jd, iptr, d);
1585  break;
1586 
1587  case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1588 
1589  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 
1591  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1592  uf = iptr->sx.s23.s3.uf;
1593  fieldtype = uf->fieldref->parseddesc.fd->type;
1594  disp = 0;
1595  }
1596  else {
1597  uf = NULL;
1598  fi = iptr->sx.s23.s3.fmiref->p.field;
1599  fieldtype = fi->type;
1600  disp = fi->offset;
1601  }
1602 
1603  if (IS_INT_LNG_TYPE(fieldtype))
1604  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1605  else
1606  s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1607 
1608  if (INSTRUCTION_IS_UNRESOLVED(iptr))
1610 
1611  /* implicit null-pointer check */
1612  switch (fieldtype) {
1613  case TYPE_INT:
1614  M_IST(s2, s1, disp);
1615  break;
1616  case TYPE_LNG:
1617  M_LST(s2, s1, disp);
1618  break;
1619  case TYPE_ADR:
1620  M_AST(s2, s1, disp);
1621  break;
1622  case TYPE_FLT:
1623  M_FST(s2, s1, disp);
1624  break;
1625  case TYPE_DBL:
1626  M_DST(s2, s1, disp);
1627  break;
1628  }
1629  break;
1630 
1631  case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1632  /* val = value (in current instruction) */
1633  /* following NOP) */
1634 
1635  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636 
1637  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1638  uf = iptr->sx.s23.s3.uf;
1639  fieldtype = uf->fieldref->parseddesc.fd->type;
1640  disp = 0;
1641 
1643  }
1644  else {
1645  fi = iptr->sx.s23.s3.fmiref->p.field;
1646  fieldtype = fi->type;
1647  disp = fi->offset;
1648  }
1649 
1650  /* implicit null-pointer check */
1651  switch (fieldtype) {
1652  case TYPE_INT:
1653  M_IST(REG_ZERO, s1, disp);
1654  break;
1655  case TYPE_LNG:
1656  M_LST(REG_ZERO, s1, disp);
1657  break;
1658  case TYPE_ADR:
1659  M_AST(REG_ZERO, s1, disp);
1660  break;
1661  case TYPE_FLT:
1662  M_FST(REG_ZERO, s1, disp);
1663  break;
1664  case TYPE_DBL:
1665  M_DST(REG_ZERO, s1, disp);
1666  break;
1667  }
1668  break;
1669 
1670 
1671  /* branch operations **************************************************/
1672 
1673  case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1674 
1676  break;
1677 
1678  case ICMD_IFEQ: /* ..., value ==> ... */
1679 
1680  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1681  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1682  M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1683  else {
1684  ICONST(REG_ITMP2, iptr->sx.val.i);
1685  M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1686  }
1687  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1688  break;
1689 
1690  case ICMD_IFLT: /* ..., value ==> ... */
1691 
1692  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1693  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1694  M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1695  else {
1696  ICONST(REG_ITMP2, iptr->sx.val.i);
1697  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1698  }
1699  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1700  break;
1701 
1702  case ICMD_IFLE: /* ..., value ==> ... */
1703 
1704  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1706  M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1707  else {
1708  ICONST(REG_ITMP2, iptr->sx.val.i);
1709  M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1710  }
1711  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1712  break;
1713 
1714  case ICMD_IFNE: /* ..., value ==> ... */
1715 
1716  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1717  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1718  M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1719  else {
1720  ICONST(REG_ITMP2, iptr->sx.val.i);
1721  M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1722  }
1723  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1724  break;
1725 
1726  case ICMD_IFGT: /* ..., value ==> ... */
1727 
1728  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1729  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1730  M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1731  else {
1732  ICONST(REG_ITMP2, iptr->sx.val.i);
1733  M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1734  }
1735  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1736  break;
1737 
1738  case ICMD_IFGE: /* ..., value ==> ... */
1739 
1740  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741  if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
1742  M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1743  else {
1744  ICONST(REG_ITMP2, iptr->sx.val.i);
1745  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1746  }
1747  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1748  break;
1749 
1750  case ICMD_IF_LEQ: /* ..., value ==> ... */
1751 
1752  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1753  if (iptr->sx.val.l == 0)
1754  emit_beqz(cd, iptr->dst.block, s1);
1755  else {
1756  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1757  M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1758  else {
1759  LCONST(REG_ITMP2, iptr->sx.val.l);
1760  M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1761  }
1762  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1763  }
1764  break;
1765 
1766  case ICMD_IF_LLT: /* ..., value ==> ... */
1767 
1768  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769  if (iptr->sx.val.l == 0)
1770  emit_bltz(cd, iptr->dst.block, s1);
1771  else {
1772  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1773  M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1774  else {
1775  LCONST(REG_ITMP2, iptr->sx.val.l);
1776  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1777  }
1778  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1779  }
1780  break;
1781 
1782  case ICMD_IF_LLE: /* ..., value ==> ... */
1783 
1784  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785  if (iptr->sx.val.l == 0)
1786  emit_blez(cd, iptr->dst.block, s1);
1787  else {
1788  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1789  M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1790  else {
1791  LCONST(REG_ITMP2, iptr->sx.val.l);
1792  M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1793  }
1794  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1795  }
1796  break;
1797 
1798  case ICMD_IF_LNE: /* ..., value ==> ... */
1799 
1800  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1801  if (iptr->sx.val.l == 0)
1802  emit_bnez(cd, iptr->dst.block, s1);
1803  else {
1804  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1805  M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1806  else {
1807  LCONST(REG_ITMP2, iptr->sx.val.l);
1808  M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
1809  }
1810  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1811  }
1812  break;
1813 
1814  case ICMD_IF_LGT: /* ..., value ==> ... */
1815 
1816  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1817  if (iptr->sx.val.l == 0)
1818  emit_bgtz(cd, iptr->dst.block, s1);
1819  else {
1820  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1821  M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1822  else {
1823  LCONST(REG_ITMP2, iptr->sx.val.l);
1824  M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
1825  }
1826  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1827  }
1828  break;
1829 
1830  case ICMD_IF_LGE: /* ..., value ==> ... */
1831 
1832  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833  if (iptr->sx.val.l == 0)
1834  emit_bgez(cd, iptr->dst.block, s1);
1835  else {
1836  if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
1837  M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
1838  else {
1839  LCONST(REG_ITMP2, iptr->sx.val.l);
1840  M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1841  }
1842  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1843  }
1844  break;
1845 
1846  case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1847  case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
1848 
1849  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1850  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1851  M_CMPEQ(s1, s2, REG_ITMP1);
1852  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1853  break;
1854 
1855  case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1856  case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
1857 
1858  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1859  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1860  M_CMPEQ(s1, s2, REG_ITMP1);
1861  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1862  break;
1863 
1864  case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1865  case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
1866 
1867  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1868  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1869  M_CMPLT(s1, s2, REG_ITMP1);
1870  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1871  break;
1872 
1873  case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1874  case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
1875 
1876  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1877  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1878  M_CMPLE(s1, s2, REG_ITMP1);
1879  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1880  break;
1881 
1882  case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1883  case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
1884 
1885  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1886  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1887  M_CMPLE(s1, s2, REG_ITMP1);
1888  emit_bnez(cd, iptr->dst.block, REG_ITMP1);
1889  break;
1890 
1891  case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1892  case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
1893 
1894  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895  s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896  M_CMPLT(s1, s2, REG_ITMP1);
1897  emit_beqz(cd, iptr->dst.block, REG_ITMP1);
1898  break;
1899 
1900  case ICMD_TABLESWITCH: /* ..., index ==> ... */
1901  {
1902  s4 i, l;
1903  branch_target_t *table;
1904 
1905  table = iptr->dst.table;
1906 
1907  l = iptr->sx.s23.s2.tablelow;
1908  i = iptr->sx.s23.s3.tablehigh;
1909 
1910  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911  if (l == 0) {
1912  M_INTMOVE(s1, REG_ITMP1);
1913  } else if (l <= 32768) {
1914  M_LDA(REG_ITMP1, s1, -l);
1915  } else {
1916  ICONST(REG_ITMP2, l);
1917  M_ISUB(s1, REG_ITMP2, REG_ITMP1);
1918  }
1919 
1920  /* number of targets */
1921  i = i - l + 1;
1922 
1923  /* range check */
1924 
1925  if (i <= 256)
1926  M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
1927  else {
1928  M_LDA(REG_ITMP2, REG_ZERO, i - 1);
1930  }
1931  emit_beqz(cd, table[0].block, REG_ITMP2);
1932 
1933  /* build jump table top down and use address of lowest entry */
1934 
1935  table += i;
1936 
1937  while (--i >= 0) {
1938  dseg_add_target(cd, table->block);
1939  --table;
1940  }
1941  }
1942 
1943  /* length of dataseg after last dseg_add_target is used by load */
1944 
1946  M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
1948  ALIGNCODENOP;
1949  break;
1950 
1951  case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1952  bte = iptr->sx.s23.s3.bte;
1953  if (bte->stub == NULL)
1954  disp = dseg_add_functionptr(cd, bte->fp);
1955  else
1956  disp = dseg_add_functionptr(cd, bte->stub);
1957 
1958  M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
1959 
1960  /* generate the actual call */
1961 
1962  M_JSR(REG_RA, REG_PV);
1963  break;
1964 
1965  case ICMD_INVOKESPECIAL:
1966  emit_nullpointer_check(cd, iptr, REG_A0);
1967  /* fall-through */
1968 
1969  case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1970  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1971  um = iptr->sx.s23.s3.um;
1972  disp = dseg_add_unique_address(cd, um);
1973 
1975  um, disp);
1976  }
1977  else {
1978  lm = iptr->sx.s23.s3.fmiref->p.method;
1979  disp = dseg_add_address(cd, lm->stubroutine);
1980  }
1981 
1982  M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
1983 
1984  /* generate the actual call */
1985 
1986  M_JSR(REG_RA, REG_PV);
1987  break;
1988 
1989  case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1990  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1991  um = iptr->sx.s23.s3.um;
1993 
1994  s1 = 0;
1995  }
1996  else {
1997  lm = iptr->sx.s23.s3.fmiref->p.method;
1998  s1 = OFFSET(vftbl_t, table[0]) +
1999  sizeof(methodptr) * lm->vftblindex;
2000  }
2001 
2002  /* implicit null-pointer check */
2004  M_ALD(REG_PV, REG_METHODPTR, s1);
2005 
2006  /* generate the actual call */
2007 
2008  M_JSR(REG_RA, REG_PV);
2009  break;
2010 
2011  case ICMD_INVOKEINTERFACE:
2012  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2013  um = iptr->sx.s23.s3.um;
2015 
2016  s1 = 0;
2017  s2 = 0;
2018  }
2019  else {
2020  lm = iptr->sx.s23.s3.fmiref->p.method;
2021  s1 = OFFSET(vftbl_t, interfacetable[0]) -
2022  sizeof(methodptr*) * lm->clazz->index;
2023 
2024  s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2025  }
2026 
2027  /* implicit null-pointer check */
2030  M_ALD(REG_PV, REG_METHODPTR, s2);
2031 
2032  /* generate the actual call */
2033 
2034  M_JSR(REG_RA, REG_PV);
2035  break;
2036 
2037  case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2038 
2039  if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2040  /* object type cast-check */
2041 
2042  classinfo *super;
2043  s4 superindex;
2044 
2045  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2046  super = NULL;
2047  superindex = 0;
2048  }
2049  else {
2050  super = iptr->sx.s23.s3.c.cls;
2051  superindex = super->index;
2052  }
2053 
2054  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2055 
2056  /* if class is not resolved, check which code to call */
2057 
2058  if (super == NULL) {
2059  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2060 
2061  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2062 
2064  iptr->sx.s23.s3.c.ref,
2065  disp);
2066 
2067  M_ILD(REG_ITMP2, REG_PV, disp);
2068  disp = dseg_add_s4(cd, ACC_INTERFACE);
2069  M_ILD(REG_ITMP3, REG_PV, disp);
2071  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2072  }
2073 
2074  /* interface checkcast code */
2075 
2076  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2077  if (super == NULL) {
2080  iptr->sx.s23.s3.c.ref,
2081  0);
2082  }
2083  else
2084  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2085 
2086  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2088  OFFSET(vftbl_t, interfacetablelength));
2089  M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2090  emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2091 
2093  (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2094  superindex * sizeof(methodptr*)));
2095  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2096 
2097  if (super == NULL)
2099  else
2101  }
2102 
2103  /* class checkcast code */
2104 
2105  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2106  if (super == NULL) {
2108 
2109  disp = dseg_add_unique_address(cd, NULL);
2110 
2113  iptr->sx.s23.s3.c.ref,
2114  disp);
2115  }
2116  else {
2117  disp = dseg_add_address(cd, super->vftbl);
2118 
2119  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2120  }
2121 
2122  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2123  M_ALD(REG_ITMP3, REG_PV, disp);
2124 
2125  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2126  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2128  M_ALD(REG_ITMP1, REG_ITMP1, 0);
2130  emit_label_bnez(cd, BRANCH_LABEL_6, REG_ITMP1); /* good */
2131 
2132  if (super == NULL) {
2133  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2134  M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2135  emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* throw */
2136  }
2137 
2138  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2139  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2141  emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* throw */
2142  /* reload */
2143  M_ALD(REG_ITMP3, REG_PV, disp);
2144  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2146  M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2148  emit_label_bnez(cd, BRANCH_LABEL_7, REG_ITMP1); /* good */
2149 
2151  if (super == NULL)
2153 
2154  /* reload s1, might have been destroyed */
2155  emit_load_s1(jd, iptr, REG_ITMP1);
2157 
2160  /* reload s1, might have been destroyed */
2161  emit_load_s1(jd, iptr, REG_ITMP1);
2162  }
2163  else {
2164  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2166  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
2167  }
2168 
2169  if (super != NULL)
2171  }
2172 
2173  if (super == NULL) {
2176  }
2177 
2178  d = codegen_reg_of_dst(jd, iptr, s1);
2179  }
2180  else {
2181  /* array type cast-check */
2182 
2183  s1 = emit_load_s1(jd, iptr, REG_A0);
2184  M_INTMOVE(s1, REG_A0);
2185 
2186  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2187  disp = dseg_add_unique_address(cd, NULL);
2188 
2191  iptr->sx.s23.s3.c.ref,
2192  disp);
2193  }
2194  else
2195  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2196 
2197  M_ALD(REG_A1, REG_PV, disp);
2199  M_ALD(REG_PV, REG_PV, disp);
2200  M_JSR(REG_RA, REG_PV);
2201  disp = (s4) (cd->mcodeptr - cd->mcodebase);
2202  M_LDA(REG_PV, REG_RA, -disp);
2203 
2204  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2205  emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2206 
2207  d = codegen_reg_of_dst(jd, iptr, s1);
2208  }
2209 
2210  M_INTMOVE(s1, d);
2211  emit_store_dst(jd, iptr, d);
2212  break;
2213 
2214  case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2215 
2216  {
2217  classinfo *super;
2218  vftbl_t *supervftbl;
2219  s4 superindex;
2220 
2221  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2222  super = NULL;
2223  superindex = 0;
2224  supervftbl = NULL;
2225 
2226  } else {
2227  super = iptr->sx.s23.s3.c.cls;
2228  superindex = super->index;
2229  supervftbl = super->vftbl;
2230  }
2231 
2232  s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2233  d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2234 
2235  if (s1 == d) {
2236  M_MOV(s1, REG_ITMP1);
2237  s1 = REG_ITMP1;
2238  }
2239 
2240  /* if class is not resolved, check which code to call */
2241 
2242  if (super == NULL) {
2243  M_CLR(d);
2244  emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2245 
2246  disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2247 
2249  iptr->sx.s23.s3.c.ref, disp);
2250 
2251  M_ILD(REG_ITMP3, REG_PV, disp);
2252 
2253  disp = dseg_add_s4(cd, ACC_INTERFACE);
2254  M_ILD(REG_ITMP2, REG_PV, disp);
2256  emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2257  }
2258 
2259  /* interface instanceof code */
2260 
2261  if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2262  if (super == NULL) {
2263  /* If d == REG_ITMP2, then it's destroyed in check
2264  code above. */
2265  if (d == REG_ITMP2)
2266  M_CLR(d);
2267 
2270  iptr->sx.s23.s3.c.ref, 0);
2271  }
2272  else {
2273  M_CLR(d);
2274  emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2275  }
2276 
2277  M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2278  M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2279  M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2280  M_BLEZ(REG_ITMP3, 2);
2282  (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2283  superindex * sizeof(methodptr*)));
2284  M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2285 
2286  if (super == NULL)
2288  else
2290  }
2291 
2292  /* class instanceof code */
2293 
2294  if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2295  if (super == NULL) {
2297 
2298  disp = dseg_add_unique_address(cd, NULL);
2299 
2301  iptr->sx.s23.s3.c.ref,
2302  disp);
2303  }
2304  else {
2305  disp = dseg_add_address(cd, supervftbl);
2306 
2307  M_CLR(d);
2308  emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2309  }
2310 
2311  M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2312  M_ALD(REG_ITMP3, REG_PV, disp);
2313 
2314  if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2315  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2317  M_ALD(REG_ITMP1, REG_ITMP1, 0);
2319  emit_label_beqz(cd, BRANCH_LABEL_8, REG_ITMP1);
2320  ICONST(d, 1);
2321  emit_label_br(cd, BRANCH_LABEL_6); /* true */
2323 
2324  if (super == NULL) {
2325  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2326  M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2327  emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* false */
2328  }
2329 
2330  M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2331 
2332  M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2334  emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* false */
2335  /* reload */
2336  M_ALD(REG_ITMP3, REG_PV, disp);
2337  M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2339  M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2341 
2342  if (d == REG_ITMP2)
2345  if (super == NULL)
2347  if (d == REG_ITMP2) {
2348  M_CLR(d);
2349 
2351  }
2353  }
2354  else {
2355  M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2357  }
2358 
2359  if (super != NULL)
2361  }
2362 
2363  if (super == NULL) {
2366  }
2367 
2368  emit_store_dst(jd, iptr, d);
2369  }
2370  break;
2371 
2372  case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2373 
2374  /* check for negative sizes and copy sizes to stack if necessary */
2375 
2376  MCODECHECK((iptr->s1.argcount << 1) + 64);
2377 
2378  for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2379 
2380  var = VAR(iptr->sx.s23.s2.args[s1]);
2381 
2382  /* copy SAVEDVAR sizes to stack */
2383 
2384  /* Already Preallocated? */
2385 
2386  if (!(var->flags & PREALLOC)) {
2387  s2 = emit_load(jd, iptr, var, REG_ITMP1);
2388  M_LST(s2, REG_SP, s1 * 8);
2389  }
2390  }
2391 
2392  /* a0 = dimension count */
2393 
2394  ICONST(REG_A0, iptr->s1.argcount);
2395 
2396  /* is patcher function set? */
2397 
2398  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2399  disp = dseg_add_unique_address(cd, 0);
2400 
2402  iptr->sx.s23.s3.c.ref,
2403  disp);
2404  }
2405  else
2406  disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2407 
2408  /* a1 = arraydescriptor */
2409 
2410  M_ALD(REG_A1, REG_PV, disp);
2411 
2412  /* a2 = pointer to dimensions = stack pointer */
2413 
2415 
2417  M_ALD(REG_PV, REG_PV, disp);
2418  M_JSR(REG_RA, REG_PV);
2419  disp = (s4) (cd->mcodeptr - cd->mcodebase);
2420  M_LDA(REG_PV, REG_RA, -disp);
2421 
2422  /* check for exception before result assignment */
2423 
2424  emit_exception_check(cd, iptr);
2425 
2426  d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2427  M_INTMOVE(REG_RESULT, d);
2428  emit_store_dst(jd, iptr, d);
2429  break;
2430 
2431  default:
2432  vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2433  } /* switch */
2434 }
2435 
2436 
2437 /* codegen_emit_stub_native ****************************************************
2438 
2439  Emits a stub routine which calls a native method.
2440 
2441 *******************************************************************************/
2442 
2443 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2444 {
2445  methodinfo *m;
2446  codeinfo *code;
2447  codegendata *cd;
2448  methoddesc *md;
2449  int i, j;
2450  int t;
2451  int s1, s2;
2452  int disp;
2453 
2454  /* get required compiler data */
2455 
2456  m = jd->m;
2457  code = jd->code;
2458  cd = jd->cd;
2459 
2460  /* initialize variables */
2461 
2462  md = m->parseddesc;
2463 
2464  /* calculate stack frame size */
2465 
2466  cd->stackframesize =
2467  1 + /* return address */
2468  sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2469  sizeof(localref_table) / SIZEOF_VOID_P +
2470  1 + /* methodinfo for call trace */
2471  md->paramcount +
2472  nmd->memuse;
2473 
2474  /* create method header */
2475 
2476  (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2477  (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2478  (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2479  (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2480  (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2481 
2482  /* generate stub code */
2483 
2484  M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
2485  M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
2486 
2487 #if defined(ENABLE_GC_CACAO)
2488  /* Save callee saved integer registers in stackframeinfo (GC may
2489  need to recover them during a collection). */
2490 
2491  disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
2492  OFFSET(stackframeinfo_t, intregs);
2493 
2494  for (i = 0; i < INT_SAV_CNT; i++)
2495  M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2496 #endif
2497 
2498  /* save integer and float argument registers */
2499 
2500  for (i = 0; i < md->paramcount; i++) {
2501  if (!md->params[i].inmemory) {
2502  s1 = md->params[i].regoff;
2503 
2504  switch (md->paramtypes[i].type) {
2505  case TYPE_INT:
2506  case TYPE_LNG:
2507  case TYPE_ADR:
2508  M_LST(s1, REG_SP, i * 8);
2509  break;
2510  case TYPE_FLT:
2511  M_FST(s1, REG_SP, i * 8);
2512  break;
2513  case TYPE_DBL:
2514  M_DST(s1, REG_SP, i * 8);
2515  break;
2516  default:
2517  assert(false);
2518  break;
2519  }
2520  }
2521  }
2522 
2523  /* prepare data structures for native function call */
2524 
2525  M_MOV(REG_SP, REG_A0);
2526  M_MOV(REG_PV, REG_A1);
2528  M_ALD(REG_PV, REG_PV, disp);
2529  M_JSR(REG_RA, REG_PV);
2530  disp = (s4) (cd->mcodeptr - cd->mcodebase);
2531  M_LDA(REG_PV, REG_RA, -disp);
2532 
2533  /* remember class argument */
2534 
2535  if (m->flags & ACC_STATIC)
2537 
2538  /* restore integer and float argument registers */
2539 
2540  for (i = 0; i < md->paramcount; i++) {
2541  if (!md->params[i].inmemory) {
2542  s1 = md->params[i].regoff;
2543 
2544  switch (md->paramtypes[i].type) {
2545  case TYPE_INT:
2546  case TYPE_LNG:
2547  case TYPE_ADR:
2548  M_LLD(s1, REG_SP, i * 8);
2549  break;
2550  case TYPE_FLT:
2551  M_FLD(s1, REG_SP, i * 8);
2552  break;
2553  case TYPE_DBL:
2554  M_DLD(s1, REG_SP, i * 8);
2555  break;
2556  default:
2557  assert(false);
2558  break;
2559  }
2560  }
2561  }
2562 
2563  /* copy or spill arguments to new locations */
2564 
2565  for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2566  t = md->paramtypes[i].type;
2567 
2568  if (IS_INT_LNG_TYPE(t)) {
2569  if (!md->params[i].inmemory) {
2570  s1 = md->params[i].regoff;
2571  s2 = nmd->params[j].regoff;
2572 
2573  if (!nmd->params[j].inmemory)
2574  M_INTMOVE(s1, s2);
2575  else
2576  M_LST(s1, REG_SP, s2);
2577  }
2578  else {
2579  s1 = md->params[i].regoff + cd->stackframesize * 8;
2580  s2 = nmd->params[j].regoff;
2581  M_LLD(REG_ITMP1, REG_SP, s1);
2582  M_LST(REG_ITMP1, REG_SP, s2);
2583  }
2584  }
2585  else {
2586  if (!md->params[i].inmemory) {
2587  s1 = md->params[i].regoff;
2588  s2 = nmd->params[j].regoff;
2589 
2590  if (!nmd->params[j].inmemory)
2591  emit_fmove(cd, s1, s2);
2592  else {
2593  if (IS_2_WORD_TYPE(t))
2594  M_DST(s1, REG_SP, s2);
2595  else
2596  M_FST(s1, REG_SP, s2);
2597  }
2598  }
2599  else {
2600  s1 = md->params[i].regoff + cd->stackframesize * 8;
2601  s2 = nmd->params[j].regoff;
2602  if (IS_2_WORD_TYPE(t)) {
2603  M_DLD(REG_FTMP1, REG_SP, s1);
2604  M_DST(REG_FTMP1, REG_SP, s2);
2605  }
2606  else {
2607  M_FLD(REG_FTMP1, REG_SP, s1);
2608  M_FST(REG_FTMP1, REG_SP, s2);
2609  }
2610  }
2611  }
2612  }
2613 
2614  /* Handle native Java methods. */
2615 
2616  if (m->flags & ACC_NATIVE) {
2617  /* put class into second argument register */
2618 
2619  if (m->flags & ACC_STATIC)
2621 
2622  /* put env into first argument register */
2623 
2624  disp = dseg_add_address(cd, VM::get_current()->get_jnienv());
2625  M_ALD(REG_A0, REG_PV, disp);
2626  }
2627 
2628  /* Call the native function. */
2629 
2630  disp = dseg_add_functionptr(cd, f);
2631  M_ALD(REG_PV, REG_PV, disp);
2632  M_JSR(REG_RA, REG_PV); /* call native method */
2633  disp = (s4) (cd->mcodeptr - cd->mcodebase);
2634  M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
2635 
2636  /* save return value */
2637 
2638  switch (md->returntype.type) {
2639  case TYPE_INT:
2640  case TYPE_LNG:
2641  case TYPE_ADR:
2642  M_LST(REG_RESULT, REG_SP, 0 * 8);
2643  break;
2644  case TYPE_FLT:
2645  M_FST(REG_FRESULT, REG_SP, 0 * 8);
2646  break;
2647  case TYPE_DBL:
2648  M_DST(REG_FRESULT, REG_SP, 0 * 8);
2649  break;
2650  case TYPE_VOID:
2651  break;
2652  default:
2653  assert(false);
2654  break;
2655  }
2656 
2657  /* remove native stackframe info */
2658 
2659  M_MOV(REG_SP, REG_A0);
2660  M_MOV(REG_PV, REG_A1);
2662  M_ALD(REG_PV, REG_PV, disp);
2663  M_JSR(REG_RA, REG_PV);
2664  disp = (s4) (cd->mcodeptr - cd->mcodebase);
2665  M_LDA(REG_PV, REG_RA, -disp);
2667 
2668  /* restore return value */
2669 
2670  switch (md->returntype.type) {
2671  case TYPE_INT:
2672  case TYPE_LNG:
2673  case TYPE_ADR:
2674  M_LLD(REG_RESULT, REG_SP, 0 * 8);
2675  break;
2676  case TYPE_FLT:
2677  M_FLD(REG_FRESULT, REG_SP, 0 * 8);
2678  break;
2679  case TYPE_DBL:
2680  M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2681  break;
2682  case TYPE_VOID:
2683  break;
2684  default:
2685  assert(false);
2686  break;
2687  }
2688 
2689 #if defined(ENABLE_GC_CACAO)
2690  /* Restore callee saved integer registers from stackframeinfo (GC
2691  might have modified them during a collection). */
2692 
2693  disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
2694  OFFSET(stackframeinfo_t, intregs);
2695 
2696  for (i = 0; i < INT_SAV_CNT; i++)
2697  M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2698 #endif
2699 
2700  M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
2701  M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2702 
2703  /* check for exception */
2704 
2705  M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
2706  M_RET(REG_ZERO, REG_RA); /* return to caller */
2707 
2708  /* handle exception */
2709 
2710  M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
2711 
2713 }
2714 
2715 
2716 /*
2717  * These are local overrides for various environment variables in Emacs.
2718  * Please do not remove this and leave it at the end of the file, where
2719  * Emacs will automagically detect them.
2720  * ---------------------------------------------------------------------
2721  * Local variables:
2722  * mode: c++
2723  * indent-tabs-mode: t
2724  * c-basic-offset: 4
2725  * tab-width: 4
2726  * End:
2727  * vim:noexpandtab:sw=4:ts=4:
2728  */
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
#define M_BLDU(a, b, disp)
Definition: codegen.hpp:177
val_operand_t val
#define BUILTIN_FAST_canstore
Definition: builtin.hpp:153
#define PATCHER_resolve_classref_to_flags
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
#define M_SRA(a, b, c)
Definition: codegen.hpp:307
basicblock * block
union varinfo::@19 vv
#define REG_PV
Definition: md-abi.hpp:42
#define M_JSR(a, b)
Definition: codegen.hpp:260
#define M_LMUL_IMM(a, b, c)
Definition: codegen.hpp:275
s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:63
#define M_CMOVGE(a, b, c)
Definition: codegen.hpp:505
#define M_ALD(a, b, disp)
Definition: codegen.hpp:345
#define PATCHER_invokeinterface
#define REG_A1
Definition: md-abi.hpp:36
Definition: jit.hpp:126
#define M_LST(a, b, disp)
Definition: codegen.hpp:349
#define REG_A0
Definition: md-abi.hpp:35
paramdesc * params
Definition: descriptor.hpp:164
#define M_SLL(a, b, c)
Definition: codegen.hpp:306
#define BRANCH_LE
#define M_DDIVS(a, b, c)
Definition: codegen.hpp:389
#define M_ILD(a, b, disp)
Definition: codegen.hpp:347
#define BRANCH_LABEL_7
Definition: emit-common.hpp:53
s4 dseg_add_unique_address(codegendata *cd, void *value)
Definition: dseg.cpp:525
int * savintregs
Definition: reg.hpp:71
methodinfo * methods
Definition: class.hpp:113
#define 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_SRL(a, b, c)
Definition: codegen.hpp:308
#define PATCHER_get_putfield
#define BRANCH_EQ
#define M_CZEXT(a, b)
Definition: codegen.hpp:451
s4 dseg_add_address(codegendata *cd, void *value)
Definition: dseg.cpp:542
codeinfo * code
Definition: jit.hpp:128
#define M_OR_IMM(a, b, c)
Definition: codegen.hpp:299
s4 dseg_add_unique_double(codegendata *cd, double value)
Definition: dseg.cpp:448
#define BRANCH_LABEL_5
Definition: emit-common.hpp:51
#define REG_FRESULT
Definition: md-abi.hpp:59
#define M_CMPULE_IMM(a, b, c)
Definition: codegen.hpp:291
int32_t argcount
Definition: instruction.hpp:64
#define dseg_add_functionptr(cd, value)
Definition: dseg.hpp:39
#define M_CMPEQ(a, b, c)
Definition: codegen.hpp:280
codegendata * cd
Definition: jit.hpp:129
#define M_FMULS(a, b, c)
Definition: codegen.hpp:386
void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
Definition: codegen.cpp:2010
#define BRANCH_LABEL_10
Definition: emit-common.hpp:56
#define M_CMPLE_IMM(a, b, c)
Definition: codegen.hpp:289
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
bool has_ext_instr_set
Definition: md.cpp:40
#define REG_ITMP1_XPTR
Definition: md-abi.hpp:50
#define REG_A2
Definition: md-abi.hpp:37
#define M_DSUBS(a, b, c)
Definition: codegen.hpp:385
#define M_CVTLI(b, c)
Definition: codegen.hpp:396
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
int savintreguse
Definition: reg.hpp:88
#define M_FST(a, b, disp)
Definition: codegen.hpp:357
#define M_ISUB(a, b, c)
Definition: codegen.hpp:265
patchref_t * patcher_add_patch_ref(jitdata *jd, functionptr patcher, void *ref, s4 disp)
constant_classref * ref
Definition: references.hpp:62
#define M_FLD(a, b, disp)
Definition: codegen.hpp:354
void dseg_add_target(codegendata *cd, basicblock *target)
Definition: dseg.cpp:565
u1 * methodptr
Definition: global.hpp:40
#define M_CMPULE(a, b, c)
Definition: codegen.hpp:284
#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
const s4 abi_registers_integer_saved[]
Definition: md-abi.cpp:75
#define M_OR(a, b, c)
Definition: codegen.hpp:295
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#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_CVTLF(b, c)
Definition: codegen.hpp:392
#define REG_ITMP2_XPC
Definition: md-abi.hpp:51
s4 dseg_add_s4(codegendata *cd, s4 value)
Definition: dseg.cpp:246
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
#define M_SAADDQ(a, b, c)
Definition: codegen.hpp:430
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
#define PATCHER_instanceof_interface
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define M_TRAPB
Definition: codegen.hpp:420
#define M_IZEXT(a, b)
Definition: codegen.hpp:452
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
BeginInst *& block
#define M_CMPULT(a, b, c)
Definition: codegen.hpp:285
classref_or_classinfo c
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
#define M_ISUB_IMM(a, b, c)
Definition: codegen.hpp:272
dst_operand_t dst
flags_operand_t flags
#define M_XOR_IMM(a, b, c)
Definition: codegen.hpp:300
#define M_XOR(a, b, c)
Definition: codegen.hpp:296
#define M_FCMPEQS(a, b, c)
Definition: codegen.hpp:407
#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_LST_U(a, b, disp)
Definition: codegen.hpp:442
#define BRANCH_LABEL_3
Definition: emit-common.hpp:49
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
imm_union * value
Definition: field.hpp:67
#define M_BSEXT(b, c)
Definition: codegen.hpp:247
#define M_ALD_INTERN(a, b, disp)
Definition: codegen.hpp:207
#define M_BLEZ(a, disp)
Definition: codegen.hpp:254
#define M_CMPLT_IMM(a, b, c)
Definition: codegen.hpp:288
s4 flags
Definition: class.hpp:90
#define M_CVTDL_C(b, c)
Definition: codegen.hpp:395
#define M_IMUL(a, b, c)
Definition: codegen.hpp:267
#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 M_SRL_IMM(a, b, c)
Definition: codegen.hpp:312
#define REG_FTMP2
Definition: md-abi.hpp:66
#define M_DADDS(a, b, c)
Definition: codegen.hpp:383
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
#define M_LLD_U(a, b, disp)
Definition: codegen.hpp:441
int * savfltregs
Definition: reg.hpp:73
classinfo * clazz
Definition: field.hpp:55
registerdata * rd
Definition: jit.hpp:130
#define M_ZAPNOT_IMM(a, b, c)
Definition: codegen.hpp:448
#define M_AST(a, b, disp)
Definition: codegen.hpp:350
#define M_CMPLT(a, b, c)
Definition: codegen.hpp:281
#define M_EXTWL(a, b, c)
Definition: codegen.hpp:455
s4 index
Definition: class.hpp:116
#define M_EXTQH(a, b, c)
Definition: codegen.hpp:460
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 M_MSKBL(a, b, c)
Definition: codegen.hpp:468
#define M_S8ADDQ(a, b, c)
Definition: codegen.hpp:427
#define M_INSBL(a, b, c)
Definition: codegen.hpp:461
#define PATCHER_checkcast_interface
#define M_LSUB_IMM(a, b, c)
Definition: codegen.hpp:273
int savfltreguse
Definition: reg.hpp:91
#define M_MOV(a, b)
Definition: codegen.hpp:340
bool inmemory
Definition: descriptor.hpp:151
#define M_FSUBS(a, b, c)
Definition: codegen.hpp:384
#define REG_ITMP2
Definition: md-abi.hpp:47
#define M_CMPLE(a, b, c)
Definition: codegen.hpp:282
void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
#define M_DMULS(a, b, c)
Definition: codegen.hpp:387
#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
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
methoddesc * parseddesc
Definition: method.hpp:78
#define M_SRA_IMM(a, b, c)
Definition: codegen.hpp:311
#define M_FMOVN(fa, fb)
Definition: codegen.hpp:412
#define M_CVTDFS(b, c)
Definition: codegen.hpp:398
#define REG_FTMP1
Definition: md-abi.hpp:65
#define M_FBEQZ(fa, disp)
Definition: codegen.hpp:416
#define M_AND_IMM(a, b, c)
Definition: codegen.hpp:298
#define PATCHER_invokevirtual
Definition: builtin.hpp:60
#define M_SLL_IMM(a, b, c)
Definition: codegen.hpp:310
#define M_IMUL_IMM(a, b, c)
Definition: codegen.hpp:274
methodinfo * m
Definition: jit.hpp:127
static bool IS_INMEMORY(s4 flags)
Definition: stack.hpp:51
s4 type
Definition: field.hpp:60
void codegen_emit_epilog(jitdata *jd)
Generates machine code for the method epilog.
Definition: codegen.cpp:174
#define s3
Definition: md-asm.hpp:71
#define BRANCH_LABEL_8
Definition: emit-common.hpp:54
#define M_FADDS(a, b, c)
Definition: codegen.hpp:382
s4 flags
Definition: reg.hpp:45
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
#define REG_METHODPTR
Definition: md-abi.hpp:43
#define M_CMPEQ_IMM(a, b, c)
Definition: codegen.hpp:287
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_S4ADDQ(a, b, c)
Definition: codegen.hpp:423
#define M_DST(a, b, disp)
Definition: codegen.hpp:356
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
#define REG_ZERO
Definition: md-abi.hpp:54
#define M_SSEXT(b, c)
Definition: codegen.hpp:248
void codegen_emit_prolog(jitdata *jd)
Generates machine code for the method prolog.
Definition: codegen.cpp:73
#define M_RET(a, b)
Definition: codegen.hpp:261
#define REG_FTMP3
Definition: md-abi.hpp:67
#define M_LLD(a, b, disp)
Definition: codegen.hpp:344
#define M_CVTFDS(b, c)
Definition: codegen.hpp:399
const parseddesc_t parseddesc
Definition: references.hpp:105
static void emit_fmove(codegendata *cd, int s, int d)
Generates a float-move from register s to d.
#define M_INSWL(a, b, c)
Definition: codegen.hpp:462
#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
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
#define M_FCMPLTS(a, b, c)
Definition: codegen.hpp:408
#define M_DLD(a, b, disp)
Definition: codegen.hpp:353
#define M_LMUL(a, b, c)
Definition: codegen.hpp:268
#define M_MSKWL(a, b, c)
Definition: codegen.hpp:469
uint32_t regoff
Definition: descriptor.hpp:153
s4 dseg_add_float(codegendata *cd, float value)
Definition: dseg.cpp:392
#define M_BNEZ(a, disp)
Definition: codegen.hpp:255
#define M_FDIVS(a, b, c)
Definition: codegen.hpp:388
#define OFFSET(s, el)
Definition: memory.hpp:90
branch_target_t * table
#define REG_RESULT
Definition: md-abi.hpp:33
#define M_INTMOVE(a, b)
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define REG_ITMP1
Definition: md-abi.hpp:46
static VM * get_current()
Definition: vm.hpp:99