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