/[gxemul]/upstream/0.4.2/src/cpus/generate_arm_r.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.4.2/src/cpus/generate_arm_r.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 9841 byte(s)
0.4.2
1 /*
2 * Copyright (C) 2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: generate_arm_r.c,v 1.5 2005/12/26 14:14:27 debug Exp $
29 *
30 * Generate functions for computing "reg" operands.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35
36
37 void sync_pc(void)
38 {
39 printf("\tuint32_t tmp, low_pc = ((size_t)ic - (size_t)\n"
40 "\t cpu->cd.arm.cur_ic_page)/sizeof(struct arm_instr_call);\n");
41 printf("\ttmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<\n"
42 "\t ARM_INSTR_ALIGNMENT_SHIFT);\n");
43 printf("\ttmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;\n");
44 }
45
46
47 void f(int s, int func, int only_name)
48 {
49 int rm = func & 15;
50 int c = (func >> 7) & 31;
51 int t = (func >> 4) & 7;
52 char name[200];
53 int pc = rm == 15, rc = c >> 1;
54
55 snprintf(name, sizeof(name), "arm_r%s_r%i_t%i_c%i", s? "s" : "",
56 rm, t, c);
57 if (only_name) {
58 printf("%s", name);
59 return;
60 }
61
62 printf("uint32_t %s(struct cpu *cpu, struct arm_instr_call *ic)"
63 " {\n", name);
64 if (pc)
65 sync_pc();
66
67 switch (t) {
68
69 case 0: /* lsl c (Logical Shift Left by constant) */
70 if (s) {
71 printf("{ uint32_t x = ");
72 if (pc)
73 printf("tmp");
74 else
75 printf("cpu->cd.arm.r[%i]", rm);
76 printf(";\n");
77 if (c != 0) {
78 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
79 printf("if (x & 0x%x)\n"
80 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
81 (int)(0x80000000 >> (c-1)));
82 printf("x <<= %i;\n", c);
83 }
84 printf(" return x; }\n");
85 } else {
86 if (pc)
87 printf("\treturn tmp");
88 else
89 printf("\treturn cpu->cd.arm.r[%i]", rm);
90 if (c != 0)
91 printf(" << %i", c);
92 printf(";\n");
93 }
94 break;
95
96 case 1: /* lsl Rc (Logical Shift Left by register) */
97 if (s) {
98 printf("{ uint32_t x = ");
99 if (pc)
100 printf("tmp");
101 else
102 printf("cpu->cd.arm.r[%i]", rm);
103 printf(";\n");
104 printf(" uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc);
105 printf(" if (y != 0) {\n");
106 printf(" cpu->cd.arm.flags &= ~ARM_F_C;\n");
107 printf(" if (y >= 32) return 0;\n");
108 printf(" x <<= (y - 1);\n");
109 printf(" if (x & 0x80000000)\n"
110 "\tcpu->cd.arm.flags |= ARM_F_C;\n");
111 printf(" x <<= 1;\n");
112 printf(" }\n");
113 printf(" return x; }\n");
114 } else {
115 printf("{ uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc);
116 printf(" uint32_t x =");
117 if (pc)
118 printf("tmp");
119 else
120 printf("cpu->cd.arm.r[%i]", rm);
121 printf(";\n");
122 printf("if (y > 31) return 0; else x <<= y;\n");
123 printf("return x; }\n");
124 }
125 break;
126
127 case 2: /* lsr c (Logical Shift Right by constant) */
128 /* 1..32 */
129 if (s) {
130 printf("{ uint32_t x = ");
131 if (pc)
132 printf("tmp");
133 else
134 printf("cpu->cd.arm.r[%i]", rm);
135 printf(";\n");
136 if (c == 0)
137 c = 32;
138 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
139 printf("if (x & 0x%x)\n"
140 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
141 (int)(1 << (c-1)));
142 if (c == 32)
143 printf("x = 0;\n");
144 else
145 printf("x >>= %i;\n", c);
146 printf(" return x; }\n");
147 } else {
148 if (c == 0)
149 printf("\treturn 0;\n");
150 else {
151 if (pc)
152 printf("\treturn tmp");
153 else
154 printf("\treturn cpu->cd.arm.r[%i]",rm);
155 printf(" >> %i;\n", c);
156 }
157 }
158 break;
159
160 case 3: /* lsr Rc (Logical Shift Right by register) */
161 if (s) {
162 printf("{ uint32_t x = ");
163 if (pc)
164 printf("tmp");
165 else
166 printf("cpu->cd.arm.r[%i]", rm);
167 printf(",y=cpu->cd.arm.r[%i]&255;\n", rc);
168 printf("if(y==0) return x;\n");
169 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
170 printf("if(y>31) y=32;\n");
171 printf("y--; x >>= y;\n");
172 printf("if (x & 1) "
173 "cpu->cd.arm.flags |= ARM_F_C;\n");
174 printf(" return x >> 1; }\n");
175 } else {
176 printf("{ uint32_t y=cpu->cd.arm.r[%i]&255;\n", rc);
177 printf("uint32_t x=");
178 if (pc)
179 printf("tmp");
180 else
181 printf("cpu->cd.arm.r[%i]",rm);
182 printf("; ");
183 printf("if (y>=32) return 0;\n");
184 printf("return x >> y; } ");
185 }
186 break;
187
188 case 4: /* asr c (Arithmetic Shift Right by constant) */
189 /* 1..32 */
190 if (s) {
191 printf("{ int32_t x = ");
192 if (pc)
193 printf("tmp");
194 else
195 printf("cpu->cd.arm.r[%i]", rm);
196 printf(";\n");
197 if (c == 0)
198 c = 32;
199 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
200 printf("if (x & 0x%x)\n"
201 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
202 (int)(1 << (c-1)));
203 if (c == 32)
204 printf("x = (x<0)? 0xffffffff : 0;\n");
205 else
206 printf("x >>= %i;\n", c);
207 printf(" return x; }\n");
208 } else {
209 if (c == 0) {
210 printf("\treturn ");
211 if (pc)
212 printf("tmp");
213 else
214 printf("cpu->cd.arm.r[%i]",rm);
215 printf(" & 0x80000000? 0xffffffff : 0;\n");
216 } else {
217 printf("return (int32_t)");
218 if (pc)
219 printf("tmp");
220 else
221 printf("cpu->cd.arm.r[%i]",rm);
222 printf(" >> %i;\n", c);
223 }
224 }
225 break;
226
227 case 5: /* asr Rc (Arithmetic Shift Right by register) */
228 if (s) {
229 printf("{ int32_t x = ");
230 if (pc)
231 printf("tmp");
232 else
233 printf("cpu->cd.arm.r[%i]", rm);
234 printf(",y=cpu->cd.arm.r[%i]&255;\n", rc);
235 printf("if(y==0) return x;\n");
236 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
237 printf("if(y>31) y=31;\n");
238 printf("y--; x >>= y;\n");
239 printf("if (x & 1) "
240 "cpu->cd.arm.flags |= ARM_F_C;\n");
241 printf(" return (int32_t)x >> 1; }\n");
242 } else {
243 printf("{ int32_t y=cpu->cd.arm.r[%i]&255;\n", rc);
244 printf("int32_t x=");
245 if (pc)
246 printf("tmp");
247 else
248 printf("cpu->cd.arm.r[%i]",rm);
249 printf("; ");
250 printf("if (y>=31) return (x<0)?0xffffffff:0;\n");
251 printf("return (int32_t)x >> y; } ");
252 }
253 break;
254
255 case 6: /* ror c OR rrx (Arithmetic Shift Right by constant) */
256 /* 0=rrx, 1..31=ror */
257 if (c == 0) {
258 printf("{ uint64_t x=");
259 if (pc)
260 printf("tmp");
261 else
262 printf("cpu->cd.arm.r[%i]",rm);
263 printf("; if (cpu->cd.arm.flags & ARM_F_C)"
264 " x |= 0x100000000ULL;");
265 if (s) {
266 printf("cpu->cd.arm.flags &= ~ARM_F_C;"
267 "if(x&1) cpu->cd.arm.flags |= "
268 "ARM_F_C;");
269 }
270 printf("return x >> 1; }\n");
271 } else if (s) {
272 printf("{ uint64_t x = ");
273 if (pc)
274 printf("tmp");
275 else
276 printf("cpu->cd.arm.r[%i]", rm);
277 printf("; x |= (x << 32);\n");
278 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
279 printf("if (x & 0x%x)\n"
280 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
281 (int)(1 << (c-1)));
282 printf(" return x >> %i; }\n", c);
283 } else {
284 printf("{ uint64_t x=");
285 if (pc)
286 printf("tmp");
287 else
288 printf("cpu->cd.arm.r[%i]",rm);
289 printf("; x |= (x << 32); ");
290 printf("return x >> %i; }\n", c);
291 }
292 break;
293
294 case 7: /* ror Rc (Rotate Right by register) */
295 if (s) {
296 printf("{ uint64_t x = ");
297 if (pc)
298 printf("tmp");
299 else
300 printf("cpu->cd.arm.r[%i]", rm);
301 printf("; int y=cpu->cd.arm.r[%i]&255;\n", rc);
302 printf("if(y==0) return x;\n");
303 printf("y --; y &= 31; x >>= y;\n");
304 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
305 printf("if (x & 1) "
306 "cpu->cd.arm.flags |= ARM_F_C;\n");
307 printf(" return x >> 1; }\n");
308 } else {
309 printf("{ int y=cpu->cd.arm.r[%i]&31;\n", rc);
310 printf("uint64_t x=");
311 if (pc)
312 printf("tmp");
313 else
314 printf("cpu->cd.arm.r[%i]",rm);
315 printf("; x |= (x << 32); ");
316 printf("return (x >> y); } ");
317 }
318 break;
319
320 default:
321 printf("\tprintf(\"%s\\n\");\n", name);
322 printf("\texit(1); /* TODO */\n\treturn 0;\n");
323 }
324
325 printf("}\n");
326 }
327
328
329 int main(int argc, char *argv[])
330 {
331 int s, func, f_start, f_end;
332
333 if (argc < 3) {
334 fprintf(stderr, "usage: %s start end\n", argv[0]);
335 exit(1);
336 }
337
338 f_start = strtol(argv[1], NULL, 0);
339 f_end = strtol(argv[2], NULL, 0);
340
341 printf("/*\n * DO NOT EDIT! AUTOMATICALLY GENERATED!\n */\n\n");
342 printf("#include <stdio.h>\n");
343 printf("#include <stdlib.h>\n");
344 printf("#include \"cpu.h\"\n");
345 printf("#include \"misc.h\"\n");
346 printf("\n\n");
347
348 if (f_start != 0 || f_end != 0) {
349 for (s=0; s<=1; s++)
350 for (func=f_start; func<=f_end; func++)
351 f(s, func, 0);
352 } else {
353 for (s=0; s<=1; s++)
354 for (func=0; func<=0xfff; func++) {
355 printf("extern uint32_t ");
356 f(s, func, 1);
357 printf("(struct cpu *, struct arm_"
358 "instr_call *);\n");
359 }
360
361 printf("\nuint32_t (*arm_r[8192])(struct cpu *,"
362 " struct arm_instr_call *) = {\n");
363 for (s=0; s<=1; s++)
364 for (func=0; func<=0xfff; func++) {
365 printf("\t");
366 f(s, func, 1);
367 if (s!=1 || func!=0xfff)
368 printf(",");
369 printf("\n");
370 }
371 printf("};\n\n");
372 }
373
374 return 0;
375 }
376

  ViewVC Help
Powered by ViewVC 1.1.26