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