blob: e0af59eab68bea5ea8c8274ff01aeba42670a06c [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_generic_regs.h ---*/
sewardjc97096c2004-06-30 09:28:04 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardjcef7d3e2009-07-02 12:21:59 +000036#ifndef __VEX_HOST_GENERIC_REGS_H
37#define __VEX_HOST_GENERIC_REGS_H
sewardjc97096c2004-06-30 09:28:04 +000038
sewardj887a11a2004-07-05 17:26:47 +000039#include "libvex_basictypes.h"
sewardj35421a32004-07-05 13:12:34 +000040
sewardjc97096c2004-06-30 09:28:04 +000041
sewardj8bc26ee2004-07-01 18:30:32 +000042/*---------------------------------------------------------*/
43/*--- Representing HOST REGISTERS ---*/
44/*---------------------------------------------------------*/
45
sewardjc97096c2004-06-30 09:28:04 +000046/* Host registers. Stuff to represent:
47
48 - The register number
49 - The register class
50 - Whether or not the register is a virtual reg.
51
52 Registers are a 32-bit Int, thusly:
53
sewardjaf5a5222004-07-01 23:14:42 +000054 bits 31-28 are the register class.
55 bits 27-23 are 0000b for real register, 0001b for virtual register
56 bits 23-0 register number
57
58 Note (importantly) that by arranging that the class field is never
59 0000b, any valid register looks like an extremely large int -- at
60 least 2^28 -- and so there is little chance of confusing it with an
61 integer array index in the register allocator.
62
63 Note further that since the class field is never 1111b, no valid
64 register can have the value INVALID_HREG.
sewardjc97096c2004-06-30 09:28:04 +000065
sewardj6c299f32009-12-31 18:00:12 +000066 There are currently 6 register classes:
sewardjc97096c2004-06-30 09:28:04 +000067
sewardj6c299f32009-12-31 18:00:12 +000068 int32 int64 float32 float64 simd64 simd128
sewardjc97096c2004-06-30 09:28:04 +000069*/
70
florian79efdc62013-02-11 00:47:35 +000071typedef
72 struct {
73 UInt reg;
74 }
75 HReg;
sewardjc97096c2004-06-30 09:28:04 +000076
sewardjaf5a5222004-07-01 23:14:42 +000077/* When extending this, do not use any value > 14 or < 0. */
sewardj4a31b262004-12-01 02:24:44 +000078/* HRegClass describes host register classes which the instruction
79 selectors can speak about. We would not expect all of them to be
80 available on any specific host. For example on x86, the available
81 classes are: Int32, Flt64, Vec128 only.
sewardj1e6ad742004-12-02 16:16:11 +000082
sewardj6c299f32009-12-31 18:00:12 +000083 IMPORTANT NOTE: host_generic_reg_alloc2.c needs how much space is
84 needed to spill each class of register. It allocates the following
85 amount of space:
sewardj7fb65eb2007-03-25 04:14:58 +000086
sewardj6c299f32009-12-31 18:00:12 +000087 HRcInt32 64 bits
sewardj7fb65eb2007-03-25 04:14:58 +000088 HRcInt64 64 bits
sewardj6c299f32009-12-31 18:00:12 +000089 HRcFlt32 64 bits
90 HRcFlt64 128 bits (on x86 these are spilled by fstpt/fldt and
91 so won't fit in a 64-bit slot)
sewardj7fb65eb2007-03-25 04:14:58 +000092 HRcVec64 64 bits
93 HRcVec128 128 bits
94
95 If you add another regclass, you must remember to update
sewardj6c299f32009-12-31 18:00:12 +000096 host_generic_reg_alloc2.c accordingly.
sewardj4a31b262004-12-01 02:24:44 +000097*/
sewardjc97096c2004-06-30 09:28:04 +000098typedef
sewardj4a31b262004-12-01 02:24:44 +000099 enum {
100 HRcINVALID=1, /* NOT A VALID REGISTER CLASS */
sewardj6c299f32009-12-31 18:00:12 +0000101 HRcInt32=3, /* 32-bit int */
102 HRcInt64=4, /* 64-bit int */
103 HRcFlt32=5, /* 32-bit float */
sewardj4a31b262004-12-01 02:24:44 +0000104 HRcFlt64=6, /* 64-bit float */
105 HRcVec64=7, /* 64-bit SIMD */
sewardj3616a2e2012-05-27 16:18:13 +0000106 HRcVec128=8 /* 128-bit SIMD */
sewardjb3d4ce72004-07-02 07:09:23 +0000107 }
sewardjc97096c2004-06-30 09:28:04 +0000108 HRegClass;
109
sewardj35421a32004-07-05 13:12:34 +0000110extern void ppHRegClass ( HRegClass );
sewardjaf5a5222004-07-01 23:14:42 +0000111
sewardjc97096c2004-06-30 09:28:04 +0000112
113/* Print an HReg in a generic (non-target-specific) way. */
sewardj35421a32004-07-05 13:12:34 +0000114extern void ppHReg ( HReg );
sewardjc97096c2004-06-30 09:28:04 +0000115
116/* Construct/destruct. */
sewardj666fbac2004-10-14 10:42:15 +0000117static inline HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual ) {
118 UInt r24 = regno & 0x00FFFFFF;
119 /* This is critical. The register number field may only
120 occupy 24 bits. */
121 if (r24 != regno)
122 vpanic("mkHReg: regno exceeds 2^24");
florian79efdc62013-02-11 00:47:35 +0000123 HReg r;
124 r.reg = regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0);
125 return r;
sewardj666fbac2004-10-14 10:42:15 +0000126}
sewardjc97096c2004-06-30 09:28:04 +0000127
sewardj1f40a0a2004-07-21 12:28:07 +0000128static inline HRegClass hregClass ( HReg r ) {
florian79efdc62013-02-11 00:47:35 +0000129 UInt rc = r.reg;
sewardj1f40a0a2004-07-21 12:28:07 +0000130 rc = (rc >> 28) & 0x0F;
sewardj3616a2e2012-05-27 16:18:13 +0000131 vassert(rc >= HRcInt32 && rc <= HRcVec128);
sewardj1f40a0a2004-07-21 12:28:07 +0000132 return (HRegClass)rc;
133}
134
135static inline UInt hregNumber ( HReg r ) {
florian79efdc62013-02-11 00:47:35 +0000136 return r.reg & 0x00FFFFFF;
sewardj1f40a0a2004-07-21 12:28:07 +0000137}
138
139static inline Bool hregIsVirtual ( HReg r ) {
florian79efdc62013-02-11 00:47:35 +0000140 return toBool(r.reg & (1<<24));
sewardj1f40a0a2004-07-21 12:28:07 +0000141}
142
florian79efdc62013-02-11 00:47:35 +0000143static inline Bool sameHReg ( HReg r1, HReg r2 )
144{
145 return toBool(r1.reg == r2.reg);
146}
sewardj1f40a0a2004-07-21 12:28:07 +0000147
florian79efdc62013-02-11 00:47:35 +0000148static const HReg INVALID_HREG = { 0xFFFFFFFF };
sewardjc97096c2004-06-30 09:28:04 +0000149
florian79efdc62013-02-11 00:47:35 +0000150static inline Bool hregIsInvalid ( HReg r )
151{
152 return sameHReg(r, INVALID_HREG);
153}
sewardj8bc26ee2004-07-01 18:30:32 +0000154
155/*---------------------------------------------------------*/
156/*--- Recording register usage (for reg-alloc) ---*/
157/*---------------------------------------------------------*/
158
159typedef
160 enum { HRmRead, HRmWrite, HRmModify }
161 HRegMode;
162
163
164/* A struct for recording the usage of registers in instructions.
165 This can get quite large, but we don't expect to allocate them
166 dynamically, so there's no problem.
167*/
sewardj1001dc42005-02-21 08:25:55 +0000168#define N_HREG_USAGE 25
sewardj8bc26ee2004-07-01 18:30:32 +0000169
170typedef
171 struct {
172 HReg hreg[N_HREG_USAGE];
173 HRegMode mode[N_HREG_USAGE];
174 Int n_used;
175 }
176 HRegUsage;
177
sewardj35421a32004-07-05 13:12:34 +0000178extern void ppHRegUsage ( HRegUsage* );
sewardj8bc26ee2004-07-01 18:30:32 +0000179
sewardj666fbac2004-10-14 10:42:15 +0000180static inline void initHRegUsage ( HRegUsage* tab ) {
181 tab->n_used = 0;
182}
sewardj8bc26ee2004-07-01 18:30:32 +0000183
184/* Add a register to a usage table. Combine incoming read uses with
185 existing write uses into a modify use, and vice versa. Do not
186 create duplicate entries -- each reg should only be mentioned once.
187*/
sewardj53f85a92004-07-02 13:45:17 +0000188extern void addHRegUse ( HRegUsage*, HRegMode, HReg );
sewardj8bc26ee2004-07-01 18:30:32 +0000189
190
191
192/*---------------------------------------------------------*/
193/*--- Indicating register remappings (for reg-alloc) ---*/
194/*---------------------------------------------------------*/
195
sewardj0ec33252004-07-03 13:30:00 +0000196/* Note that such maps can only map virtual regs to real regs.
197 addToHRegRenap will barf if given a pair not of that form. As a
198 result, no valid HRegRemap will bind a real reg to anything, and so
199 if lookupHRegMap is given a real reg, it returns it unchanged.
200 This is precisely the behaviour that the register allocator needs
201 to impose its decisions on the instructions it processes. */
202
sewardjcdc376d2012-04-23 11:21:12 +0000203#define N_HREG_REMAP 6
sewardj8bc26ee2004-07-01 18:30:32 +0000204
205typedef
206 struct {
207 HReg orig [N_HREG_REMAP];
208 HReg replacement[N_HREG_REMAP];
209 Int n_used;
210 }
211 HRegRemap;
212
sewardj35421a32004-07-05 13:12:34 +0000213extern void ppHRegRemap ( HRegRemap* );
sewardj8bc26ee2004-07-01 18:30:32 +0000214extern void initHRegRemap ( HRegRemap* );
215extern void addToHRegRemap ( HRegRemap*, HReg, HReg );
216extern HReg lookupHRegRemap ( HRegRemap*, HReg );
217
sewardjc97096c2004-06-30 09:28:04 +0000218
sewardjaf5a5222004-07-01 23:14:42 +0000219/*---------------------------------------------------------*/
220/*--- Abstract instructions ---*/
221/*---------------------------------------------------------*/
222
223/* A type is needed to refer to pointers to instructions of any
224 target. Defining it like this means that HInstr* can stand in for
225 X86Instr*, ArmInstr*, etc. */
226
227typedef void HInstr;
228
229
sewardj194d54a2004-07-03 19:08:18 +0000230/* An expandable array of HInstr*'s. Handy for insn selection and
231 register allocation. n_vregs indicates the number of virtual
232 registers mentioned in the code, something that reg-alloc needs to
233 know. These are required to be numbered 0 .. n_vregs-1.
234*/
sewardj2cd80dc2004-07-02 15:20:40 +0000235typedef
236 struct {
237 HInstr** arr;
238 Int arr_size;
239 Int arr_used;
sewardj194d54a2004-07-03 19:08:18 +0000240 Int n_vregs;
sewardj2cd80dc2004-07-02 15:20:40 +0000241 }
242 HInstrArray;
243
244extern HInstrArray* newHInstrArray ( void );
sewardj2cd80dc2004-07-02 15:20:40 +0000245extern void addHInstr ( HInstrArray*, HInstr* );
246
sewardjaf5a5222004-07-01 23:14:42 +0000247
sewardj2cd80dc2004-07-02 15:20:40 +0000248/*---------------------------------------------------------*/
sewardjcfe046e2013-01-17 14:23:53 +0000249/*--- C-Call return-location descriptions ---*/
250/*---------------------------------------------------------*/
251
252/* This is common to all back ends. It describes where the return
253 value from a C call is located. This is important in the case that
254 the call is conditional, since the return locations will need to be
255 set to 0x555..555 in the case that the call does not happen. */
256
257typedef
258 enum {
sewardj74142b82013-08-08 10:28:59 +0000259 RLPri_INVALID, /* INVALID */
260 RLPri_None, /* no return value (a.k.a C "void") */
261 RLPri_Int, /* in the primary int return reg */
262 RLPri_2Int, /* in both primary and secondary int ret regs */
263 RLPri_V128SpRel, /* 128-bit value, on the stack */
264 RLPri_V256SpRel /* 256-bit value, on the stack */
265 }
266 RetLocPrimary;
267
268typedef
269 struct {
270 /* Primary description */
271 RetLocPrimary pri;
272 /* For .pri == RLPri_V128SpRel or RLPri_V256SpRel only, gives
273 the offset of the lowest addressed byte of the value,
274 relative to the stack pointer. For all other .how values,
275 has no meaning and should be zero. */
276 Int spOff;
sewardjcfe046e2013-01-17 14:23:53 +0000277 }
278 RetLoc;
279
280extern void ppRetLoc ( RetLoc rloc );
281
sewardj74142b82013-08-08 10:28:59 +0000282static inline RetLoc mk_RetLoc_simple ( RetLocPrimary pri ) {
283 vassert(pri >= RLPri_INVALID && pri <= RLPri_2Int);
284 return (RetLoc){pri, 0};
285}
286
287static inline RetLoc mk_RetLoc_spRel ( RetLocPrimary pri, Int off ) {
288 vassert(pri >= RLPri_V128SpRel && pri <= RLPri_V256SpRel);
289 return (RetLoc){pri, off};
290}
291
292static inline Bool is_sane_RetLoc ( RetLoc rloc ) {
293 switch (rloc.pri) {
294 case RLPri_None: case RLPri_Int: case RLPri_2Int:
295 return rloc.spOff == 0;
296 case RLPri_V128SpRel: case RLPri_V256SpRel:
297 return True;
298 default:
299 return False;
300 }
301}
302
303static inline RetLoc mk_RetLoc_INVALID ( void ) {
304 return (RetLoc){RLPri_INVALID, 0};
305}
306
307static inline Bool is_RetLoc_INVALID ( RetLoc rl ) {
308 return rl.pri == RLPri_INVALID && rl.spOff == 0;
309}
310
sewardjcfe046e2013-01-17 14:23:53 +0000311
312/*---------------------------------------------------------*/
sewardj2cd80dc2004-07-02 15:20:40 +0000313/*--- Reg alloc: TODO: move somewhere else ---*/
314/*---------------------------------------------------------*/
315
316extern
317HInstrArray* doRegisterAllocation (
318
319 /* Incoming virtual-registerised code. */
320 HInstrArray* instrs_in,
sewardj2cd80dc2004-07-02 15:20:40 +0000321
322 /* An array listing all the real registers the allocator may use,
323 in no particular order. */
324 HReg* available_real_regs,
325 Int n_available_real_regs,
326
327 /* Return True iff the given insn is a reg-reg move, in which
328 case also return the src and dst regs. */
floriand8c64e02014-10-08 08:54:44 +0000329 Bool (*isMove) (const HInstr*, HReg*, HReg*),
sewardj2cd80dc2004-07-02 15:20:40 +0000330
331 /* Get info about register usage in this insn. */
floriand8c64e02014-10-08 08:54:44 +0000332 void (*getRegUsage) (HRegUsage*, const HInstr*, Bool),
sewardj2cd80dc2004-07-02 15:20:40 +0000333
334 /* Apply a reg-reg mapping to an insn. */
cerion92b64362005-12-13 12:02:26 +0000335 void (*mapRegs) (HRegRemap*, HInstr*, Bool),
sewardj2cd80dc2004-07-02 15:20:40 +0000336
sewardj6c299f32009-12-31 18:00:12 +0000337 /* Return insn(s) to spill/restore a real reg to a spill slot
sewardjfb7373a2007-08-25 21:29:03 +0000338 offset. And optionally a function to do direct reloads. */
sewardj6c299f32009-12-31 18:00:12 +0000339 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ),
340 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool ),
sewardjfb7373a2007-08-25 21:29:03 +0000341 HInstr* (*directReload) ( HInstr*, HReg, Short ),
sewardj81ec4182004-10-25 23:15:52 +0000342 Int guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000343
344 /* For debug printing only. */
floriand8c64e02014-10-08 08:54:44 +0000345 void (*ppInstr) ( const HInstr*, Bool ),
cerion92b64362005-12-13 12:02:26 +0000346 void (*ppReg) ( HReg ),
347
348 /* 32/64bit mode */
349 Bool mode64
sewardj2cd80dc2004-07-02 15:20:40 +0000350);
351
352
sewardjcef7d3e2009-07-02 12:21:59 +0000353#endif /* ndef __VEX_HOST_GENERIC_REGS_H */
sewardj2cd80dc2004-07-02 15:20:40 +0000354
sewardj8bc26ee2004-07-01 18:30:32 +0000355/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000356/*--- host_generic_regs.h ---*/
sewardj8bc26ee2004-07-01 18:30:32 +0000357/*---------------------------------------------------------------*/