experiment_arm_multi.cc Source File

Back to the index.

experiment_arm_multi.cc
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  * Given a list of common ARM load/store multiple opcodes, figure out (using
29  * simple brute force), which n bits (where n is low, e.g. 7) that cause the
30  * best separation of the 24 bit opcode space into linear lists, where "best"
31  * means to optimize the length of the longest such linear list.
32  *
33  * The result is a set of bits, such as this:
34  *
35  * xxxx100P USWLnnnn llllllll llllllll
36  * ^ ^ ^^ ^^ (in this case, n = 6)
37  *
38  * (it's a 24-bit space, because the s-bit isn't used).
39  */
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 
45 int bit_count(unsigned int x)
46 {
47  static const int c[16] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
48  return c[x & 15] + c[(x>>4) & 15] +
49  c[(x>>8) & 15] + c[(x>>12) & 15] +
50  c[(x>>16) & 15] + c[(x>>20) & 15] +
51  c[(x>>24) & 15] + c[(x>>28) & 15];
52 }
53 
54 
55 int cmpfunc(const void *a, const void *b)
56 {
57  int *pa = (int *) a, *pb = (int *) b;
58  if (*pa < *pb)
59  return -1;
60  if (*pa > *pb)
61  return 1;
62  return 0;
63 }
64 
65 
66 int calc_max_list_length(int *opcodes, int *tmp_table,
67  int n_opcodes, int bit_mask)
68 {
69  int i, maxlen, curlen;
70 
71  for (i=0; i<n_opcodes; i++)
72  tmp_table[i] = opcodes[i] & bit_mask;
73 
74  qsort(tmp_table, n_opcodes, sizeof(int), cmpfunc);
75  curlen = maxlen = 1;
76 
77  for (i=1; i<n_opcodes; i++)
78  if (tmp_table[i] == tmp_table[i-1]) {
79  curlen ++;
80  if (curlen > maxlen)
81  maxlen = curlen;
82  } else
83  curlen = 1;
84 
85  return maxlen;
86 }
87 
88 
89 int main(int argc, char *argv[])
90 {
91  FILE *f = fopen("cpu_arm_multi.txt", "r");
92  int n;
93  const int max = 10000;
94  int opcode[max];
95  int tmp_table[max];
96  int n_opcodes = 0;
97  int *max_len;
98  int bit_mask, best_bit_mask, best_bit_mask_len;
99 
100  if (argc < 2) {
101  fprintf(stderr, "usage: %s n\n", argv[0]);
102  fprintf(stderr, "where n=6 might be a good choice\n");
103  exit(1);
104  }
105 
106  n = atoi(argv[1]);
107 
108  if (f == NULL) {
109  fprintf(stderr, "could not open cpu_arm_multi.txt\n");
110  exit(1);
111  }
112 
113  /* Read the opcodes: */
114  while (!feof(f)) {
115  char s[100];
116  s[0] = s[sizeof(s)-1] = '\0';
117  fgets(s, sizeof(s), f);
118  if (s[0] == '0') {
119  if (n_opcodes > max) {
120  fprintf(stderr, "too many opcodes\n");
121  exit(1);
122  }
123  opcode[n_opcodes++] = strtol(s, NULL, 0);
124  }
125  }
126 
127  printf("nr of opcodes = %i\n", n_opcodes);
128 
129  max_len = malloc(sizeof(int) * (1 << 25));
130  if (max_len == NULL) {
131  fprintf(stderr, "out of memory\n");
132  exit(1);
133  }
134 
135  best_bit_mask_len = -1;
136 
137  for (bit_mask = 0; bit_mask <= 0x01ffffff; bit_mask ++) {
138  /* Skip the s-bit: */
139  if (bit_mask & 0x00400000)
140  continue;
141 
142  if (bit_count(bit_mask) != n)
143  continue;
144 
145  /* Calculate the max list length for this bit_mask: */
146  max_len[bit_mask] = calc_max_list_length(opcode,
147  tmp_table, n_opcodes, bit_mask);
148 
149  if (best_bit_mask_len == -1 ||
150  max_len[bit_mask] < best_bit_mask_len) {
151  best_bit_mask_len = max_len[bit_mask];
152  best_bit_mask = bit_mask;
153  printf("best bit_mask so far: 0x%08x: %i\n",
154  best_bit_mask, best_bit_mask_len);
155  }
156  }
157 
158  return 0;
159 }
160 
f
void f(int s, int func, int only_name)
Definition: generate_arm_r.c:45
main
int main(int argc, char *argv[])
Definition: experiment_arm_multi.cc:89
cmpfunc
int cmpfunc(const void *a, const void *b)
Definition: experiment_arm_multi.cc:55
bit_count
int bit_count(unsigned int x)
Definition: experiment_arm_multi.cc:45
calc_max_list_length
int calc_max_list_length(int *opcodes, int *tmp_table, int n_opcodes, int bit_mask)
Definition: experiment_arm_multi.cc:66

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17