blob: 3e3d1d688ad4b1ee688d1ac43ac875d638605299 [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
4/*--- This file (host_regs.c) is ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
9#include <stdio.h>
sewardj2cd80dc2004-07-02 15:20:40 +000010#include <malloc.h>
sewardjc97096c2004-06-30 09:28:04 +000011
12#include "basictypes.h"
13#include "host_regs.h"
14
15
16HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual )
17{
sewardjaf5a5222004-07-01 23:14:42 +000018 UInt r24 = regno & 0x00FFFFFF;
19 /* This is critical. The register number field may only
20 occupy 24 bits. */
21 if (r24 != regno)
22 panic("mkHReg: regno exceeds 2^24");
23 return regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0);
sewardjc97096c2004-06-30 09:28:04 +000024}
25
26HRegClass hregClass ( HReg r )
27{
sewardjaf5a5222004-07-01 23:14:42 +000028 UInt rc = r;
29 rc = (rc >> 28) & 0x0F;
sewardj6f37cce2004-07-03 19:44:54 +000030 assert(rc == HRcInt || rc == HRcFloat || rc == HRcVector
31 || rc == HRcInt64 || rc == HRcVector128);
sewardjc97096c2004-06-30 09:28:04 +000032 return (HRegClass)rc;
33}
34
35Bool hregIsVirtual ( HReg r )
36{
sewardjaf5a5222004-07-01 23:14:42 +000037 return (((UInt)r) & (1<<24)) ? True : False;
sewardjc97096c2004-06-30 09:28:04 +000038}
39
40UInt hregNumber ( HReg r )
41{
sewardjaf5a5222004-07-01 23:14:42 +000042 return ((UInt)r) & 0x00FFFFFF;
sewardjc97096c2004-06-30 09:28:04 +000043}
44
sewardjb3d4ce72004-07-02 07:09:23 +000045void ppHRegClass ( FILE* f, HRegClass hrc )
46{
47 switch (hrc) {
48 case HRcInt: fprintf(f, "HRcInt32"); break;
49 case HRcInt64: fprintf(f, "HRcInt64"); break;
50 case HRcFloat: fprintf(f, "HRcFloat"); break;
51 case HRcVector: fprintf(f, "HRcVector64"); break;
52 case HRcVector128: fprintf(f, "HRcVector128"); break;
53 default: panic("ppHRegClass");
54 }
55}
sewardjc97096c2004-06-30 09:28:04 +000056
57/* Generic printing for registers. */
58void ppHReg ( FILE* f, HReg r )
59{
60 Char* maybe_v = hregIsVirtual(r) ? "v" : "";
61 Int regNo = hregNumber(r);
62 switch (hregClass(r)) {
sewardj6f37cce2004-07-03 19:44:54 +000063 case HRcInt: fprintf(f, "%%%sr%d", maybe_v, regNo); return;
64 case HRcInt64: fprintf(f, "%%%sR%d", maybe_v, regNo); return;
65 case HRcFloat: fprintf(f, "%%%sf%d", maybe_v, regNo); return;
66 case HRcVector: fprintf(f, "%%%sv%d", maybe_v, regNo); return;
67 case HRcVector128: fprintf(f, "%%%sV%d", maybe_v, regNo); return;
sewardjc97096c2004-06-30 09:28:04 +000068 default: panic("ppHReg");
69 }
70}
71
sewardj8bc26ee2004-07-01 18:30:32 +000072
73/*---------------------------------------------------------*/
74/*--- Helpers for recording reg usage (for reg-alloc) ---*/
75/*---------------------------------------------------------*/
76
77void ppHRegUsage ( FILE* f, HRegUsage* tab )
78{
79 Int i;
80 Char* str;
81 fprintf(f, "HRegUsage {\n");
82 for (i = 0; i < tab->n_used; i++) {
83 switch (tab->mode[i]) {
84 case HRmRead: str = "Read "; break;
85 case HRmWrite: str = "Write "; break;
86 case HRmModify: str = "Modify "; break;
87 default: panic("ppHRegUsage");
88 }
89 fprintf(f, " %s ", str);
90 ppHReg(f, tab->hreg[i]);
91 fprintf(f, "\n");
92 }
93 fprintf(f, "}\n");
94}
95
96
97void initHRegUsage ( HRegUsage* tab )
98{
99 tab->n_used = 0;
100}
101
102
103/* Add a register to a usage table. Combine incoming read uses with
104 existing write uses into a modify use, and vice versa. Do not
105 create duplicate entries -- each reg should only be mentioned once.
106*/
sewardj53f85a92004-07-02 13:45:17 +0000107void addHRegUse ( HRegUsage* tab, HRegMode mode, HReg reg )
sewardj8bc26ee2004-07-01 18:30:32 +0000108{
109 Int i;
110 /* Find it ... */
111 for (i = 0; i < tab->n_used; i++)
112 if (tab->hreg[i] == reg)
113 break;
114 if (i == tab->n_used) {
115 /* Not found, add new entry. */
116 assert(tab->n_used+1 < N_HREG_USAGE);
117 tab->hreg[tab->n_used] = reg;
118 tab->mode[tab->n_used] = mode;
119 tab->n_used++;
120 } else {
121 /* Found: combine or ignore. */
122 if (tab->mode[i] == mode)
123 return; /* duplicate, ignore */
124 if (mode == HRmModify) {
125 tab->mode[i] = HRmModify;
126 return; /* modify mode makes previous mode irrelevant */
127 }
128 assert( (mode == HRmRead && tab->mode[i] == HRmWrite)
129 || (mode == HRmWrite && tab->mode[i] == HRmRead) );
130 tab->mode[i] = HRmModify;
131 }
132}
133
134
135/*---------------------------------------------------------*/
136/*--- Indicating register remappings (for reg-alloc) ---*/
137/*---------------------------------------------------------*/
138
139void ppHRegRemap ( FILE* f, HRegRemap* map )
140{
141 Int i;
142 fprintf(f, "HRegRemap {\n");
143 for (i = 0; i < map->n_used; i++) {
144 fprintf(f, " ");
sewardjaf5a5222004-07-01 23:14:42 +0000145 ppHReg(f, map->orig[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000146 fprintf(f, " --> ");
sewardjaf5a5222004-07-01 23:14:42 +0000147 ppHReg(f, map->replacement[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000148 fprintf(f, "\n");
149 }
150 fprintf(f, "}\n");
151}
152
153
154void initHRegRemap ( HRegRemap* map )
155{
156 map->n_used = 0;
157}
158
159
160void addToHRegRemap ( HRegRemap* map, HReg orig, HReg replacement )
161{
162 Int i;
163 for (i = 0; i < map->n_used; i++)
164 if (map->orig[i] == orig)
165 panic("addToHRegMap: duplicate entry");
sewardj0ec33252004-07-03 13:30:00 +0000166 if (!hregIsVirtual(orig))
167 panic("addToHRegMap: orig is not a vreg");
168 if (hregIsVirtual(replacement))
169 panic("addToHRegMap: replacement is not a vreg");
170
sewardj8bc26ee2004-07-01 18:30:32 +0000171 assert(map->n_used+1 < N_HREG_REMAP);
172 map->orig[map->n_used] = orig;
173 map->replacement[map->n_used] = replacement;
174 map->n_used++;
175}
176
177
178HReg lookupHRegRemap ( HRegRemap* map, HReg orig )
179{
180 Int i;
sewardj0ec33252004-07-03 13:30:00 +0000181 if (!hregIsVirtual(orig))
182 return orig;
sewardj8bc26ee2004-07-01 18:30:32 +0000183 for (i = 0; i < map->n_used; i++)
184 if (map->orig[i] == orig)
185 return map->replacement[i];
186 panic("lookupHRegRemap: not found");
187}
188
sewardj2cd80dc2004-07-02 15:20:40 +0000189/*---------------------------------------------------------*/
190/*--- Abstract instructions ---*/
191/*---------------------------------------------------------*/
192
193HInstrArray* newHInstrArray ( void )
194{
195 HInstrArray* ha = malloc(sizeof(HInstrArray));
196 ha->arr_size = 4;
197 ha->arr_used = 0;
sewardj194d54a2004-07-03 19:08:18 +0000198 ha->arr = malloc(ha->arr_size * sizeof(HInstr*));
199 ha->n_vregs = 0;
sewardj2cd80dc2004-07-02 15:20:40 +0000200 return ha;
201}
202
203void deleteHInstrArray ( HInstrArray* ha )
204{
205 free(ha->arr);
206 free(ha);
207}
208
209void addHInstr ( HInstrArray* ha, HInstr* instr )
210{
211 assert(ha->arr_used <= ha->arr_size);
212 if (ha->arr_used < ha->arr_size) {
213 ha->arr[ha->arr_used] = instr;
214 ha->arr_used++;
215 } else {
216 Int i;
217 HInstr** arr2 = malloc(ha->arr_size * 2 * sizeof(HInstr*));
218 for (i = 0; i < ha->arr_size; i++)
219 arr2[i] = ha->arr[i];
220 ha->arr_size *= 2;
221 free(ha->arr);
222 ha->arr = arr2;
223 addHInstr(ha, instr);
224 }
225}
226
227
sewardj8bc26ee2004-07-01 18:30:32 +0000228/*---------------------------------------------------------------*/
229/*--- host_regs.c ---*/
230/*---------------------------------------------------------------*/