Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: sparcccgen.c | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | /* | |
24 | * Sparc condition code operations are nasty ... | |
25 | * Ideally we want a fast mechanism to determine if a conditional | |
26 | * operation is true or not based on the condition codes. | |
27 | * Except that the condition expressions dont well match | |
28 | * the condition code flags. | |
29 | * | |
30 | * Now we have a 4 bit condition expression and a 4 bit condition | |
31 | * code register, so we could combine to form an index for a 256 | |
32 | * bit array of true and false ... except that the cond expression | |
33 | * is always encoded in the instruction ... | |
34 | * | |
35 | * For now we use the cond expression, as an index into a table of | |
36 | * 16bit words. The cond code register selects a bit from this | |
37 | * the result of which is true or false ... | |
38 | * | |
39 | * This code mechanically builds those 16bit words to be indexed | |
40 | * by the condition code register value. | |
41 | */ | |
42 | ||
43 | #include <ctype.h> /* for islower / toupper */ | |
44 | #include <errno.h> | |
45 | #include <stdarg.h> | |
46 | #include <stdio.h> | |
47 | #include <stdlib.h> | |
48 | #include <string.h> /* for strchr */ | |
49 | #include <sys/param.h> /* for MAXPATHLEN */ | |
50 | #include <sys/types.h> | |
51 | #include <unistd.h> | |
52 | ||
53 | #include "hostcpu.h" | |
54 | ||
55 | ||
56 | void fatal(char* fmt, ...); | |
57 | void strcasecpy(char * top, char * fromp); | |
58 | ||
59 | typedef enum { | |
60 | cond_a = 0x8, | |
61 | cond_n = 0x0, | |
62 | cond_ne = 0x9, | |
63 | cond_e = 0x1, | |
64 | cond_g = 0xA, | |
65 | cond_le = 0x2, | |
66 | cond_ge = 0xB, | |
67 | cond_l = 0x3, | |
68 | cond_gu = 0xC, | |
69 | cond_leu = 0x4, | |
70 | cond_cc = 0xD, | |
71 | cond_cs = 0x5, | |
72 | cond_pos = 0xE, | |
73 | cond_neg = 0x6, | |
74 | cond_vc = 0xF, | |
75 | cond_vs = 0x7 | |
76 | } cond_type_t; | |
77 | ||
78 | ||
79 | ||
80 | ||
81 | typedef enum { | |
82 | cc_bit_c = 0x1, | |
83 | cc_bit_v = 0x2, | |
84 | cc_bit_z = 0x4, | |
85 | cc_bit_n = 0x8 | |
86 | } cc_bit_t; | |
87 | ||
88 | ||
89 | void | |
90 | gencodes(FILE * fp) | |
91 | { | |
92 | int cond, ccr; | |
93 | ||
94 | ||
95 | for (cond=0; cond<16; cond++) { | |
96 | uint16_t mask; | |
97 | ||
98 | mask = 0; | |
99 | for (ccr=0; ccr<16; ccr++) { | |
100 | ||
101 | switch (cond) { | |
102 | case cond_a: | |
103 | goto set_bit; | |
104 | case cond_n: | |
105 | goto clear_bit; | |
106 | case cond_ne: | |
107 | if (!(ccr & cc_bit_z)) goto set_bit; | |
108 | goto clear_bit; | |
109 | case cond_e: | |
110 | if (ccr & cc_bit_z) goto set_bit; | |
111 | goto clear_bit; | |
112 | case cond_g: | |
113 | if ( !( (ccr&cc_bit_z) || (((ccr>>2)^ccr)&cc_bit_v) ) ) goto set_bit; | |
114 | goto clear_bit; | |
115 | case cond_le: | |
116 | if ( (ccr&cc_bit_z) || (((ccr>>2)^ccr)&cc_bit_v) ) goto set_bit; | |
117 | goto clear_bit; | |
118 | case cond_ge: | |
119 | if (!( ((ccr>>2)^ccr)&cc_bit_v )) goto set_bit; | |
120 | goto clear_bit; | |
121 | case cond_l: | |
122 | if ( ((ccr>>2)^ccr)&cc_bit_v ) goto set_bit; | |
123 | goto clear_bit; | |
124 | case cond_gu: | |
125 | if (!((ccr & cc_bit_c) || (ccr & cc_bit_z))) goto set_bit; | |
126 | goto clear_bit; | |
127 | case cond_leu: | |
128 | if ((ccr & cc_bit_c) || (ccr & cc_bit_z)) goto set_bit; | |
129 | goto clear_bit; | |
130 | case cond_cc: | |
131 | if (!(ccr & cc_bit_c)) goto set_bit; | |
132 | goto clear_bit; | |
133 | case cond_cs: | |
134 | if (ccr & cc_bit_c) goto set_bit; | |
135 | goto clear_bit; | |
136 | case cond_pos: | |
137 | if (!(ccr & cc_bit_n)) goto set_bit; | |
138 | goto clear_bit; | |
139 | case cond_neg: | |
140 | if (ccr & cc_bit_n) goto set_bit; | |
141 | goto clear_bit; | |
142 | case cond_vc: | |
143 | if (!(ccr & cc_bit_v)) goto set_bit; | |
144 | goto clear_bit; | |
145 | case cond_vs: | |
146 | if (ccr & cc_bit_v) goto set_bit; | |
147 | goto clear_bit; | |
148 | default: | |
149 | abort(); | |
150 | } | |
151 | set_bit:; | |
152 | mask |= 1<<ccr; | |
153 | clear_bit:; | |
154 | } | |
155 | fprintf(fp, "\t0x%04lx%s\n", (uint32_t)mask, cond!=15 ? "," : ""); | |
156 | } | |
157 | } | |
158 | ||
159 | ||
160 | ||
161 | ||
162 | int main(int argc, char ** argv) | |
163 | { | |
164 | #define MAXBUF 1024 | |
165 | char bufp[MAXPATHLEN]; | |
166 | char caps[MAXPATHLEN]; | |
167 | char * bnamep; | |
168 | FILE * dotc, * doth; | |
169 | char * basenamep; | |
170 | char * structnamep; | |
171 | char * specfilep; | |
172 | ||
173 | if (argc != 3) fatal("usage: %s <basefilename> <basestructname>\n", | |
174 | argv[0]); | |
175 | ||
176 | basenamep = argv[1]; | |
177 | structnamep = argv[2]; | |
178 | if (strlen(structnamep)>MAXBUF-100) fatal("basestructname is too long!"); | |
179 | ||
180 | /* Initialise the .h and .c files */ | |
181 | ||
182 | sprintf(bufp, "%s.c", basenamep); | |
183 | dotc = fopen(bufp, "w"); | |
184 | if (dotc == NULL) fatal("creating %s", bufp); | |
185 | ||
186 | sprintf(bufp, "%s.h", basenamep); | |
187 | doth = fopen(bufp, "w"); | |
188 | if (doth == NULL) fatal("creating %s", bufp); | |
189 | ||
190 | /* remove any earlier path ... */ | |
191 | bnamep = strrchr(basenamep, '/'); | |
192 | if (bnamep == (char*)0) | |
193 | bnamep = basenamep; | |
194 | else | |
195 | bnamep ++; | |
196 | ||
197 | strcasecpy(caps, bnamep); | |
198 | ||
199 | ||
200 | fprintf(dotc,"\ | |
201 | /* Autogenerated file - DO NOT EDIT */\n\ | |
202 | #include \"basics.h\"\n\ | |
203 | #include \"%s.h\"\n\ | |
204 | \n\ | |
205 | uint16_t %s[16]={\n", bnamep, structnamep); | |
206 | gencodes(dotc); | |
207 | fprintf(dotc,"\ | |
208 | };\n\ | |
209 | \n\ | |
210 | \n", bnamep, structnamep); | |
211 | ||
212 | fclose(dotc); | |
213 | ||
214 | fprintf(doth,"\ | |
215 | #ifndef _%s_H_\n\ | |
216 | #define _%s_H_\n\ | |
217 | \n\ | |
218 | extern uint16_t %s[];\n\ | |
219 | \n\ | |
220 | #endif\n", caps, caps, structnamep); | |
221 | ||
222 | fclose(doth); | |
223 | exit(0); | |
224 | ||
225 | return 0; /* compiler joy */ | |
226 | } | |
227 | ||
228 | ||
229 | ||
230 | ||
231 | ||
232 | void fatal(char* fmt, ...) | |
233 | { | |
234 | va_list args; | |
235 | ||
236 | if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: "); | |
237 | if (fmt) { | |
238 | va_start(args, fmt); | |
239 | (void)vfprintf(stderr, fmt, args); | |
240 | ||
241 | va_end(args); | |
242 | } | |
243 | ||
244 | fprintf(stderr,"\n"); | |
245 | fflush(stderr); | |
246 | fflush(stdout); | |
247 | ||
248 | exit(1); | |
249 | } | |
250 | ||
251 | ||
252 | ||
253 | ||
254 | void strcasecpy(char * top, char * fromp) | |
255 | { | |
256 | do { | |
257 | *top++ = islower((unsigned)*fromp) ? toupper((unsigned)*fromp) : *fromp; | |
258 | } while (*fromp++ != '\0'); | |
259 | } | |
260 | ||
261 |