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