/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show 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 /*
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