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