* Implemented idiv/irem, ldiv/lrem, aastore, arraycheckcast inline
[cacao.git] / src / vm / jit / mips / patcher.c
1 /* src/vm/jit/mips/patcher.c - MIPS code patching functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 3002 2005-07-12 16:02:45Z twisti $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/jit/mips/types.h"
38
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
42 #include "vm/field.h"
43 #include "vm/initialize.h"
44 #include "vm/options.h"
45 #include "vm/references.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/helper.h"
48 #include "vm/jit/patcher.h"
49
50
51 /* patcher_get_putstatic *******************************************************
52
53    Machine code:
54
55    <patched call position>
56    dfc1ffb8    ld       at,-72(s8)
57    fc250000    sd       a1,0(at)
58
59 *******************************************************************************/
60
61 bool patcher_get_putstatic(u1 *sp)
62 {
63         u1                *ra;
64         java_objectheader *o;
65         u8                 mcode;
66         unresolved_field  *uf;
67         u1                *pv;
68         fieldinfo         *fi;
69         s2                 offset;
70
71         /* get stuff from the stack */
72
73         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
74         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
75         mcode =                       *((u8 *)     (sp + 2 * 8));
76         uf    = (unresolved_field *)  *((ptrint *) (sp + 1 * 8));
77         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
78
79         /* calculate and set the new return address */
80
81         ra = ra - 2 * 4;
82         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
83
84         PATCHER_MONITORENTER;
85
86         /* get the fieldinfo */
87
88         if (!(fi = helper_resolve_fieldinfo(uf))) {
89                 PATCHER_MONITOREXIT;
90
91                 return false;
92         }
93
94         /* check if the field's class is initialized */
95
96         if (!fi->class->initialized)
97                 if (!initialize_class(fi->class))
98                         return false;
99
100         /* patch back original code */
101
102         *((u4 *) (ra + 0 * 4)) = mcode;
103         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
104
105         /* if we show disassembly, we have to skip the nop's */
106
107         if (opt_showdisassemble)
108                 ra = ra + 2 * 4;
109
110         /* get the offset from machine instruction */
111
112         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
113
114         /* patch the field value's address */
115
116         *((ptrint *) (pv + offset)) = (ptrint) &(fi->value);
117
118         /* synchronize instruction cache */
119
120         docacheflush(ra, 2 * 4);
121
122         PATCHER_MARK_PATCHED_MONITOREXIT;
123
124         return true;
125 }
126
127
128 /* patcher_get_putfield ********************************************************
129
130    Machine code:
131
132    <patched call position>
133    8ee90020    lw       a5,32(s7)
134
135 *******************************************************************************/
136
137 bool patcher_get_putfield(u1 *sp)
138 {
139         u1                *ra;
140         java_objectheader *o;
141         u8                 mcode;
142         unresolved_field  *uf;
143         fieldinfo         *fi;
144
145         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
146         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
147         mcode =                       *((u8 *)     (sp + 2 * 8));
148         uf    = (unresolved_field *)  *((ptrint *) (sp + 1 * 8));
149
150         /* calculate and set the new return address */
151
152         ra = ra - 2 * 4;
153         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
154
155         PATCHER_MONITORENTER;
156
157         /* get the fieldinfo */
158
159         if (!(fi = helper_resolve_fieldinfo(uf))) {
160                 PATCHER_MONITOREXIT;
161
162                 return false;
163         }
164
165         /* patch back original code */
166
167         *((u4 *) (ra + 0 * 4)) = mcode;
168         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
169
170         /* if we show disassembly, we have to skip the nop's */
171
172         if (opt_showdisassemble)
173                 ra = ra + 2 * 4;
174
175         /* patch the field's offset */
176
177         *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
178
179         /* synchronize instruction cache */
180
181         docacheflush(ra, 2 * 4);
182
183         PATCHER_MARK_PATCHED_MONITOREXIT;
184
185         return true;
186 }
187
188
189 /* patcher_builtin_new *********************************************************
190
191    Machine code:
192
193    dfc4ff98    ld       a0,-104(s8)
194    <patched call postition>
195    dfd9ff90    ld       t9,-112(s8)
196    0320f809    jalr     t9
197    00000000    nop
198
199 *******************************************************************************/
200
201 bool patcher_builtin_new(u1 *sp)
202 {
203         u1                *ra;
204         java_objectheader *o;
205         u8                 mcode;
206         constant_classref *cr;
207         u1                *pv;
208         classinfo         *c;
209         s2                 offset;
210
211         /* get stuff from the stack */
212
213         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
214         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
215         mcode =                       *((u8 *)     (sp + 2 * 8));
216         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
217         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
218
219         /* calculate and set the new return address */
220
221         ra = ra - (4 + 2 * 4);
222         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
223
224         PATCHER_MONITORENTER;
225
226         /* get the classinfo */
227
228         if (!(c = helper_resolve_classinfo(cr))) {
229                 PATCHER_MONITOREXIT;
230
231                 return false;
232         }
233
234         /* patch back original code */
235
236         *((u4 *) (ra + 1 * 4)) = mcode;
237         *((u4 *) (ra + 2 * 4)) = mcode >> 32;
238
239         /* get the offset from machine instruction */
240
241         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
242
243         /* patch the classinfo pointer */
244
245         *((ptrint *) (pv + offset)) = (ptrint) c;
246
247         /* if we show disassembly, we have to skip the nop's */
248
249         if (opt_showdisassemble)
250                 ra = ra + 2 * 4;
251
252         /* get the offset from machine instruction */
253
254         offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
255
256         /* patch new function address */
257
258         *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_new;
259
260         /* synchronize instruction cache */
261
262         docacheflush(ra + 4, 2 * 4);
263
264         PATCHER_MARK_PATCHED_MONITOREXIT;
265
266         return true;
267 }
268
269
270 /* patcher_builtin_newarray ****************************************************
271
272    Machine code:
273
274    dfc5ffa0    ld       a1,-96(s8)
275    <patched call position>
276    dfd9ff98    ld       t9,-104(s8)
277    0320f809    jalr     t9
278    00000000    nop
279
280 *******************************************************************************/
281
282 bool patcher_builtin_newarray(u1 *sp)
283 {
284         u1                *ra;
285         java_objectheader *o;
286         u8                 mcode;
287         constant_classref *cr;
288         u1                *pv;
289         classinfo         *c;
290         s2                 offset;
291
292         /* get stuff from the stack */
293
294         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
295         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
296         mcode =                       *((u8 *)     (sp + 2 * 8));
297         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
298         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
299
300         /* calculate and set the new return address */
301
302         ra = ra - (4 + 2 * 4);
303         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
304
305         PATCHER_MONITORENTER;
306
307         /* get the classinfo */
308
309         if (!(c = helper_resolve_classinfo(cr))) {
310                 PATCHER_MONITOREXIT;
311
312                 return false;
313         }
314
315         /* patch back original code */
316
317         *((u4 *) (ra + 1 * 4)) = mcode;
318         *((u4 *) (ra + 2 * 4)) = mcode >> 32;
319
320         /* get the offset from machine instruction */
321
322         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
323
324         /* patch the class' vftbl pointer */
325
326         *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
327
328         /* if we show disassembly, we have to skip the nop */
329
330         if (opt_showdisassemble)
331                 ra = ra + 2 * 4;
332
333         /* get the offset from machine instruction */
334
335         offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
336
337         /* patch new function address */
338
339         *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_newarray;
340
341         /* synchronize instruction cache */
342
343         docacheflush(ra + 4, 2 * 4);
344
345         PATCHER_MARK_PATCHED_MONITOREXIT;
346
347         return true;
348 }
349
350
351 /* patcher_builtin_multianewarray **********************************************
352
353    Machine code:
354
355    <patched call position>
356    24040002    addiu    a0,zero,2
357    dfc5ff90    ld       a1,-112(s8)
358    03a03025    move     a2,sp
359    dfd9ff88    ld       t9,-120(s8)
360    0320f809    jalr     t9
361    00000000    nop
362
363 *******************************************************************************/
364
365 bool patcher_builtin_multianewarray(u1 *sp)
366 {
367         u1                *ra;
368         java_objectheader *o;
369         u8                 mcode;
370         constant_classref *cr;
371         u1                *pv;
372         classinfo         *c;
373         s2                 offset;
374
375         /* get stuff from the stack */
376
377         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
378         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
379         mcode =                       *((u8 *)     (sp + 2 * 8));
380         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
381         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
382
383         /* calculate and set the new return address */
384
385         ra = ra - 2 * 4;
386         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
387
388         PATCHER_MONITORENTER;
389
390         /* get the classinfo */
391
392         if (!(c = helper_resolve_classinfo(cr))) {
393                 PATCHER_MONITOREXIT;
394
395                 return false;
396         }
397
398         /* patch back original code */
399
400         *((u4 *) (ra + 0 * 4)) = mcode;
401         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
402
403         /* if we show disassembly, we have to skip the nop's */
404
405         if (opt_showdisassemble)
406                 ra = ra + 2 * 4;
407
408         /* get the offset from machine instruction */
409
410         offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff);
411
412         /* patch the class' vftbl pointer */
413
414         *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
415
416         /* synchronize instruction cache */
417
418         docacheflush(ra, 2 * 4);
419
420         PATCHER_MARK_PATCHED_MONITOREXIT;
421
422         return true;
423 }
424
425
426 /* patcher_builtin_arraycheckcast **********************************************
427
428    Machine code:
429
430    <patched call position>
431    dfc5ffc0    ld       a1,-64(s8)
432    dfd9ffb8    ld       t9,-72(s8)
433    0320f809    jalr     t9
434    00000000    nop
435
436 *******************************************************************************/
437
438 bool patcher_builtin_arraycheckcast(u1 *sp)
439 {
440         u1                *ra;
441         java_objectheader *o;
442         u8                 mcode;
443         constant_classref *cr;
444         u1                *pv;
445         classinfo         *c;
446         s2                 offset;
447
448         /* get stuff from the stack */
449
450         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
451         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
452         mcode =                       *((u8 *)     (sp + 2 * 8));
453         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
454         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
455
456         /* calculate and set the new return address */
457
458         ra = ra - 2 * 4;
459         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
460
461         PATCHER_MONITORENTER;
462
463         /* get the classinfo */
464
465         if (!(c = helper_resolve_classinfo(cr))) {
466                 PATCHER_MONITOREXIT;
467
468                 return false;
469         }
470
471         /* patch back original code */
472
473         *((u4 *) (ra + 0 * 4)) = mcode;
474         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
475
476         /* if we show disassembly, we have to skip the nop's */
477
478         if (opt_showdisassemble)
479                 ra = ra + 2 * 4;
480
481         /* get the offset from machine instruction */
482
483         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
484
485         /* patch the class' vftbl pointer */
486
487         *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
488
489         /* get the offset from machine instruction */
490
491         offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
492
493         /* patch new function address */
494
495         *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arraycheckcast;
496
497         /* synchronize instruction cache */
498
499         docacheflush(ra, 2 * 4);
500
501         PATCHER_MARK_PATCHED_MONITOREXIT;
502
503         return true;
504 }
505
506
507 /* patcher_builtin_arrayinstanceof *********************************************
508
509    Machine code:
510
511    dfc5fe98    ld       a1,-360(s8)
512    <patched call position>
513    dfd9fe90    ld       t9,-368(s8)
514    0320f809    jalr     t9
515    00000000    nop
516
517 *******************************************************************************/
518
519 bool patcher_builtin_arrayinstanceof(u1 *sp)
520 {
521         u1                *ra;
522         java_objectheader *o;
523         u8                 mcode;
524         constant_classref *cr;
525         u1                *pv;
526         classinfo         *c;
527         s4                 offset;
528
529         /* get stuff from the stack */
530
531         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
532         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
533         mcode =                       *((u8 *)     (sp + 2 * 8));
534         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
535         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
536
537         /* calculate and set the new return address */
538
539         ra = ra - 3 * 4;
540         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
541
542         PATCHER_MONITORENTER;
543
544         /* get the classinfo */
545
546         if (!(c = helper_resolve_classinfo(cr))) {
547                 PATCHER_MONITOREXIT;
548
549                 return false;
550         }
551
552         /* patch back original code */
553
554         *((u4 *) (ra + 1 * 4)) = mcode;
555         *((u4 *) (ra + 2 * 4)) = mcode >> 32;
556
557         /* get the offset from machine instruction */
558
559         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
560
561         /* patch the class' vftbl pointer */
562         
563         *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
564
565         /* if we show disassembly, we have to skip the nop's */
566
567         if (opt_showdisassemble)
568                 ra = ra + 2 * 4;
569
570         /* get the offset from machine instruction */
571
572         offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
573
574         /* patch new function address */
575
576         *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arrayinstanceof;
577
578         /* synchronize instruction cache */
579
580         docacheflush(ra + 4, 2 * 4);
581
582         PATCHER_MARK_PATCHED_MONITOREXIT;
583
584         return true;
585 }
586
587
588 /* patcher_invokestatic_special ************************************************
589
590    Machine code:
591
592    <patched call position>
593    dfdeffc0    ld       s8,-64(s8)
594    03c0f809    jalr     s8
595    00000000    nop
596
597 ******************************************************************************/
598
599 bool patcher_invokestatic_special(u1 *sp)
600 {
601         u1                *ra;
602         java_objectheader *o;
603         u8                 mcode;
604         unresolved_method *um;
605         u1                *pv;
606         methodinfo        *m;
607         s4                 offset;
608
609         /* get stuff from the stack */
610
611         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
612         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
613         mcode =                       *((u8 *)     (sp + 2 * 8));
614         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
615         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
616
617         /* calculate and set the new return address */
618
619         ra = ra - 2 * 4;
620         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
621
622         PATCHER_MONITORENTER;
623
624         /* get the fieldinfo */
625
626         if (!(m = helper_resolve_methodinfo(um))) {
627                 PATCHER_MONITOREXIT;
628
629                 return false;
630         }
631
632         /* patch back original code */
633
634         *((u4 *) (ra + 0 * 4)) = mcode;
635         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
636
637         /* if we show disassembly, we have to skip the nop's */
638
639         if (opt_showdisassemble)
640                 ra = ra + 2 * 4;
641
642         /* get the offset from machine instruction */
643
644         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
645
646         /* patch stubroutine */
647
648         *((ptrint *) (pv + offset)) = (ptrint) m->stubroutine;
649
650         /* synchronize instruction cache */
651
652         docacheflush(ra, 2 * 4);
653
654         PATCHER_MARK_PATCHED_MONITOREXIT;
655
656         return true;
657 }
658
659
660 /* patcher_invokevirtual *******************************************************
661
662    Machine code:
663
664    <patched call position>
665    dc990000    ld       t9,0(a0)
666    df3e0040    ld       s8,64(t9)
667    03c0f809    jalr     s8
668    00000000    nop
669
670 *******************************************************************************/
671
672 bool patcher_invokevirtual(u1 *sp)
673 {
674         u1                *ra;
675         java_objectheader *o;
676         u8                 mcode;
677         unresolved_method *um;
678         methodinfo        *m;
679
680         /* get stuff from the stack */
681
682         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
683         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
684         mcode =                       *((u8 *)     (sp + 2 * 8));
685         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
686
687         /* calculate and set the new return address */
688
689         ra = ra - 2 * 4;
690         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
691
692         PATCHER_MONITORENTER;
693
694         /* get the fieldinfo */
695
696         if (!(m = helper_resolve_methodinfo(um))) {
697                 PATCHER_MONITOREXIT;
698
699                 return false;
700         }
701
702         /* patch back original code */
703
704         *((u4 *) (ra + 0 * 4)) = mcode;
705         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
706
707         /* if we show disassembly, we have to skip the nop's */
708
709         if (opt_showdisassemble)
710                 ra = ra + 2 * 4;
711
712         /* patch vftbl index */
713
714         *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
715                                                                          sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
716
717         /* synchronize instruction cache */
718
719         docacheflush(ra, 2 * 4);
720
721         PATCHER_MARK_PATCHED_MONITOREXIT;
722
723         return true;
724 }
725
726
727 /* patcher_invokeinterface *****************************************************
728
729    Machine code:
730
731    <patched call position>
732    dc990000    ld       t9,0(a0)
733    df39ffa0    ld       t9,-96(t9)
734    df3e0018    ld       s8,24(t9)
735    03c0f809    jalr     s8
736    00000000    nop
737
738 *******************************************************************************/
739
740 bool patcher_invokeinterface(u1 *sp)
741 {
742         u1                *ra;
743         java_objectheader *o;
744         u8                 mcode;
745         unresolved_method *um;
746         methodinfo        *m;
747
748         /* get stuff from the stack */
749
750         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
751         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
752         mcode =                       *((u8 *)     (sp + 2 * 8));
753         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
754
755         /* calculate and set the new return address */
756
757         ra = ra - 2 * 4;
758         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
759
760         PATCHER_MONITORENTER;
761
762         /* get the fieldinfo */
763
764         if (!(m = helper_resolve_methodinfo(um))) {
765                 PATCHER_MONITOREXIT;
766
767                 return false;
768         }
769
770         /* patch back original code */
771
772         *((u4 *) (ra + 0 * 4)) = mcode;
773         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
774
775         /* if we show disassembly, we have to skip the nop's */
776
777         if (opt_showdisassemble)
778                 ra = ra + 2 * 4;
779
780         /* patch interfacetable index */
781
782         *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
783                                                                          sizeof(methodptr*) * m->class->index) & 0x0000ffff);
784
785         /* patch method offset */
786
787         *((s4 *) (ra + 2 * 4)) |=
788                 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
789
790         /* synchronize instruction cache */
791
792         docacheflush(ra, 2 * 4);
793
794         PATCHER_MARK_PATCHED_MONITOREXIT;
795
796         return true;
797 }
798
799
800 /* patcher_checkcast_instanceof_flags ******************************************
801
802    Machine code:
803
804    <patched call position>
805    8fc3ff24    lw       v1,-220(s8)
806    30630200    andi     v1,v1,512
807    1060000d    beq      v1,zero,0x000000001051824c
808    00000000    nop
809
810 *******************************************************************************/
811
812 bool patcher_checkcast_instanceof_flags(u1 *sp)
813 {
814         u1                *ra;
815         java_objectheader *o;
816         u8                 mcode;
817         constant_classref *cr;
818         u1                *pv;
819         classinfo         *c;
820         s2                 offset;
821
822         /* get stuff from the stack */
823
824         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
825         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
826         mcode =                       *((u8 *)     (sp + 2 * 8));
827         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
828         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
829
830         /* calculate and set the new return address */
831
832         ra = ra - 2 * 4;
833         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
834
835         PATCHER_MONITORENTER;
836
837         /* get the fieldinfo */
838
839         if (!(c = helper_resolve_classinfo(cr))) {
840                 PATCHER_MONITOREXIT;
841
842                 return false;
843         }
844
845         /* patch back original code */
846
847         *((u4 *) (ra + 0 * 4)) = mcode;
848         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
849
850         /* if we show disassembly, we have to skip the nop's */
851
852         if (opt_showdisassemble)
853                 ra = ra + 2 * 4;
854
855         /* get the offset from machine instruction */
856
857         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
858
859         /* patch class flags */
860
861         *((s4 *) (pv + offset)) = (s4) c->flags;
862
863         /* synchronize instruction cache */
864
865         docacheflush(ra, 2 * 4);
866
867         PATCHER_MARK_PATCHED_MONITOREXIT;
868
869         return true;
870 }
871
872
873 /* patcher_checkcast_instanceof_interface **************************************
874
875    Machine code:
876
877    <patched call position>
878    dd030000    ld       v1,0(a4)
879    8c79001c    lw       t9,28(v1)
880    27390000    addiu    t9,t9,0
881    1b200082    blez     t9,zero,0x000000001051843c
882    00000000    nop
883    dc790000    ld       t9,0(v1)
884
885 *******************************************************************************/
886
887 bool patcher_checkcast_instanceof_interface(u1 *sp)
888 {
889         u1                *ra;
890         java_objectheader *o;
891         u8                 mcode;
892         constant_classref *cr;
893         classinfo         *c;
894
895         /* get stuff from the stack */
896
897         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
898         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
899         mcode =                       *((u8 *)     (sp + 2 * 8));
900         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
901
902         /* calculate and set the new return address */
903
904         ra = ra - 2 * 4;
905         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
906
907         PATCHER_MONITORENTER;
908
909         /* get the fieldinfo */
910
911         if (!(c = helper_resolve_classinfo(cr))) {
912                 PATCHER_MONITOREXIT;
913
914                 return false;
915         }
916
917         /* patch back original code */
918
919         *((u4 *) (ra + 0 * 4)) = mcode;
920         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
921
922         /* if we show disassembly, we have to skip the nop's */
923
924         if (opt_showdisassemble)
925                 ra = ra + 2 * 4;
926
927         /* patch super class index */
928
929         *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
930
931         *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
932                                                                          c->index * sizeof(methodptr*)) & 0x0000ffff);
933
934         /* synchronize instruction cache */
935
936         docacheflush(ra, 6 * 4);
937
938         PATCHER_MARK_PATCHED_MONITOREXIT;
939
940         return true;
941 }
942
943
944 /* patcher_checkcast_instanceof_class ******************************************
945
946    Machine code:
947
948    <patched call position>
949    dd030000    ld       v1,0(a4)
950    dfd9ff18    ld       t9,-232(s8)
951
952 *******************************************************************************/
953
954 bool patcher_checkcast_instanceof_class(u1 *sp)
955 {
956         u1                *ra;
957         java_objectheader *o;
958         u8                 mcode;
959         constant_classref *cr;
960         u1                *pv;
961         classinfo         *c;
962         s2                 offset;
963
964         /* get stuff from the stack */
965
966         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
967         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
968         mcode =                       *((u8 *)     (sp + 2 * 8));
969         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
970         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
971
972         /* calculate and set the new return address */
973
974         ra = ra - 2 * 4;
975         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
976
977         PATCHER_MONITORENTER;
978
979         /* get the fieldinfo */
980
981         if (!(c = helper_resolve_classinfo(cr))) {
982                 PATCHER_MONITOREXIT;
983
984                 return false;
985         }
986
987         /* patch back original code */
988
989         *((u4 *) (ra + 0 * 4)) = mcode;
990         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
991
992         /* if we show disassembly, we have to skip the nop's */
993
994         if (opt_showdisassemble)
995                 ra = ra + 2 * 4;
996
997         /* get the offset from machine instruction */
998
999         offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff);
1000
1001         /* patch super class' vftbl */
1002
1003         *((ptrint *) (pv + offset)) = (ptrint) c->vftbl;
1004
1005         /* synchronize instruction cache */
1006
1007         docacheflush(ra, 2 * 4);
1008
1009         PATCHER_MARK_PATCHED_MONITOREXIT;
1010
1011         return true;
1012 }
1013
1014
1015 /* patcher_clinit **************************************************************
1016
1017    XXX
1018
1019 *******************************************************************************/
1020
1021 bool patcher_clinit(u1 *sp)
1022 {
1023         u1                *ra;
1024         java_objectheader *o;
1025         u8                 mcode;
1026         classinfo         *c;
1027
1028         /* get stuff from the stack */
1029
1030         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
1031         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1032         mcode =                       *((u8 *)     (sp + 2 * 8));
1033         c     = (classinfo *)         *((ptrint *) (sp + 1 * 8));
1034
1035         /* calculate and set the new return address */
1036
1037         ra = ra - 2 * 4;
1038         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1039
1040         PATCHER_MONITORENTER;
1041
1042         /* check if the class is initialized */
1043
1044         if (!c->initialized) {
1045                 if (!initialize_class(c)) {
1046                         PATCHER_MONITOREXIT;
1047
1048                         return false;
1049                 }
1050         }
1051
1052         /* patch back original code */
1053
1054         *((u4 *) (ra + 0)) = mcode;
1055         *((u4 *) (ra + 4)) = mcode >> 32;
1056
1057         /* synchronize instruction cache */
1058
1059         docacheflush(ra, 2 * 4);
1060
1061         PATCHER_MARK_PATCHED_MONITOREXIT;
1062
1063         return true;
1064 }
1065
1066
1067 /* patcher_resolve_native ******************************************************
1068
1069    XXX
1070
1071 *******************************************************************************/
1072
1073 #if !defined(ENABLE_STATICVM)
1074 bool patcher_resolve_native(u1 *sp)
1075 {
1076         u1                *ra;
1077         java_objectheader *o;
1078         u8                 mcode;
1079         methodinfo        *m;
1080         u1                *pv;
1081         functionptr        f;
1082         s2                 offset;
1083
1084         /* get stuff from the stack */
1085
1086         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
1087         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1088         mcode =                       *((u8 *)     (sp + 2 * 8));
1089         m     = (methodinfo *)        *((ptrint *) (sp + 1 * 8));
1090         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
1091
1092         /* calculate and set the new return address */
1093
1094         ra = ra - 2 * 4;
1095         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1096
1097         PATCHER_MONITORENTER;
1098
1099         /* resolve native function */
1100
1101         if (!(f = native_resolve_function(m))) {
1102                 PATCHER_MONITOREXIT;
1103
1104                 return false;
1105         }
1106
1107         /* patch back original code */
1108
1109         *((u4 *) (ra + 0 * 4)) = mcode;
1110         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1111
1112         /* if we show disassembly, we have to skip the nop's */
1113
1114         if (opt_showdisassemble)
1115                 ra = ra + 2 * 4;
1116
1117         /* get the offset from machine instruction */
1118
1119         offset = (s2) (*((u4 *) ra) & 0x0000ffff);
1120
1121         /* patch native function pointer */
1122
1123         *((ptrint *) (pv + offset)) = (ptrint) f;
1124
1125         /* synchronize instruction cache */
1126
1127         docacheflush(ra, 2 * 4);
1128
1129         PATCHER_MARK_PATCHED_MONITOREXIT;
1130
1131         return true;
1132 }
1133 #endif /* !defined(ENABLE_STATICVM) */
1134
1135
1136 /*
1137  * These are local overrides for various environment variables in Emacs.
1138  * Please do not remove this and leave it at the end of the file, where
1139  * Emacs will automagically detect them.
1140  * ---------------------------------------------------------------------
1141  * Local variables:
1142  * mode: c
1143  * indent-tabs-mode: t
1144  * c-basic-offset: 4
1145  * tab-width: 4
1146  * End:
1147  * vim:noexpandtab:sw=4:ts=4:
1148  */