/[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 18 - (hide annotations)
Mon Oct 8 16:19:11 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 11408 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


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 dpavlin 18 printf("{ uint64_t x=");
362 dpavlin 16 if (pc)
363     printf("tmp");
364     else
365     printf("cpu->cd.arm.r[%i]",rm);
366     printf("; x |= (x << 32); ");
367 dpavlin 18 printf("return x >> %i; }\n", c);
368 dpavlin 16 }
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