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