/[gxemul]/trunk/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

Annotation of /trunk/src/cpus/generate_arm_r.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (hide annotations)
Mon Oct 8 16:19:01 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 11404 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.988 2005/10/11 03:53:57 debug Exp $

==============  RELEASE 0.3.6  ==============

20051008	The bug was not because of faulty ARM documentation after all,
		but it was related to those parts of the code.
		Fixing the RTC (dev_mc146818) to work with CATS.
20051009	Rewriting the R() function; now there are 8192 automatically
		generated smaller functions doing the same thing, but hopefully
		faster. This also fixes some bugs which were triggered when
		trying to compile GXemul inside itself. :-)
		Adding a dummy dev_lpt.
20051010	Small hack to not update virtual translation tables if memory
		accesses are done with the NO_EXCEPTION flag; a time reduction
		of almost a factor 2 for a full NetBSD/cats install. :-)
20051011	Passing -A as the default boot arg for CATS (works fine with
		OpenBSD/cats).

==============  RELEASE 0.3.6.1  ==============


1 dpavlin 16 /*
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.1 2005/10/09 21:32:07 debug Exp $
29     *
30     * Generate functions for computing "reg" operands.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35    
36    
37     #if 0
38     /*
39     * update_c is set if the C flag should be updated with the last shifted/
40     * rotated bit.
41     */
42     uint32_t R(struct cpu *cpu, struct arm_instr_call *ic,
43     uint32_t iword, int update_c)
44     {
45     int rm = iword & 15, lastbit, t, c;
46     uint32_t tmp = cpu->cd.arm.r[rm];
47    
48     case 2: /* lsr #c (c = 1..32) */
49     if (c == 0)
50     c = 32;
51     if (update_c) {
52     lastbit = ((uint64_t)tmp >> (c-1)) & 1;
53     }
54     tmp = (uint64_t)tmp >> c;
55     break;
56     case 3: /* lsr Rc */
57     c = cpu->cd.arm.r[c >> 1] & 255;
58     if (c >= 32)
59     c = 33;
60     if (update_c) {
61     if (c == 0)
62     update_c = 0;
63     else
64     lastbit = ((uint64_t)tmp >> (c-1)) & 1;
65     }
66     tmp = (uint64_t)tmp >> c;
67     break;
68     case 4: /* asr #c (c = 1..32) */
69     if (c == 0)
70     c = 32;
71     if (update_c) {
72     lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1;
73     }
74     tmp = (int64_t)(int32_t)tmp >> c;
75     break;
76     case 5: /* asr Rc */
77     c = cpu->cd.arm.r[c >> 1] & 255;
78     if (c >= 32)
79     c = 33;
80     if (update_c) {
81     if (c == 0)
82     update_c = 0;
83     else
84     lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1;
85     }
86     tmp = (int64_t)(int32_t)tmp >> c;
87     break;
88     case 6: /* ror 1..31 */
89     if (c == 0) {
90     fatal("TODO: rrx\n");
91     exit(1);
92     }
93     if (update_c)
94     lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1;
95     tmp = (uint64_t)(((uint64_t)tmp << 32) | tmp) >> c;
96     break;
97     case 7: /* ror Rc */
98     c = cpu->cd.arm.r[c >> 1] & 255;
99     if (update_c) {
100     if (c == 0)
101     update_c = 0;
102     else {
103     c &= 31;
104     if (c == 0)
105     lastbit = tmp & 0x80000000;
106     else
107     lastbit = ((int64_t)(int32_t)tmp
108     >> (c-1)) & 1;
109     tmp = (uint64_t)(((uint64_t)tmp << 32)
110     | tmp) >> c;
111     }
112     }
113     break;
114     }
115     if (update_c) {
116     cpu->cd.arm.cpsr &= ~ARM_FLAG_C;
117     if (lastbit)
118     cpu->cd.arm.cpsr |= ARM_FLAG_C;
119     }
120     return tmp;
121     }
122     #endif
123    
124    
125     void sync_pc(void)
126     {
127     printf("\tuint32_t tmp, low_pc = ((size_t)ic - (size_t)\n"
128     "\t cpu->cd.arm.cur_ic_page)/sizeof(struct arm_instr_call);\n");
129     printf("\ttmp = cpu->cd.arm.r[15] & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<\n"
130     "\t ARM_INSTR_ALIGNMENT_SHIFT);\n");
131     printf("\ttmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;\n");
132     }
133    
134    
135     void f(int s, int func, int only_name)
136     {
137     int rm = func & 15;
138     int c = (func >> 7) & 31;
139     int t = (func >> 4) & 7;
140     char name[200];
141     int pc = rm == 15, rc = c >> 1;
142    
143     snprintf(name, sizeof(name), "arm_r%s_r%i_t%i_c%i", s? "s" : "",
144     rm, t, c);
145     if (only_name) {
146     printf("%s", name);
147     return;
148     }
149    
150     printf("uint32_t %s(struct cpu *cpu, struct arm_instr_call *ic)"
151     " {\n", name);
152     if (pc)
153     sync_pc();
154    
155     switch (t) {
156    
157     case 0: /* lsl c (Logical Shift Left by constant) */
158     if (s) {
159     printf("{ uint32_t x = ");
160     if (pc)
161     printf("tmp");
162     else
163     printf("cpu->cd.arm.r[%i]", rm);
164     printf(";\n");
165     if (c != 0) {
166     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
167     printf("if (x & 0x%x)\n"
168     "\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n",
169     (int)(0x80000000 >> (c-1)));
170     printf("x <<= %i;\n", c);
171     }
172     printf(" return x; }\n");
173     } else {
174     if (pc)
175     printf("\treturn tmp");
176     else
177     printf("\treturn cpu->cd.arm.r[%i]", rm);
178     if (c != 0)
179     printf(" << %i", c);
180     printf(";\n");
181     }
182     break;
183    
184     case 1: /* lsl Rc (Logical Shift Left by register) */
185     if (s) {
186     printf("{ uint32_t x = ");
187     if (pc)
188     printf("tmp");
189     else
190     printf("cpu->cd.arm.r[%i]", rm);
191     printf(";\n");
192     printf(" uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc);
193     printf(" if (y != 0) {\n");
194     printf(" cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
195     printf(" if (y >= 32) return 0;\n");
196     printf(" x <<= (y - 1);\n");
197     printf(" if (x & 0x80000000)\n"
198     "\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n");
199     printf(" x <<= 1;\n");
200     printf(" }\n");
201     printf(" return x; }\n");
202     } else {
203     printf("{ uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc);
204     printf(" uint32_t x =");
205     if (pc)
206     printf("tmp");
207     else
208     printf("cpu->cd.arm.r[%i]", rm);
209     printf(";\n");
210     printf("if (y > 31) return 0; else x <<= y;\n");
211     printf("return x; }\n");
212     }
213     break;
214    
215     case 2: /* lsr c (Logical Shift Right by constant) */
216     /* 1..32 */
217     if (s) {
218     printf("{ uint32_t x = ");
219     if (pc)
220     printf("tmp");
221     else
222     printf("cpu->cd.arm.r[%i]", rm);
223     printf(";\n");
224     if (c == 0)
225     c = 32;
226     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
227     printf("if (x & 0x%x)\n"
228     "\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n",
229     (int)(1 << (c-1)));
230     if (c == 32)
231     printf("x = 0;\n");
232     else
233     printf("x >>= %i;\n", c);
234     printf(" return x; }\n");
235     } else {
236     if (c == 0)
237     printf("\treturn 0;\n");
238     else {
239     if (pc)
240     printf("\treturn tmp");
241     else
242     printf("\treturn cpu->cd.arm.r[%i]",rm);
243     printf(" >> %i;\n", c);
244     }
245     }
246     break;
247    
248     case 3: /* lsr Rc (Logical Shift Right by register) */
249     if (s) {
250     printf("{ uint32_t x = ");
251     if (pc)
252     printf("tmp");
253     else
254     printf("cpu->cd.arm.r[%i]", rm);
255     printf(",y=cpu->cd.arm.r[%i]&255;\n", rc);
256     printf("if(y==0) return x;\n");
257     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
258     printf("if(y>31) y=32;\n");
259     printf("y--; x >>= y;\n");
260     printf("if (x & 1) "
261     "cpu->cd.arm.cpsr |= ARM_FLAG_C;\n");
262     printf(" return x >> 1; }\n");
263     } else {
264     printf("{ uint32_t y=cpu->cd.arm.r[%i]&255;\n", rc);
265     printf("uint32_t x=");
266     if (pc)
267     printf("tmp");
268     else
269     printf("cpu->cd.arm.r[%i]",rm);
270     printf("; ");
271     printf("if (y>=32) return 0;\n");
272     printf("return x >> y; } ");
273     }
274     break;
275    
276     case 4: /* asr c (Arithmetic Shift Right by constant) */
277     /* 1..32 */
278     if (s) {
279     printf("{ int32_t x = ");
280     if (pc)
281     printf("tmp");
282     else
283     printf("cpu->cd.arm.r[%i]", rm);
284     printf(";\n");
285     if (c == 0)
286     c = 32;
287     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
288     printf("if (x & 0x%x)\n"
289     "\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n",
290     (int)(1 << (c-1)));
291     if (c == 32)
292     printf("x = (x<0)? 0xffffffff : 0;\n");
293     else
294     printf("x >>= %i;\n", c);
295     printf(" return x; }\n");
296     } else {
297     if (c == 0) {
298     printf("\treturn ");
299     if (pc)
300     printf("tmp");
301     else
302     printf("cpu->cd.arm.r[%i]",rm);
303     printf(" & 0x80000000? 0xffffffff : 0;\n");
304     } else {
305     printf("return (int32_t)");
306     if (pc)
307     printf("tmp");
308     else
309     printf("cpu->cd.arm.r[%i]",rm);
310     printf(" >> %i;\n", c);
311     }
312     }
313     break;
314    
315     case 5: /* asr Rc (Arithmetic Shift Right by register) */
316     if (s) {
317     printf("{ int32_t x = ");
318     if (pc)
319     printf("tmp");
320     else
321     printf("cpu->cd.arm.r[%i]", rm);
322     printf(",y=cpu->cd.arm.r[%i]&255;\n", rc);
323     printf("if(y==0) return x;\n");
324     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
325     printf("if(y>31) y=31;\n");
326     printf("y--; x >>= y;\n");
327     printf("if (x & 1) "
328     "cpu->cd.arm.cpsr |= ARM_FLAG_C;\n");
329     printf(" return (int32_t)x >> 1; }\n");
330     } else {
331     printf("{ int32_t y=cpu->cd.arm.r[%i]&255;\n", rc);
332     printf("int32_t x=");
333     if (pc)
334     printf("tmp");
335     else
336     printf("cpu->cd.arm.r[%i]",rm);
337     printf("; ");
338     printf("if (y>=31) return (x<0)?0xffffffff:0;\n");
339     printf("return (int32_t)x >> y; } ");
340     }
341     break;
342    
343     case 6: /* ror c OR rrx (Arithmetic Shift Right by constant) */
344     /* 0=rrx, 1..31=ror */
345     if (c == 0) {
346     printf("\tprintf(\"%s\\n\");\n", name);
347     printf("\texit(1); /* TODO */\n\treturn 0;\n");
348     } else if (s) {
349     printf("{ uint64_t x = ");
350     if (pc)
351     printf("tmp");
352     else
353     printf("cpu->cd.arm.r[%i]", rm);
354     printf("; x |= (x << 32);\n");
355     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
356     printf("if (x & 0x%x)\n"
357     "\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n",
358     (int)(1 << (c-1)));
359     printf(" return x >> %i; }\n", c);
360     } else {
361     printf("uint64_t x=");
362     if (pc)
363     printf("tmp");
364     else
365     printf("cpu->cd.arm.r[%i]",rm);
366     printf("; x |= (x << 32); ");
367     printf("return x >> %i;\n", c);
368     }
369     break;
370    
371     case 7: /* ror Rc (Rotate Right by register) */
372     if (s) {
373     printf("{ uint64_t x = ");
374     if (pc)
375     printf("tmp");
376     else
377     printf("cpu->cd.arm.r[%i]", rm);
378     printf("; int y=cpu->cd.arm.r[%i]&255;\n", rc);
379     printf("if(y==0) return x;\n");
380     printf("y --; y &= 31; x >>= y;\n");
381     printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n");
382     printf("if (x & 1) "
383     "cpu->cd.arm.cpsr |= ARM_FLAG_C;\n");
384     printf(" return x >> 1; }\n");
385     } else {
386     printf("{ int y=cpu->cd.arm.r[%i]&31;\n", rc);
387     printf("uint64_t x=");
388     if (pc)
389     printf("tmp");
390     else
391     printf("cpu->cd.arm.r[%i]",rm);
392     printf("; x |= (x << 32); ");
393     printf("return (x >> y); } ");
394     }
395     break;
396    
397     default:
398     printf("\tprintf(\"%s\\n\");\n", name);
399     printf("\texit(1); /* TODO */\n\treturn 0;\n");
400     }
401    
402     printf("}\n");
403     }
404    
405    
406     int main(int argc, char *argv[])
407     {
408     int s, func, f_start, f_end;
409    
410     if (argc < 3) {
411     fprintf(stderr, "usage: %s start end\n", argv[0]);
412     exit(1);
413     }
414    
415     f_start = strtol(argv[1], NULL, 0);
416     f_end = strtol(argv[2], NULL, 0);
417    
418     printf("/*\n * DO NOT EDIT! AUTOMATICALLY GENERATED!\n */\n\n");
419     printf("#include <stdio.h>\n");
420     printf("#include <stdlib.h>\n");
421     printf("#include \"cpu.h\"\n");
422     printf("#include \"misc.h\"\n");
423     printf("\n\n");
424    
425     if (f_start != 0 || f_end != 0) {
426     for (s=0; s<=1; s++)
427     for (func=f_start; func<=f_end; func++)
428     f(s, func, 0);
429     } else {
430     for (s=0; s<=1; s++)
431     for (func=0; func<=0xfff; func++) {
432     printf("extern uint32_t ");
433     f(s, func, 1);
434     printf("(struct cpu *, struct arm_"
435     "instr_call *);\n");
436     }
437    
438     printf("\nuint32_t (*arm_r[8192])(struct cpu *,"
439     " struct arm_instr_call *) = {\n");
440     for (s=0; s<=1; s++)
441     for (func=0; func<=0xfff; func++) {
442     printf("\t");
443     f(s, func, 1);
444     if (s!=1 || func!=0xfff)
445     printf(",");
446     printf("\n");
447     }
448     printf("};\n\n");
449     }
450    
451     return 0;
452     }
453    

  ViewVC Help
Powered by ViewVC 1.1.26