blob: 9bf1a750dbe4591f48ce9b066b7098091a5a14ec [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
4/*--- This file (host_regs.h) is ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
9#ifndef __HOST_REGS_H
10#define __HOST_REGS_H
11
12
sewardj8bc26ee2004-07-01 18:30:32 +000013/*---------------------------------------------------------*/
14/*--- Representing HOST REGISTERS ---*/
15/*---------------------------------------------------------*/
16
sewardjc97096c2004-06-30 09:28:04 +000017/* Host registers. Stuff to represent:
18
19 - The register number
20 - The register class
21 - Whether or not the register is a virtual reg.
22
23 Registers are a 32-bit Int, thusly:
24
sewardjaf5a5222004-07-01 23:14:42 +000025 bits 31-28 are the register class.
26 bits 27-23 are 0000b for real register, 0001b for virtual register
27 bits 23-0 register number
28
29 Note (importantly) that by arranging that the class field is never
30 0000b, any valid register looks like an extremely large int -- at
31 least 2^28 -- and so there is little chance of confusing it with an
32 integer array index in the register allocator.
33
34 Note further that since the class field is never 1111b, no valid
35 register can have the value INVALID_HREG.
sewardjc97096c2004-06-30 09:28:04 +000036
37 There are currently 3 register classes:
38
39 int
40 floating
sewardjaf5a5222004-07-01 23:14:42 +000041 vector
sewardjc97096c2004-06-30 09:28:04 +000042*/
43
44typedef UInt HReg;
45
sewardjaf5a5222004-07-01 23:14:42 +000046/* When extending this, do not use any value > 14 or < 0. */
sewardjc97096c2004-06-30 09:28:04 +000047typedef
sewardjb3d4ce72004-07-02 07:09:23 +000048enum { HRcInt=4, /* 32-bit int */
49 HRcInt64=5, /* 64-bit int */
50 HRcFloat=6, /* 64-bit float */
51 HRcVector=7, /* 64-bit SIMD */
52 HRcVector128=8 /* 128-bit SIMD */
53 }
sewardjc97096c2004-06-30 09:28:04 +000054 HRegClass;
55
sewardjaf5a5222004-07-01 23:14:42 +000056extern void ppHRegClass ( FILE*, HRegClass );
57
sewardjc97096c2004-06-30 09:28:04 +000058
59/* Print an HReg in a generic (non-target-specific) way. */
60extern void ppHReg ( FILE*, HReg );
61
62/* Construct/destruct. */
63extern HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual );
64
65extern HRegClass hregClass ( HReg );
66extern Bool hregIsVirtual ( HReg );
67extern UInt hregNumber ( HReg );
68
sewardjaf5a5222004-07-01 23:14:42 +000069
sewardj8bc26ee2004-07-01 18:30:32 +000070#define INVALID_HREG ((HReg)0xFFFFFFFF)
71
72
73/*---------------------------------------------------------*/
74/*--- Recording register usage (for reg-alloc) ---*/
75/*---------------------------------------------------------*/
76
77typedef
78 enum { HRmRead, HRmWrite, HRmModify }
79 HRegMode;
80
81
82/* A struct for recording the usage of registers in instructions.
83 This can get quite large, but we don't expect to allocate them
84 dynamically, so there's no problem.
85*/
86#define N_HREG_USAGE 4
87
88typedef
89 struct {
90 HReg hreg[N_HREG_USAGE];
91 HRegMode mode[N_HREG_USAGE];
92 Int n_used;
93 }
94 HRegUsage;
95
96extern void ppHRegUsage ( FILE*, HRegUsage* );
97
98extern void initHRegUsage ( HRegUsage* );
99
100/* Add a register to a usage table. Combine incoming read uses with
101 existing write uses into a modify use, and vice versa. Do not
102 create duplicate entries -- each reg should only be mentioned once.
103*/
sewardj53f85a92004-07-02 13:45:17 +0000104extern void addHRegUse ( HRegUsage*, HRegMode, HReg );
sewardj8bc26ee2004-07-01 18:30:32 +0000105
106
107
108/*---------------------------------------------------------*/
109/*--- Indicating register remappings (for reg-alloc) ---*/
110/*---------------------------------------------------------*/
111
sewardj0ec33252004-07-03 13:30:00 +0000112/* Note that such maps can only map virtual regs to real regs.
113 addToHRegRenap will barf if given a pair not of that form. As a
114 result, no valid HRegRemap will bind a real reg to anything, and so
115 if lookupHRegMap is given a real reg, it returns it unchanged.
116 This is precisely the behaviour that the register allocator needs
117 to impose its decisions on the instructions it processes. */
118
sewardj8bc26ee2004-07-01 18:30:32 +0000119#define N_HREG_REMAP 4
120
121typedef
122 struct {
123 HReg orig [N_HREG_REMAP];
124 HReg replacement[N_HREG_REMAP];
125 Int n_used;
126 }
127 HRegRemap;
128
129extern void ppHRegRemap ( FILE*, HRegRemap* );
130extern void initHRegRemap ( HRegRemap* );
131extern void addToHRegRemap ( HRegRemap*, HReg, HReg );
132extern HReg lookupHRegRemap ( HRegRemap*, HReg );
133
sewardjc97096c2004-06-30 09:28:04 +0000134
sewardjaf5a5222004-07-01 23:14:42 +0000135/*---------------------------------------------------------*/
136/*--- Abstract instructions ---*/
137/*---------------------------------------------------------*/
138
139/* A type is needed to refer to pointers to instructions of any
140 target. Defining it like this means that HInstr* can stand in for
141 X86Instr*, ArmInstr*, etc. */
142
143typedef void HInstr;
144
145
sewardj2cd80dc2004-07-02 15:20:40 +0000146/* An expandable array of HInstr*'s. Handy for insn
147 selection and register allocation. */
148
149typedef
150 struct {
151 HInstr** arr;
152 Int arr_size;
153 Int arr_used;
154 }
155 HInstrArray;
156
157extern HInstrArray* newHInstrArray ( void );
158extern void deleteHInstrArray ( HInstrArray* );
159extern void addHInstr ( HInstrArray*, HInstr* );
160
sewardjaf5a5222004-07-01 23:14:42 +0000161
sewardjc97096c2004-06-30 09:28:04 +0000162#endif /* ndef __HOST_REGS_H */
sewardj8bc26ee2004-07-01 18:30:32 +0000163
sewardj2cd80dc2004-07-02 15:20:40 +0000164
165/*---------------------------------------------------------*/
166/*--- Reg alloc: TODO: move somewhere else ---*/
167/*---------------------------------------------------------*/
168
169extern
170HInstrArray* doRegisterAllocation (
171
172 /* Incoming virtual-registerised code. */
173 HInstrArray* instrs_in,
174 Int n_vregs,
175
176 /* An array listing all the real registers the allocator may use,
177 in no particular order. */
178 HReg* available_real_regs,
179 Int n_available_real_regs,
180
181 /* Return True iff the given insn is a reg-reg move, in which
182 case also return the src and dst regs. */
183 Bool (*isMove) (HInstr*, HReg*, HReg*),
184
185 /* Get info about register usage in this insn. */
186 void (*getRegUsage) (HRegUsage*, HInstr*),
187
188 /* Apply a reg-reg mapping to an insn. */
189 void (*mapRegs) (HRegRemap*, HInstr*),
190
191 /* Return an insn to spill/restore a real reg to a spill slot
192 offset. */
193 HInstr* (*genSpill) ( HReg, Int ),
194 HInstr* (*genReload) ( HReg, Int )
195);
196
197
198
sewardj8bc26ee2004-07-01 18:30:32 +0000199/*---------------------------------------------------------------*/
200/*--- host_regs.h ---*/
201/*---------------------------------------------------------------*/