/[gxemul]/upstream/0.4.1/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 /upstream/0.4.1/src/cpus/generate_arm_r.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29 - (hide annotations)
Mon Oct 8 16:20:32 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 9841 byte(s)
0.4.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 dpavlin 22 * $Id: generate_arm_r.c,v 1.5 2005/12/26 14:14:27 debug Exp $
29 dpavlin 16 *
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 dpavlin 20 printf("\ttmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<\n"
42 dpavlin 16 "\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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
79 dpavlin 16 printf("if (x & 0x%x)\n"
80 dpavlin 20 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
81 dpavlin 16 (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 dpavlin 20 printf(" cpu->cd.arm.flags &= ~ARM_F_C;\n");
107 dpavlin 16 printf(" if (y >= 32) return 0;\n");
108     printf(" x <<= (y - 1);\n");
109     printf(" if (x & 0x80000000)\n"
110 dpavlin 20 "\tcpu->cd.arm.flags |= ARM_F_C;\n");
111 dpavlin 16 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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
139 dpavlin 16 printf("if (x & 0x%x)\n"
140 dpavlin 20 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
141 dpavlin 16 (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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
170 dpavlin 16 printf("if(y>31) y=32;\n");
171     printf("y--; x >>= y;\n");
172     printf("if (x & 1) "
173 dpavlin 20 "cpu->cd.arm.flags |= ARM_F_C;\n");
174 dpavlin 16 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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
200 dpavlin 16 printf("if (x & 0x%x)\n"
201 dpavlin 20 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
202 dpavlin 16 (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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
237 dpavlin 16 printf("if(y>31) y=31;\n");
238     printf("y--; x >>= y;\n");
239     printf("if (x & 1) "
240 dpavlin 20 "cpu->cd.arm.flags |= ARM_F_C;\n");
241 dpavlin 16 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 dpavlin 22 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 dpavlin 16 } 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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
279 dpavlin 16 printf("if (x & 0x%x)\n"
280 dpavlin 20 "\tcpu->cd.arm.flags |= ARM_F_C;\n",
281 dpavlin 16 (int)(1 << (c-1)));
282     printf(" return x >> %i; }\n", c);
283     } else {
284 dpavlin 18 printf("{ uint64_t x=");
285 dpavlin 16 if (pc)
286     printf("tmp");
287     else
288     printf("cpu->cd.arm.r[%i]",rm);
289     printf("; x |= (x << 32); ");
290 dpavlin 18 printf("return x >> %i; }\n", c);
291 dpavlin 16 }
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 dpavlin 20 printf("cpu->cd.arm.flags &= ~ARM_F_C;\n");
305 dpavlin 16 printf("if (x & 1) "
306 dpavlin 20 "cpu->cd.arm.flags |= ARM_F_C;\n");
307 dpavlin 16 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