8 #include "vm/jit/sparc64/md-abi.h"
10 #include "vm/exceptions.h"
11 #include "vm/stringlocal.h"
12 #include "vm/jit/asmpart.h"
13 #include "vm/jit/stacktrace.h"
15 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
16 #include "vm/options.h" /* XXX debug */
17 #include "vm/jit/disass.h" /* XXX debug */
21 /* md_init *********************************************************************
23 Do some machine dependent initialization.
25 *******************************************************************************/
33 /* md_stacktrace_get_returnaddress *********************************************
35 Returns the return address of the current stackframe, specified by
36 the passed stack pointer and the stack frame size.
38 *******************************************************************************/
40 u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
43 /* flush register windows to the stack */
46 /* the return address resides in register i7, the last register in the
47 * 16-extended-word save area
49 ra = *((u1 **) (sp + 120));
51 /* ra is the address of the call instr, advance to the real return address */
58 /* md_codegen_get_pv_from_pc ***************************************************
60 This reconstructs and returns the PV of a method given a return address
61 pointer. (basically, same was as the generated code following the jump does)
66 277afffe ldah pv,-2(ra)
67 237ba61c lda pv,-23012(pv)
69 *******************************************************************************/
71 u1 *md_codegen_get_pv_from_pc(u1 *ra)
79 /* get first instruction word after jump */
83 /* check if we have 2 instructions (ldah, lda) */
85 if ((mcode >> 16) == 0x277a) {
86 /* get displacement of first instruction (ldah) */
88 offset = (s4) (mcode << 16);
91 /* get displacement of second instruction (lda) */
93 mcode = *((u4 *) (ra + 1 * 4));
95 assert((mcode >> 16) == 0x237b);
97 offset = (s2) (mcode & 0x0000ffff);
101 /* get displacement of first instruction (lda) */
103 assert((mcode >> 16) == 0x237a);
105 offset = (s2) (mcode & 0x0000ffff);
112 /* md_get_method_patch_address *************************************************
114 Gets the patch address of the currently compiled method. The offset
115 is extracted from the load instruction(s) before the jump and added
116 to the right base address (PV or REG_METHODPTR).
118 INVOKESTATIC/SPECIAL:
120 dfdeffb8 ld s8,-72(s8)
134 df39ff90 ld t9,-112(t9)
135 df3e0018 ld s8,24(t9)
139 *******************************************************************************/
141 u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
147 /* go back to the actual load instruction (3 instructions on MIPS) */
151 /* get first instruction word on current PC */
153 mcode = *((u4 *) ra);
155 /* check if we have 2 instructions (lui) */
157 if ((mcode >> 16) == 0x3c19) {
158 /* XXX write a regression for this */
161 /* get displacement of first instruction (lui) */
163 offset = (s4) (mcode << 16);
165 /* get displacement of second instruction (daddiu) */
167 mcode = *((u4 *) (ra + 1 * 4));
169 assert((mcode >> 16) != 0x6739);
171 offset += (s2) (mcode & 0x0000ffff);
174 /* get first instruction (ld) */
176 mcode = *((u4 *) ra);
178 /* get the offset from the instruction */
180 offset = (s2) (mcode & 0x0000ffff);
182 /* check for call with REG_METHODPTR: ld s8,x(t9) */
184 #if SIZEOF_VOID_P == 8
185 if ((mcode >> 16) == 0xdf3e) {
187 if ((mcode >> 16) == 0x8f3e) {
189 /* in this case we use the passed method pointer */
194 /* in the normal case we check for a `ld s8,x(s8)' instruction */
196 #if SIZEOF_VOID_P == 8
197 assert((mcode >> 16) == 0xdfde);
199 assert((mcode >> 16) == 0x8fde);
202 /* and get the final data segment address */
204 pa = sfi->pv + offset;
212 /* md_cacheflush ***************************************************************
214 Calls the system's function to flush the instruction and data
217 *******************************************************************************/
219 void md_cacheflush(u1 *addr, s4 nbytes)
225 /* md_icacheflush **************************************************************
227 Calls the system's function to flush the instruction cache.
229 *******************************************************************************/
231 void md_icacheflush(u1 *addr, s4 nbytes)
237 /* md_patch_replacement_point **************************************************
239 Patch the given replacement point.
241 *******************************************************************************/
243 void md_patch_replacement_point(rplpoint *rp)
247 /* save the current machine code */
248 mcode = *(u4*)rp->pc;
250 /* write the new machine code */
251 *(u4*)(rp->pc) = (u4) rp->mcode;
253 /* store saved mcode */
256 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
264 /* flush instruction cache */
265 /* md_icacheflush(rp->pc,4); */
269 * These are local overrides for various environment variables in Emacs.
270 * Please do not remove this and leave it at the end of the file, where
271 * Emacs will automagically detect them.
272 * ---------------------------------------------------------------------
275 * indent-tabs-mode: t
279 * vim:noexpandtab:sw=4:ts=4: