]>
Commit | Line | Data |
---|---|---|
99dee823 | 1 | /* Copyright (C) 2012-2021 Free Software Foundation, Inc. |
04d170d2 GJL |
2 | Contributed by Georg-Johann Lay (avr@gjlay.de) |
3 | ||
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING3. If not see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
e3cf7a95 GJL |
20 | #include <stdlib.h> |
21 | #include <stdio.h> | |
df48be86 | 22 | #include <string.h> |
e3cf7a95 GJL |
23 | |
24 | #define IN_GEN_AVR_MMCU_TEXI | |
25 | ||
04d170d2 GJL |
26 | #include "avr-devices.c" |
27 | ||
80b38f83 GJL |
28 | static const avr_mcu_t* |
29 | mcus[sizeof avr_mcu_types / sizeof avr_mcu_types[0]]; | |
5be35a61 | 30 | |
e3cf7a95 GJL |
31 | static int letter (char c) |
32 | { | |
33 | return c >= 'a' && c <= 'z'; | |
34 | } | |
35 | ||
36 | static int digit (char c) | |
37 | { | |
38 | return c >= '0' && c <= '9'; | |
39 | } | |
40 | ||
80b38f83 GJL |
41 | static int |
42 | str_prefix_p (const char *str, const char *prefix) | |
43 | { | |
44 | return strncmp (str, prefix, strlen (prefix)) == 0; | |
45 | } | |
46 | ||
47 | ||
48 | /* Used by string comparator to group MCUs by their | |
49 | name prefix like "attiny" or "atmega". */ | |
50 | ||
51 | static int | |
52 | c_prefix (const char *str) | |
53 | { | |
54 | static const char *const prefixes[] = | |
55 | { | |
56 | "attiny", "atmega", "atxmega", "ata", "at90" | |
57 | }; | |
58 | ||
59 | int i, n = (int) (sizeof (prefixes) / sizeof (*prefixes)); | |
60 | ||
61 | for (i = 0; i < n; i++) | |
62 | if (str_prefix_p (str, prefixes[i])) | |
63 | return i; | |
64 | ||
65 | return n; | |
66 | } | |
67 | ||
68 | ||
69 | /* If A starts a group of digits, return their value as a number. */ | |
70 | ||
71 | static int | |
72 | c_number (const char *a) | |
73 | { | |
74 | int val = 0; | |
75 | ||
76 | if (digit (*a) && ! digit (*(a-1))) | |
77 | { | |
78 | while (digit (*a)) | |
79 | val = 10 * val + (*a++) - '0'; | |
80 | } | |
81 | ||
82 | return val; | |
83 | } | |
84 | ||
85 | ||
86 | /* Compare two MCUs and order them for easy lookup. */ | |
87 | ||
5be35a61 GJL |
88 | static int |
89 | comparator (const void *va, const void *vb) | |
90 | { | |
80b38f83 GJL |
91 | const avr_mcu_t *mcu_a = *(const avr_mcu_t* const*) va; |
92 | const avr_mcu_t *mcu_b = *(const avr_mcu_t* const*) vb; | |
93 | const char *a = mcu_a->name; | |
94 | const char *b = mcu_b->name; | |
95 | ||
96 | // First, group MCUs according to their pure-letter prefix. | |
97 | ||
98 | int c = c_prefix (a) - c_prefix (b); | |
99 | if (c) | |
100 | return c; | |
101 | ||
102 | // Second, if their prefixes are the same, group according to | |
103 | // their flash size. | |
104 | ||
105 | c = (int) mcu_a->flash_size - (int) mcu_b->flash_size; | |
106 | if (c) | |
107 | return c; | |
108 | ||
109 | // Third, group according to aligned groups of digits. | |
e3cf7a95 GJL |
110 | |
111 | while (*a && *b) | |
112 | { | |
80b38f83 GJL |
113 | c = c_number (a) - c_number (b); |
114 | if (c) | |
115 | return c; | |
e3cf7a95 GJL |
116 | |
117 | if (*a != *b) | |
80b38f83 | 118 | return *a - *b; |
e3cf7a95 GJL |
119 | |
120 | a++; | |
121 | b++; | |
122 | } | |
5be35a61 | 123 | |
e3cf7a95 | 124 | return *a - *b; |
5be35a61 GJL |
125 | } |
126 | ||
127 | static void | |
128 | print_mcus (size_t n_mcus) | |
129 | { | |
5219b232 | 130 | int duplicate = 0; |
5be35a61 GJL |
131 | size_t i; |
132 | ||
133 | if (!n_mcus) | |
134 | return; | |
135 | ||
80b38f83 | 136 | qsort (mcus, n_mcus, sizeof (avr_mcu_t*), comparator); |
5be35a61 GJL |
137 | |
138 | printf ("@*@var{mcu}@tie{}="); | |
139 | ||
140 | for (i = 0; i < n_mcus; i++) | |
5219b232 | 141 | { |
80b38f83 | 142 | printf (" @code{%s}%s", mcus[i]->name, i == n_mcus-1 ? ".\n\n" : ","); |
5219b232 | 143 | |
80b38f83 GJL |
144 | if (i && !strcmp (mcus[i]->name, mcus[i-1]->name)) |
145 | { | |
146 | // Sanity-check: Fail on devices that are present more than once. | |
5219b232 | 147 | |
80b38f83 GJL |
148 | duplicate = 1; |
149 | fprintf (stderr, "error: duplicate device: %s\n", mcus[i]->name); | |
150 | } | |
5219b232 GJL |
151 | } |
152 | ||
153 | if (duplicate) | |
154 | exit (1); | |
5be35a61 GJL |
155 | } |
156 | ||
04d170d2 GJL |
157 | int main (void) |
158 | { | |
4a2caf6c | 159 | enum avr_arch_id arch_id = ARCH_UNKNOWN; |
5be35a61 | 160 | size_t i, n_mcus = 0; |
1c494c6a | 161 | const avr_mcu_t *mcu; |
04d170d2 | 162 | |
99dee823 | 163 | printf ("@c Copyright (C) 2012-2021 Free Software Foundation, Inc.\n"); |
04d170d2 GJL |
164 | printf ("@c This is part of the GCC manual.\n"); |
165 | printf ("@c For copying conditions, see the file " | |
80b38f83 | 166 | "gcc/doc/include/fdl.texi.\n\n"); |
04d170d2 GJL |
167 | |
168 | printf ("@c This file is generated automatically using\n"); | |
169 | printf ("@c gcc/config/avr/gen-avr-mmcu-texi.c from:\n"); | |
80b38f83 GJL |
170 | printf ("@c gcc/config/avr/avr-arch.h\n"); |
171 | printf ("@c gcc/config/avr/avr-devices.c\n"); | |
172 | printf ("@c gcc/config/avr/avr-mcus.def\n\n"); | |
04d170d2 GJL |
173 | |
174 | printf ("@c Please do not edit manually.\n\n"); | |
175 | ||
176 | printf ("@table @code\n\n"); | |
177 | ||
178 | for (mcu = avr_mcu_types; mcu->name; mcu++) | |
179 | { | |
180 | if (mcu->macro == NULL) | |
80b38f83 GJL |
181 | { |
182 | arch_id = mcu->arch_id; | |
5be35a61 | 183 | |
80b38f83 GJL |
184 | // Start a new architecture: Flush the MCUs collected so far. |
185 | print_mcus (n_mcus); | |
186 | n_mcus = 0; | |
5be35a61 | 187 | |
80b38f83 GJL |
188 | for (i = 0; i < sizeof (avr_texinfo) / sizeof (*avr_texinfo); i++) |
189 | if (arch_id == avr_texinfo[i].arch_id) | |
190 | printf ("@item %s\n%s\n", mcu->name, avr_texinfo[i].texinfo); | |
191 | } | |
4a2caf6c | 192 | else if (arch_id == (enum avr_arch_id) mcu->arch_id) |
80b38f83 GJL |
193 | { |
194 | mcus[n_mcus++] = mcu; | |
195 | } | |
04d170d2 GJL |
196 | } |
197 | ||
5be35a61 | 198 | print_mcus (n_mcus); |
04d170d2 GJL |
199 | printf ("@end table\n"); |
200 | ||
201 | return EXIT_SUCCESS; | |
202 | } |