1 /* src/vm/jit/s390/patcher.c - s390 code patching functions
3 Copyright (C) 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 #include "mm/memory.h"
32 #include "native/native.h"
34 #include "vm/jit/builtin.hpp"
36 #include "vm/field.hpp"
37 #include "vm/initialize.h"
38 #include "vm/options.h"
39 #include "vm/references.h"
40 #include "vm/resolve.h"
43 #include "vm/jit/patcher-common.hpp"
44 #include "vm/jit/s390/codegen.h"
45 #include "vm/jit/s390/md-abi.h"
48 #define PATCH_BACK_ORIGINAL_MCODE \
49 *((u2 *) pr->mpc) = (u2) pr->mcode;
54 /* patcher_patch_code **********************************************************
56 Just patches back the original machine code.
58 *******************************************************************************/
60 void patcher_patch_code(patchref_t *pr)
62 PATCH_BACK_ORIGINAL_MCODE;
66 /* patcher_get_putstatic *******************************************************
70 *******************************************************************************/
72 bool patcher_get_putstatic(patchref_t *pr)
80 /* get stuff from the stack */
82 uf = (unresolved_field *) pr->ref;
83 datap = (u1 *) pr->datap;
85 /* get the fieldinfo */
87 if (!(fi = resolve_field_eager(uf)))
90 /* check if the field's class is initialized */
92 if (!(fi->clazz->state & CLASS_INITIALIZED))
93 if (!initialize_class(fi->clazz))
96 PATCH_BACK_ORIGINAL_MCODE;
98 /* patch the field value's address */
100 *((intptr_t *) datap) = (intptr_t) fi->value;
106 /* patcher_get_putfield ********************************************************
110 *******************************************************************************/
112 bool patcher_get_putfield(patchref_t *pr)
115 unresolved_field *uf;
121 /* get stuff from the stack */
124 uf = (unresolved_field *) pr->ref;
127 /* get the fieldinfo */
129 if (!(fi = resolve_field_eager(uf)))
132 PATCH_BACK_ORIGINAL_MCODE;
134 /* If there is an operand load before, skip the load size passed in disp (see ICMD_PUTFIELD) */
138 /* patch correct offset */
140 if (fi->type == TYPE_LNG) {
141 ASSERT_VALID_DISP(fi->offset + 4);
142 /* 2 RX operations, for 2 words; each already contains a 0 or 4 offset. */
143 N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
145 N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
147 ASSERT_VALID_DISP(fi->offset);
149 N_RX_SET_DISP(ra, fi->offset);
155 /* patcher_invokestatic_special ************************************************
159 *******************************************************************************/
161 bool patcher_invokestatic_special(patchref_t *pr)
163 unresolved_method *um;
169 /* get stuff from the stack */
171 um = (unresolved_method *) pr->ref;
172 datap = (u1 *) pr->datap;
174 /* get the fieldinfo */
176 if (!(m = resolve_method_eager(um)))
179 PATCH_BACK_ORIGINAL_MCODE;
181 /* patch stubroutine */
183 *((ptrint *) datap) = (ptrint) m->stubroutine;
188 /* patcher_invokevirtual *******************************************************
192 *******************************************************************************/
194 bool patcher_invokevirtual(patchref_t *pr)
197 unresolved_method *um;
203 /* get stuff from the stack */
206 um = (unresolved_method *) pr->ref;
208 /* get the fieldinfo */
210 if (!(m = resolve_method_eager(um)))
213 /* patch back original code */
215 PATCH_BACK_ORIGINAL_MCODE;
217 /* patch vftbl index */
220 off = (s4) (OFFSET(vftbl_t, table[0]) +
221 sizeof(methodptr) * m->vftblindex);
223 ASSERT_VALID_DISP(off);
225 N_RX_SET_DISP(ra + SZ_RX, off);
231 /* patcher_invokeinterface *****************************************************
235 *******************************************************************************/
237 bool patcher_invokeinterface(patchref_t *pr)
240 unresolved_method *um;
246 /* get stuff from the stack */
249 um = (unresolved_method *) pr->ref;
251 /* get the fieldinfo */
253 if (!(m = resolve_method_eager(um)))
256 /* patch back original code */
258 PATCH_BACK_ORIGINAL_MCODE;
260 /* get interfacetable index */
262 idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
263 sizeof(methodptr) * m->clazz->index);
265 ASSERT_VALID_IMM(idx);
267 /* get method offset */
270 (s4) (sizeof(methodptr) * (m - m->clazz->methods));
272 ASSERT_VALID_DISP(off);
276 N_RI_SET_IMM(ra + SZ_L, idx);
277 N_RX_SET_DISP(ra + SZ_L + SZ_LHI + SZ_L, off);
283 /* patcher_resolve_classref_to_flags *******************************************
285 CHECKCAST/INSTANCEOF:
287 <patched call position>
289 *******************************************************************************/
291 bool patcher_resolve_classref_to_flags(patchref_t *pr)
293 constant_classref *cr;
299 /* get stuff from the stack */
301 cr = (constant_classref *) pr->ref;
302 datap = (u1 *) pr->datap;
304 /* get the fieldinfo */
306 if (!(c = resolve_classref_eager(cr)))
309 PATCH_BACK_ORIGINAL_MCODE;
311 /* patch class flags */
313 *((s4 *) datap) = (s4) c->flags;
318 /* patcher_resolve_classref_to_classinfo ***************************************
324 *******************************************************************************/
326 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
328 constant_classref *cr;
334 /* get stuff from the stack */
336 cr = (constant_classref *) pr->ref;
337 datap = (u1 *) pr->datap;
339 /* get the classinfo */
341 if (!(c = resolve_classref_eager(cr)))
344 PATCH_BACK_ORIGINAL_MCODE;
346 /* patch the classinfo pointer */
348 *((ptrint *) datap) = (ptrint) c;
353 /* patcher_resolve_classref_to_vftbl *******************************************
358 *******************************************************************************/
360 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
362 constant_classref *cr;
368 /* get stuff from the stack */
370 cr = (constant_classref *) pr->ref;
371 datap = (u1 *) pr->datap;
373 /* get the fieldinfo */
375 if (!(c = resolve_classref_eager(cr)))
378 PATCH_BACK_ORIGINAL_MCODE;
380 /* patch super class' vftbl */
382 *((ptrint *) datap) = (ptrint) c->vftbl;
387 /* patcher_checkcast_instanceof_interface **************************************
391 *******************************************************************************/
393 bool patcher_checkcast_instanceof_interface(patchref_t *pr)
397 constant_classref *cr;
402 /* get stuff from the stack */
405 cr = (constant_classref *) pr->ref;
407 /* get the fieldinfo */
409 if (!(c = resolve_classref_eager(cr)))
412 /* patch back original code */
414 PATCH_BACK_ORIGINAL_MCODE;
416 /* patch super class index */
418 /* From here, split your editor and open codegen.c */
420 switch (N_RX_GET_REG(ra)) {
422 /* First M_ALD is into ITMP1 */
423 /* INSTANCEOF code */
425 N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index);
427 ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC,
428 (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
433 /* First M_ALD is into ITMP2 */
436 N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index);
438 ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC + SZ_ILL,
439 (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
453 * These are local overrides for various environment variables in Emacs.
454 * Please do not remove this and leave it at the end of the file, where
455 * Emacs will automagically detect them.
456 * ---------------------------------------------------------------------
459 * indent-tabs-mode: t
463 * vim:noexpandtab:sw=4:ts=4: