blob: 7786b182ebb22f386f6d0eeb60b27562a898a546 [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;
30 assert(rc == HRcInt || rc == HRcFloat || rc == HRcVector);
sewardjc97096c2004-06-30 09:28:04 +000031 return (HRegClass)rc;
32}
33
34Bool hregIsVirtual ( HReg r )
35{
sewardjaf5a5222004-07-01 23:14:42 +000036 return (((UInt)r) & (1<<24)) ? True : False;
sewardjc97096c2004-06-30 09:28:04 +000037}
38
39UInt hregNumber ( HReg r )
40{
sewardjaf5a5222004-07-01 23:14:42 +000041 return ((UInt)r) & 0x00FFFFFF;
sewardjc97096c2004-06-30 09:28:04 +000042}
43
sewardjb3d4ce72004-07-02 07:09:23 +000044void ppHRegClass ( FILE* f, HRegClass hrc )
45{
46 switch (hrc) {
47 case HRcInt: fprintf(f, "HRcInt32"); break;
48 case HRcInt64: fprintf(f, "HRcInt64"); break;
49 case HRcFloat: fprintf(f, "HRcFloat"); break;
50 case HRcVector: fprintf(f, "HRcVector64"); break;
51 case HRcVector128: fprintf(f, "HRcVector128"); break;
52 default: panic("ppHRegClass");
53 }
54}
sewardjc97096c2004-06-30 09:28:04 +000055
56/* Generic printing for registers. */
57void ppHReg ( FILE* f, HReg r )
58{
59 Char* maybe_v = hregIsVirtual(r) ? "v" : "";
60 Int regNo = hregNumber(r);
61 switch (hregClass(r)) {
62 case HRcInt: fprintf(f, "%%%sr%d", maybe_v, regNo); return;
63 case HRcFloat: fprintf(f, "%%%sf%d", maybe_v, regNo); return;
64 case HRcVector: fprintf(f, "%%%sv%d", maybe_v, regNo); return;
65 default: panic("ppHReg");
66 }
67}
68
sewardj8bc26ee2004-07-01 18:30:32 +000069
70/*---------------------------------------------------------*/
71/*--- Helpers for recording reg usage (for reg-alloc) ---*/
72/*---------------------------------------------------------*/
73
74void ppHRegUsage ( FILE* f, HRegUsage* tab )
75{
76 Int i;
77 Char* str;
78 fprintf(f, "HRegUsage {\n");
79 for (i = 0; i < tab->n_used; i++) {
80 switch (tab->mode[i]) {
81 case HRmRead: str = "Read "; break;
82 case HRmWrite: str = "Write "; break;
83 case HRmModify: str = "Modify "; break;
84 default: panic("ppHRegUsage");
85 }
86 fprintf(f, " %s ", str);
87 ppHReg(f, tab->hreg[i]);
88 fprintf(f, "\n");
89 }
90 fprintf(f, "}\n");
91}
92
93
94void initHRegUsage ( HRegUsage* tab )
95{
96 tab->n_used = 0;
97}
98
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 +0000104void addHRegUse ( HRegUsage* tab, HRegMode mode, HReg reg )
sewardj8bc26ee2004-07-01 18:30:32 +0000105{
106 Int i;
107 /* Find it ... */
108 for (i = 0; i < tab->n_used; i++)
109 if (tab->hreg[i] == reg)
110 break;
111 if (i == tab->n_used) {
112 /* Not found, add new entry. */
113 assert(tab->n_used+1 < N_HREG_USAGE);
114 tab->hreg[tab->n_used] = reg;
115 tab->mode[tab->n_used] = mode;
116 tab->n_used++;
117 } else {
118 /* Found: combine or ignore. */
119 if (tab->mode[i] == mode)
120 return; /* duplicate, ignore */
121 if (mode == HRmModify) {
122 tab->mode[i] = HRmModify;
123 return; /* modify mode makes previous mode irrelevant */
124 }
125 assert( (mode == HRmRead && tab->mode[i] == HRmWrite)
126 || (mode == HRmWrite && tab->mode[i] == HRmRead) );
127 tab->mode[i] = HRmModify;
128 }
129}
130
131
132/*---------------------------------------------------------*/
133/*--- Indicating register remappings (for reg-alloc) ---*/
134/*---------------------------------------------------------*/
135
136void ppHRegRemap ( FILE* f, HRegRemap* map )
137{
138 Int i;
139 fprintf(f, "HRegRemap {\n");
140 for (i = 0; i < map->n_used; i++) {
141 fprintf(f, " ");
sewardjaf5a5222004-07-01 23:14:42 +0000142 ppHReg(f, map->orig[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000143 fprintf(f, " --> ");
sewardjaf5a5222004-07-01 23:14:42 +0000144 ppHReg(f, map->replacement[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000145 fprintf(f, "\n");
146 }
147 fprintf(f, "}\n");
148}
149
150
151void initHRegRemap ( HRegRemap* map )
152{
153 map->n_used = 0;
154}
155
156
157void addToHRegRemap ( HRegRemap* map, HReg orig, HReg replacement )
158{
159 Int i;
160 for (i = 0; i < map->n_used; i++)
161 if (map->orig[i] == orig)
162 panic("addToHRegMap: duplicate entry");
163 assert(map->n_used+1 < N_HREG_REMAP);
164 map->orig[map->n_used] = orig;
165 map->replacement[map->n_used] = replacement;
166 map->n_used++;
167}
168
169
170HReg lookupHRegRemap ( HRegRemap* map, HReg orig )
171{
172 Int i;
173 for (i = 0; i < map->n_used; i++)
174 if (map->orig[i] == orig)
175 return map->replacement[i];
176 panic("lookupHRegRemap: not found");
177}
178
sewardj2cd80dc2004-07-02 15:20:40 +0000179/*---------------------------------------------------------*/
180/*--- Abstract instructions ---*/
181/*---------------------------------------------------------*/
182
183HInstrArray* newHInstrArray ( void )
184{
185 HInstrArray* ha = malloc(sizeof(HInstrArray));
186 ha->arr_size = 4;
187 ha->arr_used = 0;
188 ha->arr = malloc(ha->arr_size * sizeof(HInstr*));
189 return ha;
190}
191
192void deleteHInstrArray ( HInstrArray* ha )
193{
194 free(ha->arr);
195 free(ha);
196}
197
198void addHInstr ( HInstrArray* ha, HInstr* instr )
199{
200 assert(ha->arr_used <= ha->arr_size);
201 if (ha->arr_used < ha->arr_size) {
202 ha->arr[ha->arr_used] = instr;
203 ha->arr_used++;
204 } else {
205 Int i;
206 HInstr** arr2 = malloc(ha->arr_size * 2 * sizeof(HInstr*));
207 for (i = 0; i < ha->arr_size; i++)
208 arr2[i] = ha->arr[i];
209 ha->arr_size *= 2;
210 free(ha->arr);
211 ha->arr = arr2;
212 addHInstr(ha, instr);
213 }
214}
215
216
sewardj8bc26ee2004-07-01 18:30:32 +0000217/*---------------------------------------------------------------*/
218/*--- host_regs.c ---*/
219/*---------------------------------------------------------------*/