blob: 7e9923b68dd7d6c9a783bcc3a073bac116823633 [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardj38a3f862005-01-13 15:06:51 +00004/*--- This file (h_generic_regs.h) is ---*/
sewardjdbcfae72005-08-02 11:14:04 +00005/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/
sewardjc97096c2004-06-30 09:28:04 +00006/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjf8ed9d82004-11-12 17:40:23 +00009/*
10 This file is part of LibVEX, a library for dynamic binary
11 instrumentation and translation.
12
sewardje7441532007-01-08 05:51:05 +000013 Copyright (C) 2004-2007 OpenWorks LLP. All rights reserved.
sewardjf8ed9d82004-11-12 17:40:23 +000014
sewardj7bd6ffe2005-08-03 16:07:36 +000015 This library is made available under a dual licensing scheme.
sewardjf8ed9d82004-11-12 17:40:23 +000016
sewardj7bd6ffe2005-08-03 16:07:36 +000017 If you link LibVEX against other code all of which is itself
18 licensed under the GNU General Public License, version 2 dated June
19 1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
20 v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL
21 is missing, you can obtain a copy of the GPL v2 from the Free
22 Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 02110-1301, USA.
24
25 For any other uses of LibVEX, you must first obtain a commercial
26 license from OpenWorks LLP. Please contact info@open-works.co.uk
27 for information about commercial licensing.
28
29 This software is provided by OpenWorks LLP "as is" and any express
30 or implied warranties, including, but not limited to, the implied
31 warranties of merchantability and fitness for a particular purpose
32 are disclaimed. In no event shall OpenWorks LLP be liable for any
33 direct, indirect, incidental, special, exemplary, or consequential
34 damages (including, but not limited to, procurement of substitute
35 goods or services; loss of use, data, or profits; or business
36 interruption) however caused and on any theory of liability,
37 whether in contract, strict liability, or tort (including
38 negligence or otherwise) arising in any way out of the use of this
39 software, even if advised of the possibility of such damage.
sewardjf8ed9d82004-11-12 17:40:23 +000040
41 Neither the names of the U.S. Department of Energy nor the
42 University of California nor the names of its contributors may be
43 used to endorse or promote products derived from this software
44 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000045*/
46
sewardj38a3f862005-01-13 15:06:51 +000047#ifndef __H_GENERIC_REGS_H
48#define __H_GENERIC_REGS_H
sewardjc97096c2004-06-30 09:28:04 +000049
sewardj887a11a2004-07-05 17:26:47 +000050#include "libvex_basictypes.h"
sewardj35421a32004-07-05 13:12:34 +000051
sewardjc97096c2004-06-30 09:28:04 +000052
sewardj8bc26ee2004-07-01 18:30:32 +000053/*---------------------------------------------------------*/
54/*--- Representing HOST REGISTERS ---*/
55/*---------------------------------------------------------*/
56
sewardjc97096c2004-06-30 09:28:04 +000057/* Host registers. Stuff to represent:
58
59 - The register number
60 - The register class
61 - Whether or not the register is a virtual reg.
62
63 Registers are a 32-bit Int, thusly:
64
sewardjaf5a5222004-07-01 23:14:42 +000065 bits 31-28 are the register class.
66 bits 27-23 are 0000b for real register, 0001b for virtual register
67 bits 23-0 register number
68
69 Note (importantly) that by arranging that the class field is never
70 0000b, any valid register looks like an extremely large int -- at
71 least 2^28 -- and so there is little chance of confusing it with an
72 integer array index in the register allocator.
73
74 Note further that since the class field is never 1111b, no valid
75 register can have the value INVALID_HREG.
sewardjc97096c2004-06-30 09:28:04 +000076
sewardj6485f252005-07-04 09:21:19 +000077 There are currently 5 register classes:
sewardjc97096c2004-06-30 09:28:04 +000078
sewardj6485f252005-07-04 09:21:19 +000079 int32 int64 float64 simd64 simd128
sewardjc97096c2004-06-30 09:28:04 +000080*/
81
82typedef UInt HReg;
83
sewardjaf5a5222004-07-01 23:14:42 +000084/* When extending this, do not use any value > 14 or < 0. */
sewardj4a31b262004-12-01 02:24:44 +000085/* HRegClass describes host register classes which the instruction
86 selectors can speak about. We would not expect all of them to be
87 available on any specific host. For example on x86, the available
88 classes are: Int32, Flt64, Vec128 only.
sewardj1e6ad742004-12-02 16:16:11 +000089
sewardj7fb65eb2007-03-25 04:14:58 +000090 IMPORTANT NOTE: reg_alloc2.c needs how much space is needed to spill
91 each class of register. It has the following knowledge hardwired in:
92
93 HRcInt32 32 bits
94 HRcInt64 64 bits
95 HRcFlt64 80 bits (on x86 these are spilled by fstpt/fldt)
96 HRcVec64 64 bits
97 HRcVec128 128 bits
98
99 If you add another regclass, you must remember to update
100 reg_alloc2.c accordingly.
sewardj4a31b262004-12-01 02:24:44 +0000101*/
sewardjc97096c2004-06-30 09:28:04 +0000102typedef
sewardj4a31b262004-12-01 02:24:44 +0000103 enum {
104 HRcINVALID=1, /* NOT A VALID REGISTER CLASS */
105 HRcInt32=4, /* 32-bit int */
106 HRcInt64=5, /* 64-bit int */
107 HRcFlt64=6, /* 64-bit float */
108 HRcVec64=7, /* 64-bit SIMD */
109 HRcVec128=8 /* 128-bit SIMD */
sewardjb3d4ce72004-07-02 07:09:23 +0000110 }
sewardjc97096c2004-06-30 09:28:04 +0000111 HRegClass;
112
sewardj35421a32004-07-05 13:12:34 +0000113extern void ppHRegClass ( HRegClass );
sewardjaf5a5222004-07-01 23:14:42 +0000114
sewardjc97096c2004-06-30 09:28:04 +0000115
116/* Print an HReg in a generic (non-target-specific) way. */
sewardj35421a32004-07-05 13:12:34 +0000117extern void ppHReg ( HReg );
sewardjc97096c2004-06-30 09:28:04 +0000118
119/* Construct/destruct. */
sewardj666fbac2004-10-14 10:42:15 +0000120static inline HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual ) {
121 UInt r24 = regno & 0x00FFFFFF;
122 /* This is critical. The register number field may only
123 occupy 24 bits. */
124 if (r24 != regno)
125 vpanic("mkHReg: regno exceeds 2^24");
126 return regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0);
127}
sewardjc97096c2004-06-30 09:28:04 +0000128
sewardj1f40a0a2004-07-21 12:28:07 +0000129static inline HRegClass hregClass ( HReg r ) {
130 UInt rc = r;
131 rc = (rc >> 28) & 0x0F;
sewardjb5749b02004-12-29 19:23:49 +0000132 vassert(rc >= HRcInt32 && rc <= HRcVec128);
sewardj1f40a0a2004-07-21 12:28:07 +0000133 return (HRegClass)rc;
134}
135
136static inline UInt hregNumber ( HReg r ) {
137 return ((UInt)r) & 0x00FFFFFF;
138}
139
140static inline Bool hregIsVirtual ( HReg r ) {
sewardj58277842005-02-07 03:11:17 +0000141 return toBool(((UInt)r) & (1<<24));
sewardj1f40a0a2004-07-21 12:28:07 +0000142}
143
144
sewardjc97096c2004-06-30 09:28:04 +0000145
sewardjaf5a5222004-07-01 23:14:42 +0000146
sewardj8bc26ee2004-07-01 18:30:32 +0000147#define INVALID_HREG ((HReg)0xFFFFFFFF)
148
149
150/*---------------------------------------------------------*/
151/*--- Recording register usage (for reg-alloc) ---*/
152/*---------------------------------------------------------*/
153
154typedef
155 enum { HRmRead, HRmWrite, HRmModify }
156 HRegMode;
157
158
159/* A struct for recording the usage of registers in instructions.
160 This can get quite large, but we don't expect to allocate them
161 dynamically, so there's no problem.
162*/
sewardj1001dc42005-02-21 08:25:55 +0000163#define N_HREG_USAGE 25
sewardj8bc26ee2004-07-01 18:30:32 +0000164
165typedef
166 struct {
167 HReg hreg[N_HREG_USAGE];
168 HRegMode mode[N_HREG_USAGE];
169 Int n_used;
170 }
171 HRegUsage;
172
sewardj35421a32004-07-05 13:12:34 +0000173extern void ppHRegUsage ( HRegUsage* );
sewardj8bc26ee2004-07-01 18:30:32 +0000174
sewardj666fbac2004-10-14 10:42:15 +0000175static inline void initHRegUsage ( HRegUsage* tab ) {
176 tab->n_used = 0;
177}
sewardj8bc26ee2004-07-01 18:30:32 +0000178
179/* Add a register to a usage table. Combine incoming read uses with
180 existing write uses into a modify use, and vice versa. Do not
181 create duplicate entries -- each reg should only be mentioned once.
182*/
sewardj53f85a92004-07-02 13:45:17 +0000183extern void addHRegUse ( HRegUsage*, HRegMode, HReg );
sewardj8bc26ee2004-07-01 18:30:32 +0000184
185
186
187/*---------------------------------------------------------*/
188/*--- Indicating register remappings (for reg-alloc) ---*/
189/*---------------------------------------------------------*/
190
sewardj0ec33252004-07-03 13:30:00 +0000191/* Note that such maps can only map virtual regs to real regs.
192 addToHRegRenap will barf if given a pair not of that form. As a
193 result, no valid HRegRemap will bind a real reg to anything, and so
194 if lookupHRegMap is given a real reg, it returns it unchanged.
195 This is precisely the behaviour that the register allocator needs
196 to impose its decisions on the instructions it processes. */
197
sewardj40c80262006-02-08 19:30:46 +0000198#define N_HREG_REMAP 5
sewardj8bc26ee2004-07-01 18:30:32 +0000199
200typedef
201 struct {
202 HReg orig [N_HREG_REMAP];
203 HReg replacement[N_HREG_REMAP];
204 Int n_used;
205 }
206 HRegRemap;
207
sewardj35421a32004-07-05 13:12:34 +0000208extern void ppHRegRemap ( HRegRemap* );
sewardj8bc26ee2004-07-01 18:30:32 +0000209extern void initHRegRemap ( HRegRemap* );
210extern void addToHRegRemap ( HRegRemap*, HReg, HReg );
211extern HReg lookupHRegRemap ( HRegRemap*, HReg );
212
sewardjc97096c2004-06-30 09:28:04 +0000213
sewardjaf5a5222004-07-01 23:14:42 +0000214/*---------------------------------------------------------*/
215/*--- Abstract instructions ---*/
216/*---------------------------------------------------------*/
217
218/* A type is needed to refer to pointers to instructions of any
219 target. Defining it like this means that HInstr* can stand in for
220 X86Instr*, ArmInstr*, etc. */
221
222typedef void HInstr;
223
224
sewardj194d54a2004-07-03 19:08:18 +0000225/* An expandable array of HInstr*'s. Handy for insn selection and
226 register allocation. n_vregs indicates the number of virtual
227 registers mentioned in the code, something that reg-alloc needs to
228 know. These are required to be numbered 0 .. n_vregs-1.
229*/
sewardj2cd80dc2004-07-02 15:20:40 +0000230typedef
231 struct {
232 HInstr** arr;
233 Int arr_size;
234 Int arr_used;
sewardj194d54a2004-07-03 19:08:18 +0000235 Int n_vregs;
sewardj2cd80dc2004-07-02 15:20:40 +0000236 }
237 HInstrArray;
238
239extern HInstrArray* newHInstrArray ( void );
sewardj2cd80dc2004-07-02 15:20:40 +0000240extern void addHInstr ( HInstrArray*, HInstr* );
241
sewardjaf5a5222004-07-01 23:14:42 +0000242
sewardj2cd80dc2004-07-02 15:20:40 +0000243/*---------------------------------------------------------*/
244/*--- Reg alloc: TODO: move somewhere else ---*/
245/*---------------------------------------------------------*/
246
247extern
248HInstrArray* doRegisterAllocation (
249
250 /* Incoming virtual-registerised code. */
251 HInstrArray* instrs_in,
sewardj2cd80dc2004-07-02 15:20:40 +0000252
253 /* An array listing all the real registers the allocator may use,
254 in no particular order. */
255 HReg* available_real_regs,
256 Int n_available_real_regs,
257
258 /* Return True iff the given insn is a reg-reg move, in which
259 case also return the src and dst regs. */
260 Bool (*isMove) (HInstr*, HReg*, HReg*),
261
262 /* Get info about register usage in this insn. */
cerion92b64362005-12-13 12:02:26 +0000263 void (*getRegUsage) (HRegUsage*, HInstr*, Bool),
sewardj2cd80dc2004-07-02 15:20:40 +0000264
265 /* Apply a reg-reg mapping to an insn. */
cerion92b64362005-12-13 12:02:26 +0000266 void (*mapRegs) (HRegRemap*, HInstr*, Bool),
sewardj2cd80dc2004-07-02 15:20:40 +0000267
268 /* Return an insn to spill/restore a real reg to a spill slot
sewardjfb7373a2007-08-25 21:29:03 +0000269 offset. And optionally a function to do direct reloads. */
cerion92b64362005-12-13 12:02:26 +0000270 HInstr* (*genSpill) ( HReg, Int, Bool ),
271 HInstr* (*genReload) ( HReg, Int, Bool ),
sewardjfb7373a2007-08-25 21:29:03 +0000272 HInstr* (*directReload) ( HInstr*, HReg, Short ),
sewardj81ec4182004-10-25 23:15:52 +0000273 Int guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000274
275 /* For debug printing only. */
cerion92b64362005-12-13 12:02:26 +0000276 void (*ppInstr) ( HInstr*, Bool ),
277 void (*ppReg) ( HReg ),
278
279 /* 32/64bit mode */
280 Bool mode64
sewardj2cd80dc2004-07-02 15:20:40 +0000281);
282
283
sewardj38a3f862005-01-13 15:06:51 +0000284#endif /* ndef __H_GENERIC_REGS_H */
sewardj2cd80dc2004-07-02 15:20:40 +0000285
sewardj8bc26ee2004-07-01 18:30:32 +0000286/*---------------------------------------------------------------*/
sewardj38a3f862005-01-13 15:06:51 +0000287/*--- h_generic_regs.h ---*/
sewardj8bc26ee2004-07-01 18:30:32 +0000288/*---------------------------------------------------------------*/