add docs for r5900 arg characters
[deliverable/binutils-gdb.git] / opcodes / cgen-opc.in
CommitLineData
ab0bd049
DE
1/* Generic opcode table support for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
0499462e 4THIS FILE IS USED TO GENERATE @prefix@-opc.c.
ab0bd049
DE
5
6Copyright (C) 1998 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
0499462e
DE
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
ab0bd049
DE
23
24#include "sysdep.h"
25#include <stdio.h>
26#include "ansidecl.h"
27#include "libiberty.h"
28#include "bfd.h"
29#include "symcat.h"
0499462e 30#include "@prefix@-opc.h"
1e74d15c 31#include "opintl.h"
ab0bd049 32
86dc452e
DE
33/* Used by the ifield rtx function. */
34#define FLD(f) (fields->f)
35
c2009f4a
DE
36/* The hash functions are recorded here to help keep assembler code out of
37 the disassembler and vice versa. */
38
39static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
40static unsigned int asm_hash_insn PARAMS ((const char *));
41static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
95b03313 42static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT));
fcea6f20 43
ab0bd049 44/* Look up instruction INSN_VALUE and extract its fields.
2613b5e6 45 INSN, if non-null, is the insn table entry.
ab0bd049
DE
46 Otherwise INSN_VALUE is examined to compute it.
47 LENGTH is the bit length of INSN_VALUE if known, otherwise 0.
fcea6f20 48 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
2613b5e6 49 If INSN != NULL, LENGTH must be valid.
390bd87d 50 ALIAS_P is non-zero if alias insns are to be included in the search.
2613b5e6 51
95b03313 52 The result is a pointer to the insn table entry, or NULL if the instruction
ab0bd049
DE
53 wasn't recognized. */
54
55const CGEN_INSN *
c2009f4a
DE
56@arch@_cgen_lookup_insn (od, insn, insn_value, length, fields, alias_p)
57 CGEN_OPCODE_DESC od;
ab0bd049 58 const CGEN_INSN *insn;
fcea6f20 59 CGEN_INSN_BYTES insn_value;
ab0bd049
DE
60 int length;
61 CGEN_FIELDS *fields;
2613b5e6 62 int alias_p;
ab0bd049 63{
95b03313 64 unsigned char buf[CGEN_MAX_INSN_SIZE];
fcea6f20 65 unsigned char *bufp;
95b03313 66 CGEN_INSN_INT base_insn;
fcea6f20
DE
67#if CGEN_INT_INSN_P
68 CGEN_EXTRACT_INFO *info = NULL;
69#else
70 CGEN_EXTRACT_INFO ex_info;
71 CGEN_EXTRACT_INFO *info = &ex_info;
72#endif
73
95b03313
DE
74#if CGEN_INT_INSN_P
75 cgen_put_insn_value (od, buf, length, insn_value);
76 bufp = buf;
77 base_insn = insn_value; /*???*/
78#else
fcea6f20 79 ex_info.dis_info = NULL;
95b03313 80 ex_info.insn_bytes = insn_value;
fcea6f20 81 ex_info.valid = -1;
95b03313
DE
82 base_insn = cgen_get_insn_value (od, buf, length);
83 bufp = insn_value;
fcea6f20 84#endif
ab0bd049
DE
85
86 if (!insn)
87 {
88 const CGEN_INSN_LIST *insn_list;
89
ab0bd049
DE
90 /* The instructions are stored in hash lists.
91 Pick the first one and keep trying until we find the right one. */
92
fcea6f20 93 insn_list = CGEN_DIS_LOOKUP_INSN (od, bufp, base_insn);
ab0bd049
DE
94 while (insn_list != NULL)
95 {
96 insn = insn_list->insn;
97
390bd87d
DE
98 if (alias_p
99 || ! CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
ab0bd049 100 {
390bd87d
DE
101 /* Basic bit mask must be correct. */
102 /* ??? May wish to allow target to defer this check until the
103 extract handler. */
86dc452e
DE
104 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
105 == CGEN_INSN_BASE_VALUE (insn))
390bd87d 106 {
fbc8134d 107 /* ??? 0 is passed for `pc' */
fcea6f20 108 int elength = (*CGEN_EXTRACT_FN (insn)) (od, insn, info,
95b03313 109 base_insn, fields,
fbc8134d 110 (bfd_vma) 0);
2613b5e6
DE
111 if (elength > 0)
112 {
113 /* sanity check */
114 if (length != 0 && length != elength)
115 abort ();
116 return insn;
117 }
390bd87d 118 }
ab0bd049
DE
119 }
120
121 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
122 }
123 }
124 else
125 {
390bd87d
DE
126 /* Sanity check: can't pass an alias insn if ! alias_p. */
127 if (! alias_p
128 && CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
129 abort ();
2613b5e6
DE
130 /* Sanity check: length must be correct. */
131 if (length != CGEN_INSN_BITSIZE (insn))
132 abort ();
390bd87d 133
fbc8134d 134 /* ??? 0 is passed for `pc' */
95b03313 135 length = (*CGEN_EXTRACT_FN (insn)) (od, insn, info, base_insn, fields,
fbc8134d 136 (bfd_vma) 0);
2613b5e6
DE
137 /* Sanity check: must succeed.
138 Could relax this later if it ever proves useful. */
139 if (length == 0)
140 abort ();
141 return insn;
ab0bd049
DE
142 }
143
144 return NULL;
145}
146
2613b5e6 147/* Fill in the operand instances used by INSN whose operands are FIELDS.
bed9a23c 148 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
2613b5e6 149 in. */
ab0bd049 150
2613b5e6 151void
c2009f4a
DE
152@arch@_cgen_get_insn_operands (od, insn, fields, indices)
153 CGEN_OPCODE_DESC od;
2613b5e6
DE
154 const CGEN_INSN * insn;
155 const CGEN_FIELDS * fields;
ab0bd049
DE
156 int *indices;
157{
ab0bd049
DE
158 const CGEN_OPERAND_INSTANCE *opinst;
159 int i;
160
ab0bd049 161 for (i = 0, opinst = CGEN_INSN_OPERANDS (insn);
b2f18612
DE
162 opinst != NULL
163 && CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END;
ab0bd049
DE
164 ++i, ++opinst)
165 {
166 const CGEN_OPERAND *op = CGEN_OPERAND_INSTANCE_OPERAND (opinst);
167 if (op == NULL)
168 indices[i] = CGEN_OPERAND_INSTANCE_INDEX (opinst);
169 else
fbc8134d
DE
170 indices[i] = @arch@_cgen_get_int_operand (CGEN_OPERAND_INDEX (op),
171 fields);
ab0bd049 172 }
2613b5e6
DE
173}
174
175/* Cover function to @arch@_cgen_get_insn_operands when either INSN or FIELDS
176 isn't known.
177 The INSN, INSN_VALUE, and LENGTH arguments are passed to
178 @arch@_cgen_lookup_insn unchanged.
179
180 The result is the insn table entry or NULL if the instruction wasn't
181 recognized. */
182
183const CGEN_INSN *
c2009f4a
DE
184@arch@_cgen_lookup_get_insn_operands (od, insn, insn_value, length, indices)
185 CGEN_OPCODE_DESC od;
2613b5e6 186 const CGEN_INSN *insn;
fcea6f20 187 CGEN_INSN_BYTES insn_value;
2613b5e6
DE
188 int length;
189 int *indices;
190{
191 CGEN_FIELDS fields;
192
193 /* Pass non-zero for ALIAS_P only if INSN != NULL.
194 If INSN == NULL, we want a real insn. */
c2009f4a 195 insn = @arch@_cgen_lookup_insn (od, insn, insn_value, length, &fields,
2613b5e6
DE
196 insn != NULL);
197 if (! insn)
198 return NULL;
ab0bd049 199
c2009f4a 200 @arch@_cgen_get_insn_operands (od, insn, &fields, indices);
ab0bd049
DE
201 return insn;
202}
This page took 0.056537 seconds and 4 git commands to generate.