1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include "sysdep.h"
23: #include <stdio.h>
24: #include "ansidecl.h"
25: #include "libiberty.h"
26: #include "safe-ctype.h"
27: #include "bfd.h"
28: #include "symcat.h"
29: #include "opcode/cgen.h"
30: #include "opintl.h"
31:
32: static CGEN_INSN_LIST * hash_insn_array (CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
33: static CGEN_INSN_LIST * hash_insn_list (CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
34: static void build_asm_hash_table (CGEN_CPU_DESC);
35:
36:
37:
38: void
39: cgen_set_parse_operand_fn (CGEN_CPU_DESC cd, cgen_parse_operand_fn fn)
40: {
41: cd->parse_operand_fn = fn;
42: }
43:
44:
45:
46: void
47: cgen_init_parse_operand (CGEN_CPU_DESC cd)
48: {
49:
50: (void) (* cd->parse_operand_fn)
51: (cd, CGEN_PARSE_OPERAND_INIT, NULL, 0, 0, NULL, NULL);
52: }
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66: static CGEN_INSN_LIST *
67: hash_insn_array (CGEN_CPU_DESC cd,
68: const CGEN_INSN *insns,
69: int count,
70: int entsize ATTRIBUTE_UNUSED,
71: CGEN_INSN_LIST **htable,
72: CGEN_INSN_LIST *hentbuf)
73: {
74: int i;
75:
76: for (i = count - 1; i >= 0; --i, ++hentbuf)
77: {
78: unsigned int hash;
79: const CGEN_INSN *insn = &insns[i];
80:
81: if (! (* cd->asm_hash_p) (insn))
82: continue;
83: hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (insn));
84: hentbuf->next = htable[hash];
85: hentbuf->insn = insn;
86: htable[hash] = hentbuf;
87: }
88:
89: return hentbuf;
90: }
91:
92:
93:
94:
95:
96: static CGEN_INSN_LIST *
97: hash_insn_list (CGEN_CPU_DESC cd,
98: const CGEN_INSN_LIST *insns,
99: CGEN_INSN_LIST **htable,
100: CGEN_INSN_LIST *hentbuf)
101: {
102: const CGEN_INSN_LIST *ilist;
103:
104: for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
105: {
106: unsigned int hash;
107:
108: if (! (* cd->asm_hash_p) (ilist->insn))
109: continue;
110: hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (ilist->insn));
111: hentbuf->next = htable[hash];
112: hentbuf->insn = ilist->insn;
113: htable[hash] = hentbuf;
114: }
115:
116: return hentbuf;
117: }
118:
119:
120:
121: static void
122: build_asm_hash_table (CGEN_CPU_DESC cd)
123: {
124: int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
125: CGEN_INSN_TABLE *insn_table = &cd->insn_table;
126: CGEN_INSN_TABLE *macro_insn_table = &cd->macro_insn_table;
127: unsigned int hash_size = cd->asm_hash_size;
128: CGEN_INSN_LIST *hash_entry_buf;
129: CGEN_INSN_LIST **asm_hash_table;
130: CGEN_INSN_LIST *asm_hash_table_entries;
131:
132:
133:
134:
135: asm_hash_table = (CGEN_INSN_LIST **)
136: xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
137: memset (asm_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
138: asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
139: xmalloc (count * sizeof (CGEN_INSN_LIST));
140:
141:
142:
143:
144:
145:
146: hash_entry_buf = hash_insn_array (cd,
147: insn_table->init_entries + 1,
148: insn_table->num_init_entries - 1,
149: insn_table->entry_size,
150: asm_hash_table, hash_entry_buf);
151:
152:
153:
154: hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
155: macro_insn_table->num_init_entries,
156: macro_insn_table->entry_size,
157: asm_hash_table, hash_entry_buf);
158:
159:
160:
161:
162: hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
163: asm_hash_table, hash_entry_buf);
164:
165:
166:
167: hash_insn_list (cd, macro_insn_table->new_entries,
168: asm_hash_table, hash_entry_buf);
169:
170: cd->asm_hash_table = asm_hash_table;
171: cd->asm_hash_table_entries = asm_hash_table_entries;
172: }
173:
174:
175:
176: CGEN_INSN_LIST *
177: cgen_asm_lookup_insn (CGEN_CPU_DESC cd, const char *insn)
178: {
179: unsigned int hash;
180:
181: if (cd->asm_hash_table == NULL)
182: build_asm_hash_table (cd);
183:
184: hash = (* cd->asm_hash) (insn);
185: return cd->asm_hash_table[hash];
186: }
187: ^L
188:
189:
190:
191:
192:
193:
194:
195:
196: const char *
197: cgen_parse_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
198: const char **strp,
199: CGEN_KEYWORD *keyword_table,
200: long *valuep)
201: {
202: const CGEN_KEYWORD_ENTRY *ke;
203: char buf[256];
204: const char *p,*start;
205:
206: if (keyword_table->name_hash_table == NULL)
207: (void) cgen_keyword_search_init (keyword_table, NULL);
208:
209: p = start = *strp;
210:
211:
212:
213:
214: if (*p)
215: ++p;
216:
217:
218: while (((p - start) < (int) sizeof (buf))
219: && *p
220: && (ISALNUM (*p)
221: || *p == '_'
222: || strchr (keyword_table->nonalpha_chars, *p)))
223: ++p;
224:
225: if (p - start >= (int) sizeof (buf))
226: {
227:
228:
229: buf[0] = 0;
230: }
231: else
232: {
233: memcpy (buf, start, p - start);
234: buf[p - start] = 0;
235: }
236:
237: ke = cgen_keyword_lookup_name (keyword_table, buf);
238:
239: if (ke != NULL)
240: {
241: *valuep = ke->value;
242:
243: if (ke->name[0] != 0)
244: *strp = p;
245: return NULL;
246: }
247:
248: return "unrecognized keyword/register name";
249: }
250:
251:
252:
253:
254:
255:
256: const char *
257: cgen_parse_signed_integer (CGEN_CPU_DESC cd,
258: const char **strp,
259: int opindex,
260: long *valuep)
261: {
262: bfd_vma value;
263: enum cgen_parse_operand_result result;
264: const char *errmsg;
265:
266: errmsg = (* cd->parse_operand_fn)
267: (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
268: &result, &value);
269:
270: if (!errmsg)
271: *valuep = value;
272: return errmsg;
273: }
274:
275:
276:
277:
278:
279:
280: const char *
281: cgen_parse_unsigned_integer (CGEN_CPU_DESC cd,
282: const char **strp,
283: int opindex,
284: unsigned long *valuep)
285: {
286: bfd_vma value;
287: enum cgen_parse_operand_result result;
288: const char *errmsg;
289:
290: errmsg = (* cd->parse_operand_fn)
291: (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
292: &result, &value);
293:
294: if (!errmsg)
295: *valuep = value;
296: return errmsg;
297: }
298:
299:
300:
301: const char *
302: cgen_parse_address (CGEN_CPU_DESC cd,
303: const char **strp,
304: int opindex,
305: int opinfo,
306: enum cgen_parse_operand_result *resultp,
307: bfd_vma *valuep)
308: {
309: bfd_vma value;
310: enum cgen_parse_operand_result result_type;
311: const char *errmsg;
312:
313: errmsg = (* cd->parse_operand_fn)
314: (cd, CGEN_PARSE_OPERAND_ADDRESS, strp, opindex, opinfo,
315: &result_type, &value);
316:
317: if (!errmsg)
318: {
319: if (resultp != NULL)
320: *resultp = result_type;
321: *valuep = value;
322: }
323: return errmsg;
324: }
325: ^L
326:
327:
328: const char *
329: cgen_validate_signed_integer (long value, long min, long max)
330: {
331: if (value < min || value > max)
332: {
333: static char buf[100];
334:
335:
336: sprintf (buf, _("operand out of range (%ld not between %ld and %ld)"),
337: value, min, max);
338: return buf;
339: }
340:
341: return NULL;
342: }
343:
344:
345:
346:
347:
348: const char *
349: cgen_validate_unsigned_integer (unsigned long value,
350: unsigned long min,
351: unsigned long max)
352: {
353: if (value < min || value > max)
354: {
355: static char buf[100];
356:
357:
358: sprintf (buf, _("operand out of range (%lu not between %lu and %lu)"),
359: value, min, max);
360: return buf;
361: }
362:
363: return NULL;
364: }