CACAO
md.hpp
Go to the documentation of this file.
1 /* src/vm/jit/aarch64/md.hpp - machine dependent Aarch64 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_AARCH64_MD_HPP_
27 #define VM_JIT_AARCH64_MD_HPP_ 1
28 
29 #include "config.h"
30 
31 #include <cassert>
32 #include <stdint.h>
33 
35 
36 #include "vm/global.hpp"
37 #include "vm/vm.hpp"
38 
39 #include "vm/jit/asmpart.hpp"
40 #include "vm/jit/code.hpp"
42 #include "vm/jit/disass.hpp"
43 #include "vm/jit/methodtree.hpp"
44 
45 
46 /* global variables ***********************************************************/
47 
48 extern bool has_ext_instr_set;
49 
50 
51 /* inline functions ***********************************************************/
52 
53 /**
54  * Returns the size (in bytes) of the current stackframe, specified by
55  * the passed codeinfo structure.
56  */
57 inline static int32_t md_stacktrace_get_framesize(codeinfo* code)
58 {
59  // Check for the asm_vm_call_method special case.
60  if (code == NULL)
61  return 0;
62 
63  // On Aarch64 we use 8-byte stackslots with a 16-byte aligned stack
64  u4 stacksize = code->stackframesize * 8;
65  stacksize += stacksize % 16;
66  return stacksize;
67 }
68 
69 
70 /* md_stacktrace_get_returnaddress *********************************************
71 
72  Returns the return address of the current stackframe, specified by
73  the passed stack pointer and the stack frame size.
74 
75 *******************************************************************************/
76 
77 inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
78 {
79  void *ra;
80 
81  /* On Aarch64 the return address is located on the top of the
82  stackframe. */
83 
84  ra = *((void **) (((uintptr_t) sp) + stackframesize - SIZEOF_VOID_P));
85 
86  return ra;
87 }
88 
89 
90 /* md_codegen_get_pv_from_pc ***************************************************
91 
92  Machine code:
93 
94  6b5b4000 jsr (pv)
95  277afffe ldah pv,-2(ra)
96  237ba61c lda pv,-23012(pv)
97 
98 *******************************************************************************/
99 
100 inline static void *md_codegen_get_pv_from_pc(void *ra)
101 {
102  uint32_t *pc = (uint32_t *) ra;
103  void *pv = NULL;
104 
105  /* Get first instruction word after jump. */
106  uint32_t mcode = pc[0];
107 
108  /* Check for SUB with immediate, as immediate is only 12 bit wide, we
109  * might have 2 consecutive subs where the first is shifted */
110  u1 high = (mcode >> 24) & 0xff;
111  if (high == 0xD1) {
112  u1 shift = (mcode >> 22) & 0x3;
113  s4 offset = (mcode >> 10) & 0xfff;
114  if (shift) {
115  // as this instruction is shifted, shift the offset by 12 bits
116  // and add the offset of the next sub instruction
117  offset = (offset << 12);
118  offset += (pc[1] >> 10) & 0xfff;
119  }
120  pv = ((uint8_t *) pc) - offset;
121  } else {
122  // md_codegen_get_pv_from_pc is also called for optimized methods (compiler2).
123  // Since we do not adjust the pv register after each subroutine call,
124  // we fall back on searching the method tree
125  pv = methodtree_find(ra);
126  }
127 
128  return pv;
129 }
130 
131 
132 /* md_cacheflush ***************************************************************
133 
134  Calls the system's function to flush the instruction and data
135  cache.
136 
137 *******************************************************************************/
138 
139 extern void asm_flush_icache_range(void *start, void *end) __asm__("asm_flush_icache_range");
140 extern void asm_flush_dcache_range(void *start, void *end) __asm__("asm_flush_dcache_range");
141 
142 inline static void md_cacheflush(void *addr, int nbytes)
143 {
144  asm_flush_icache_range(addr, ((char*)addr + nbytes));
145  asm_flush_dcache_range(addr, ((char*)addr + nbytes));
146 }
147 
148 
149 /* md_icacheflush **************************************************************
150 
151  Calls the system's function to flush the instruction cache.
152 
153 *******************************************************************************/
154 
155 inline static void md_icacheflush(void *addr, int nbytes)
156 {
157  asm_flush_icache_range(addr, ((char*)addr + nbytes));
158 }
159 
160 
161 /* md_dcacheflush **************************************************************
162 
163  Calls the system's function to flush the data cache.
164 
165 *******************************************************************************/
166 
167 inline static void md_dcacheflush(void *addr, int nbytes)
168 {
169  asm_flush_dcache_range(addr, ((char*)addr + nbytes));
170 }
171 
172 #endif // VM_JIT_AARCH64_MD_HPP_
173 
174 
175 /*
176  * These are local overrides for various environment variables in Emacs.
177  * Please do not remove this and leave it at the end of the file, where
178  * Emacs will automagically detect them.
179  * ---------------------------------------------------------------------
180  * Local variables:
181  * mode: c++
182  * indent-tabs-mode: t
183  * c-basic-offset: 4
184  * tab-width: 4
185  * End:
186  */
#define methodtree_find
Definition: md-asm.hpp:101
#define pv
Definition: md-asm.hpp:65
#define ra
Definition: md-asm.hpp:62
int32_t stackframesize
Definition: code.hpp:87
bool has_ext_instr_set
Definition: md.cpp:40
static void md_dcacheflush(void *addr, int nbytes)
Definition: md.hpp:167
void asm_flush_dcache_range(void *start, void *end) __asm__("asm_flush_dcache_range")
uint8_t u1
Definition: types.hpp:40
void asm_flush_icache_range(void *start, void *end) __asm__("asm_flush_icache_range")
int32_t s4
Definition: types.hpp:45
static void * md_codegen_get_pv_from_pc(void *ra)
Definition: md.hpp:100
uint32_t u4
Definition: types.hpp:46
#define sp
Definition: md-asm.hpp:81
#define pc
Definition: md-asm.hpp:56
static void * md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
Definition: md.hpp:77
static void md_icacheflush(void *addr, int nbytes)
Definition: md.hpp:155
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:57
static void md_cacheflush(void *addr, int nbytes)
Definition: md.hpp:142