blob: dfd22a3cdad2a3355329acf22fbb5b999dc60f58 [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>
10
11#include "basictypes.h"
12#include "host_regs.h"
13
14
15HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual )
16{
sewardjaf5a5222004-07-01 23:14:42 +000017 UInt r24 = regno & 0x00FFFFFF;
18 /* This is critical. The register number field may only
19 occupy 24 bits. */
20 if (r24 != regno)
21 panic("mkHReg: regno exceeds 2^24");
22 return regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0);
sewardjc97096c2004-06-30 09:28:04 +000023}
24
25HRegClass hregClass ( HReg r )
26{
sewardjaf5a5222004-07-01 23:14:42 +000027 UInt rc = r;
28 rc = (rc >> 28) & 0x0F;
29 assert(rc == HRcInt || rc == HRcFloat || rc == HRcVector);
sewardjc97096c2004-06-30 09:28:04 +000030 return (HRegClass)rc;
31}
32
33Bool hregIsVirtual ( HReg r )
34{
sewardjaf5a5222004-07-01 23:14:42 +000035 return (((UInt)r) & (1<<24)) ? True : False;
sewardjc97096c2004-06-30 09:28:04 +000036}
37
38UInt hregNumber ( HReg r )
39{
sewardjaf5a5222004-07-01 23:14:42 +000040 return ((UInt)r) & 0x00FFFFFF;
sewardjc97096c2004-06-30 09:28:04 +000041}
42
sewardjb3d4ce72004-07-02 07:09:23 +000043void ppHRegClass ( FILE* f, HRegClass hrc )
44{
45 switch (hrc) {
46 case HRcInt: fprintf(f, "HRcInt32"); break;
47 case HRcInt64: fprintf(f, "HRcInt64"); break;
48 case HRcFloat: fprintf(f, "HRcFloat"); break;
49 case HRcVector: fprintf(f, "HRcVector64"); break;
50 case HRcVector128: fprintf(f, "HRcVector128"); break;
51 default: panic("ppHRegClass");
52 }
53}
sewardjc97096c2004-06-30 09:28:04 +000054
55/* Generic printing for registers. */
56void ppHReg ( FILE* f, HReg r )
57{
58 Char* maybe_v = hregIsVirtual(r) ? "v" : "";
59 Int regNo = hregNumber(r);
60 switch (hregClass(r)) {
61 case HRcInt: fprintf(f, "%%%sr%d", maybe_v, regNo); return;
62 case HRcFloat: fprintf(f, "%%%sf%d", maybe_v, regNo); return;
63 case HRcVector: fprintf(f, "%%%sv%d", maybe_v, regNo); return;
64 default: panic("ppHReg");
65 }
66}
67
sewardj8bc26ee2004-07-01 18:30:32 +000068
69/*---------------------------------------------------------*/
70/*--- Helpers for recording reg usage (for reg-alloc) ---*/
71/*---------------------------------------------------------*/
72
73void ppHRegUsage ( FILE* f, HRegUsage* tab )
74{
75 Int i;
76 Char* str;
77 fprintf(f, "HRegUsage {\n");
78 for (i = 0; i < tab->n_used; i++) {
79 switch (tab->mode[i]) {
80 case HRmRead: str = "Read "; break;
81 case HRmWrite: str = "Write "; break;
82 case HRmModify: str = "Modify "; break;
83 default: panic("ppHRegUsage");
84 }
85 fprintf(f, " %s ", str);
86 ppHReg(f, tab->hreg[i]);
87 fprintf(f, "\n");
88 }
89 fprintf(f, "}\n");
90}
91
92
93void initHRegUsage ( HRegUsage* tab )
94{
95 tab->n_used = 0;
96}
97
98
99/* Add a register to a usage table. Combine incoming read uses with
100 existing write uses into a modify use, and vice versa. Do not
101 create duplicate entries -- each reg should only be mentioned once.
102*/
sewardj53f85a92004-07-02 13:45:17 +0000103void addHRegUse ( HRegUsage* tab, HRegMode mode, HReg reg )
sewardj8bc26ee2004-07-01 18:30:32 +0000104{
105 Int i;
106 /* Find it ... */
107 for (i = 0; i < tab->n_used; i++)
108 if (tab->hreg[i] == reg)
109 break;
110 if (i == tab->n_used) {
111 /* Not found, add new entry. */
112 assert(tab->n_used+1 < N_HREG_USAGE);
113 tab->hreg[tab->n_used] = reg;
114 tab->mode[tab->n_used] = mode;
115 tab->n_used++;
116 } else {
117 /* Found: combine or ignore. */
118 if (tab->mode[i] == mode)
119 return; /* duplicate, ignore */
120 if (mode == HRmModify) {
121 tab->mode[i] = HRmModify;
122 return; /* modify mode makes previous mode irrelevant */
123 }
124 assert( (mode == HRmRead && tab->mode[i] == HRmWrite)
125 || (mode == HRmWrite && tab->mode[i] == HRmRead) );
126 tab->mode[i] = HRmModify;
127 }
128}
129
130
131/*---------------------------------------------------------*/
132/*--- Indicating register remappings (for reg-alloc) ---*/
133/*---------------------------------------------------------*/
134
135void ppHRegRemap ( FILE* f, HRegRemap* map )
136{
137 Int i;
138 fprintf(f, "HRegRemap {\n");
139 for (i = 0; i < map->n_used; i++) {
140 fprintf(f, " ");
sewardjaf5a5222004-07-01 23:14:42 +0000141 ppHReg(f, map->orig[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000142 fprintf(f, " --> ");
sewardjaf5a5222004-07-01 23:14:42 +0000143 ppHReg(f, map->replacement[i]);
sewardj8bc26ee2004-07-01 18:30:32 +0000144 fprintf(f, "\n");
145 }
146 fprintf(f, "}\n");
147}
148
149
150void initHRegRemap ( HRegRemap* map )
151{
152 map->n_used = 0;
153}
154
155
156void addToHRegRemap ( HRegRemap* map, HReg orig, HReg replacement )
157{
158 Int i;
159 for (i = 0; i < map->n_used; i++)
160 if (map->orig[i] == orig)
161 panic("addToHRegMap: duplicate entry");
162 assert(map->n_used+1 < N_HREG_REMAP);
163 map->orig[map->n_used] = orig;
164 map->replacement[map->n_used] = replacement;
165 map->n_used++;
166}
167
168
169HReg lookupHRegRemap ( HRegRemap* map, HReg orig )
170{
171 Int i;
172 for (i = 0; i < map->n_used; i++)
173 if (map->orig[i] == orig)
174 return map->replacement[i];
175 panic("lookupHRegRemap: not found");
176}
177
178/*---------------------------------------------------------------*/
179/*--- host_regs.c ---*/
180/*---------------------------------------------------------------*/