modified: common/CMakeLists.txt
[dyninst.git] / dyninstAPI / src / inst-aarch64.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #ifndef INST_AARCH64_H
32 #define INST_AARCH64_H
33
34
35 #define DEAD_REG              0
36 #define LIVE_REG              1
37 #define LIVE_UNCLOBBERED_REG  2
38 #define LIVE_CLOBBERED_REG    3
39
40 #define GPRSIZE_32            4
41 #define GPRSIZE_64            8
42 #define FPRSIZE               8
43
44 #define REG_SP                1         
45 #define REG_TOC               2   /* TOC anchor                            */
46 // REG_GUARD_OFFSET and REG_GUARD_VALUE could overlap.
47 #define REG_GUARD_ADDR        5   /* Arbitrary                             */
48 #define REG_GUARD_VALUE       6
49 #define REG_GUARD_OFFSET      6
50
51 #define REG_COST_ADDR         5
52 #define REG_COST_VALUE        6
53
54 #define REG_SCRATCH          10
55
56 #define REG_MT_POS           12   /* Register to reserve for MT implementation */
57 #define NUM_INSN_MT_PREAMBLE 26   /* number of instructions required for   */
58                                   /* the MT preamble.                      */ 
59
60 // The stack grows down from high addresses toward low addresses.
61 // There is a maximum number of bytes on the stack below the current
62 // value of the stack frame pointer that a function can use without
63 // first establishing a new stack frame.  When our instrumentation
64 // needs to use the stack, we make sure not to write into this
65 // potentially used area.  AIX documentation stated 220 bytes as
66 // the maximum size of this area.  64-bit PowerPC ELF ABI Supplement,
67 // Version 1.9, 2004-10-23, used by Linux, stated 288 bytes for this
68 // area.  We skip the larger number of bytes (288) to be safe on both
69 // AIX and Linux, 32-bit and 64-bit.
70 #define STACKSKIP          288
71
72 // Both 32-bit and 64-bit PowerPC ELF ABI documents for Linux state
73 // that the stack frame pointer value must always be 16-byte (quadword)
74 // aligned.  Use the following macro on all quantities used to
75 // increment or decrement the stack frame pointer.
76 #define ALIGN_QUADWORD(x)  ( ((x) + 0xf) & ~0xf )  //x is positive or unsigned
77
78 #define GPRSAVE_32  (32*4)
79 #define GPRSAVE_64  (32*8)
80 #define FPRSAVE     (14*8)
81 #define SPRSAVE_32  (6*4+8)
82 #define SPRSAVE_64  (6*8+8)
83 #define FUNCSAVE_32 (32*4)
84 #define FUNCSAVE_64 (32*8)
85 #define FUNCARGS_32 (16*4)
86 #define FUNCARGS_64 (16*8)
87 #define LINKAREA_32 (6*4)
88 #define LINKAREA_64 (6*8)
89
90 #if defined(os_linux)
91 #define PARAM_OFFSET(mutatee_address_width)                         \
92         (                                                           \
93             ((mutatee_address_width) == sizeof(uint64_t))           \
94             ? (   /* 64-bit ELF PowerPC Linux                   */  \
95                   sizeof(uint64_t) +  /* TOC save               */  \
96                   sizeof(uint64_t) +  /* link editor doubleword */  \
97                   sizeof(uint64_t) +  /* compiler doubleword    */  \
98                   sizeof(uint64_t) +  /* LR save                */  \
99                   sizeof(uint64_t) +  /* CR save                */  \
100                   sizeof(uint64_t)    /* Stack frame back chain */  \
101               )                                                     \
102             : (   /* 32-bit ELF PowerPC Linux                   */  \
103                   sizeof(uint32_t) +  /* LR save                */  \
104                   sizeof(uint32_t)    /* Stack frame back chain */  \
105               )                                                     \
106         )
107 #elif defined(os_vxworks)
108 #define PARAM_OFFSET(bah) (0)
109 #else
110 #error "Unknown operating system in inst-power.h"
111 #endif
112
113
114 // Okay, now that we have those defined, let's define the offsets upwards
115 #define TRAMP_FRAME_SIZE_32 ALIGN_QUADWORD(STACKSKIP + GPRSAVE_32 + FPRSAVE \
116                                            + SPRSAVE_32 \
117                                            + FUNCSAVE_32 + FUNCARGS_32 + LINKAREA_32)
118 #define TRAMP_FRAME_SIZE_64 ALIGN_QUADWORD(STACKSKIP + GPRSAVE_64 + FPRSAVE \
119                                            + SPRSAVE_64 \
120                                            + FUNCSAVE_64 + FUNCARGS_64 + LINKAREA_64)
121 #define PDYN_RESERVED_32 (LINKAREA_32 + FUNCARGS_32 + FUNCSAVE_32)
122 #define PDYN_RESERVED_64 (LINKAREA_64 + FUNCARGS_64 + FUNCSAVE_64)
123
124 #define TRAMP_SPR_OFFSET_32 (PDYN_RESERVED_32) /* 4 for LR */
125 #define STK_LR       (              0)
126 #define STK_CR_32    (STK_LR      + 4)
127 #define STK_CTR_32   (STK_CR_32   + 4)
128 #define STK_XER_32   (STK_CTR_32  + 4)
129 #define STK_FP_CR_32 (STK_XER_32  + 4)
130 #define STK_SPR0_32  (STK_FP_CR_32+ 8)
131
132 #define TRAMP_SPR_OFFSET_64 (PDYN_RESERVED_64)
133 #define STK_CR_64    (STK_LR      + 8)
134 #define STK_CTR_64   (STK_CR_64   + 8)
135 #define STK_XER_64   (STK_CTR_64  + 8)
136 #define STK_FP_CR_64 (STK_XER_64  + 8)
137 #define STK_SPR0_64  (STK_FP_CR_64+ 8)
138
139 #define TRAMP_SPR_OFFSET(x) (((x) == 8) ? TRAMP_SPR_OFFSET_64 : TRAMP_SPR_OFFSET_32)
140
141 #define TRAMP_FPR_OFFSET_32 (TRAMP_SPR_OFFSET_32 + SPRSAVE_32)
142 #define TRAMP_FPR_OFFSET_64 (TRAMP_SPR_OFFSET_64 + SPRSAVE_64)
143 #define TRAMP_FPR_OFFSET(x) (((x) == 8) ? TRAMP_FPR_OFFSET_64 : TRAMP_FPR_OFFSET_32)
144
145 #define TRAMP_GPR_OFFSET_32 (TRAMP_FPR_OFFSET_32 + FPRSAVE)
146 #define TRAMP_GPR_OFFSET_64 (TRAMP_FPR_OFFSET_64 + FPRSAVE)
147 #define TRAMP_GPR_OFFSET(x) (((x) == 8) ? TRAMP_GPR_OFFSET_64 : TRAMP_GPR_OFFSET_32)
148
149 #define FUNC_CALL_SAVE_32 (LINKAREA_32 + FUNCARGS_32)
150 #define FUNC_CALL_SAVE_64 (LINKAREA_64 + FUNCARGS_64)
151 #define FUNC_CALL_SAVE(x) (((x) == 8) ? FUNC_CALL_SAVE_64 : FUNC_CALL_SAVE_32)
152
153 ///////////////////////////// Multi-instruction sequences
154 class codeGen;
155
156 void saveSPR(codeGen &gen,
157              Register scratchReg,
158              int sprnum,
159              int stkOffset);
160 void restoreSPR(codeGen &gen,
161                 Register scratchReg,
162                 int sprnum,
163                 int stkOffset);
164 void saveLR(codeGen &gen,
165             Register scratchReg,
166             int stkOffset);
167 void restoreLR(codeGen &gen,
168                Register scratchReg,
169                int stkOffset);
170 void setBRL(codeGen &gen,
171             Register scratchReg,
172             long val,
173             unsigned ti); // We're lazy and hand in the next insn
174 void saveCR(codeGen &gen,
175             Register scratchReg,
176             int stkOffset);
177 void restoreCR(codeGen &gen,
178                Register scratchReg,
179                int stkOffset);
180 void saveFPSCR(codeGen &gen,
181                Register scratchReg,
182                int stkOffset);
183 void restoreFPSCR(codeGen &gen,
184                   Register scratchReg,
185                   int stkOffset);
186 void saveRegister(codeGen &gen,
187                   Register reg,
188                   int save_off);
189 // We may want to restore a _logical_ register N
190 // (that is, the save slot for N) into a different reg.
191 // This avoids using a temporary
192 void restoreRegister(codeGen &gen,
193                      Register source,
194                      Register dest,
195                      int save_off);
196 // Much more common case
197 void restoreRegister(codeGen &gen,
198                      Register reg,
199                      int save_off);
200 void saveFPRegister(codeGen &gen,
201                     Register reg,
202                     int save_off);
203 // See above...
204 void restoreFPRegister(codeGen &gen,
205                        Register source,
206                        Register dest,
207                        int save_off);
208 void restoreFPRegister(codeGen &gen,
209                        Register reg,
210                        int save_off);
211 void pushStack(codeGen &gen);
212 void popStack(codeGen &gen);
213 unsigned saveGPRegisters(codeGen &gen, 
214                          registerSpace *theRegSpace,
215                          int save_off, int numReqGPRs=-1);
216 unsigned restoreGPRegisters(codeGen &gen, 
217                             registerSpace *theRegSpace,
218                             int save_off);
219 unsigned saveFPRegisters(codeGen &gen, 
220                          registerSpace *theRegSpace,
221                          int save_off);
222 unsigned restoreFPRegisters(codeGen &gen,
223                             registerSpace *theRegSpace,
224                             int save_off);
225 unsigned saveSPRegisters(codeGen &gen, registerSpace *,
226                          int save_off, int force_save);
227 unsigned restoreSPRegisters(codeGen &gen, registerSpace *,
228                             int save_off, int force_save);
229
230 #endif