generate_arm_r.c Source File

Back to the index.

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

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18