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