CACAO
md.hpp
Go to the documentation of this file.
1 /* src/vm/jit/sparc64/md.cpp - machine dependent SPARC64 functions
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
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.
12 
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.
17 
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
21  02110-1301, USA.
22 
23 */
24 
25 
26 #ifndef VM_JIT_SPARC64_MD_HPP_
27 #define VM_JIT_SPARC64_MD_HPP_ 1
28 
29 #include "config.h"
30 
31 #include <cassert>
32 #include <stdint.h>
33 
34 #include "vm/types.hpp"
35 #include "vm/jit/code.hpp"
37 
38 
39 /**
40  * Returns the size (in bytes) of the current stackframe, specified by
41  * the passed codeinfo structure.
42  */
43 inline static int32_t md_stacktrace_get_framesize(codeinfo* code)
44 {
45  // Check for the asm_vm_call_method special case.
46  if (code == NULL)
47  return 0;
48 
49  // On SPARC we use 8-byte stackslots.
50 #error Verify the below line, then remove this error!
51  return code->stackframesize * 8;
52 }
53 
54 
55 /* md_stacktrace_get_returnaddress *********************************************
56 
57  Returns the return address of the current stackframe, specified by
58  the passed stack pointer and the stack frame size.
59 
60 *******************************************************************************/
61 
62 inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
63 {
64  void *ra;
65 
66  /* flush register windows to the stack */
67  __asm__ ("flushw");
68 
69  /* the return address resides in register i7, the last register in the
70  * 16-extended-word save area
71  */
72  ra = *((void **) (((uintptr_t) sp) + 120 + BIAS));
73 
74  /* NOTE: on SPARC ra is the address of the call instruction */
75 
76  return ra;
77 }
78 
79 inline static void *md_get_framepointer(void *sp)
80 {
81  void *fp;
82 
83  /* flush register windows to the stack */
84  __asm__ ("flushw");
85 
86  fp = *((void **) (((uintptr_t) sp) + 112 + BIAS));
87 
88  return fp;
89 }
90 
91 inline static void *md_get_pv_from_stackframe(void *sp)
92 {
93  void *pv;
94 
95  /* flush register windows to the stack */
96  __asm__ ("flushw");
97 
98  pv = *((void **) (((uintptr_t) sp) + 104 + BIAS));
99 
100  return pv;
101 }
102 
103 
104 /* md_codegen_get_pv_from_pc ***************************************************
105 
106  This reconstructs and returns the PV of a method given a return address
107  pointer. (basically, same was as the generated code following the jump does)
108 
109  Machine code:
110 
111  6b5b4000 jmpl (pv)
112  10000000 nop
113  277afffe ldah pv,-2(ra)
114  237ba61c lda pv,-23012(pv)
115 
116 *******************************************************************************/
117 
118 /* TODO Move these macros into the code generator. */
119 
120 /* shift away 13-bit immediate, mask rd and rs1 */
121 #define SHIFT_AND_MASK(instr) \
122  ((instr >> 13) & 0x60fc1)
123 
124 /* NOP is defined as a SETHI instruction with rd and imm. set to zero */
125 /* therefore we check if the 22-bit immediate is zero */
126 #define IS_SETHI(instr) \
127  (((instr & 0xc1c00000) == 0x01000000) \
128  && ((instr & 0x3fffff) != 0x0))
129 
130 inline s2 decode_13bit_imm(u4 instr) {
131  s2 imm;
132 
133  /* mask everything else in the instruction */
134  imm = instr & 0x00001fff;
135 
136  /* sign extend 13-bit to 16-bit */
137  imm <<= 3;
138  imm >>= 3;
139 
140  return imm;
141 }
142 
143 inline static void *md_codegen_get_pv_from_pc(void *ra)
144 {
145  uint8_t *pv;
146  u8 mcode;
147  s4 offset;
148 
149  pv = ra;
150 
151  /* get the instruction word after jump and nop */
152  mcode = *((u4 *) (ra+8) );
153 
154  /* check if we have a sethi insruction */
155  if (IS_SETHI(mcode)) {
156  s4 xor_imm;
157 
158  /* get 22-bit immediate of sethi instruction */
159  offset = (s4) (mcode & 0x3fffff);
160  offset = offset << 10;
161 
162  /* now the xor */
163  mcode = *((u4 *) (ra+12) );
164  xor_imm = decode_13bit_imm(mcode);
165 
166  offset ^= xor_imm;
167  }
168  else {
169  u4 mcode_masked;
170 
171  mcode_masked = SHIFT_AND_MASK(mcode);
172 
173  assert(mcode_masked == 0x40001);
174 
175  /* mask and extend the negative sign for the 13 bit immediate */
176  offset = decode_13bit_imm(mcode);
177  }
178 
179  pv += offset;
180 
181  return pv;
182 }
183 
184 
185 /* md_cacheflush ***************************************************************
186 
187  Calls the system's function to flush the instruction and data
188  cache.
189 
190 *******************************************************************************/
191 
192 inline static void md_cacheflush(void *addr, int nbytes)
193 {
194  /* don't know yet */
195 }
196 
197 
198 /* md_dcacheflush **************************************************************
199 
200  Calls the system's function to flush the data cache.
201 
202 *******************************************************************************/
203 
204 inline static void md_dcacheflush(void *addr, int nbytes)
205 {
206  /* XXX don't know yet */
207  /* printf("md_dcacheflush\n"); */
208  __asm__ __volatile__ ( "membar 0x7F" : : : "memory" );
209 }
210 
211 #endif // VM_JIT_SPARC64_MD_HPP_
212 
213 
214 /*
215  * These are local overrides for various environment variables in Emacs.
216  * Please do not remove this and leave it at the end of the file, where
217  * Emacs will automagically detect them.
218  * ---------------------------------------------------------------------
219  * Local variables:
220  * mode: c++
221  * indent-tabs-mode: t
222  * c-basic-offset: 4
223  * tab-width: 4
224  * End:
225  * vim:noexpandtab:sw=4:ts=4:
226  */
#define pv
Definition: md-asm.hpp:65
s2 decode_13bit_imm(u4 instr)
Definition: md.cpp:57
#define ra
Definition: md-asm.hpp:62
int32_t stackframesize
Definition: code.hpp:88
#define BIAS
Definition: md-abi.hpp:107
static void * md_get_framepointer(void *sp)
Definition: md.hpp:79
static void md_dcacheflush(void *addr, int nbytes)
Definition: md.hpp:204
uint64_t u8
Definition: types.hpp:49
static void * md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
Definition: md.hpp:62
static int32_t md_stacktrace_get_framesize(codeinfo *code)
Returns the size (in bytes) of the current stackframe, specified by the passed codeinfo structure...
Definition: md.hpp:43
int32_t s4
Definition: types.hpp:45
static void * md_get_pv_from_stackframe(void *sp)
Definition: md.hpp:91
uint32_t u4
Definition: types.hpp:46
#define IS_SETHI(instr)
Definition: md.hpp:126
#define sp
Definition: md-asm.hpp:81
#define SHIFT_AND_MASK(instr)
Definition: md.hpp:121
int16_t s2
Definition: types.hpp:42
static void * md_codegen_get_pv_from_pc(void *ra)
Definition: md.hpp:143
#define fp
Definition: md-asm.hpp:79
static void md_cacheflush(void *addr, int nbytes)
Definition: md.hpp:138