* mips-dis.c (print_insn_arg): Do not prefix 'P' arguments with '$'.
[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
4This file is used to generate @arch@-opc.c.
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
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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"
30#include "@arch@-opc.h"
31
32/* Look up instruction INSN_VALUE and extract its fields.
33 If non-null INSN is the insn table entry.
34 Otherwise INSN_VALUE is examined to compute it.
35 LENGTH is the bit length of INSN_VALUE if known, otherwise 0.
390bd87d 36 ALIAS_P is non-zero if alias insns are to be included in the search.
ab0bd049
DE
37 The result a pointer to the insn table entry, or NULL if the instruction
38 wasn't recognized. */
39
40const CGEN_INSN *
390bd87d 41@arch@_cgen_lookup_insn (insn, insn_value, length, fields, alias_p)
ab0bd049
DE
42 const CGEN_INSN *insn;
43 cgen_insn_t insn_value;
44 int length;
45 CGEN_FIELDS *fields;
46{
390bd87d 47 char buf[16];
ab0bd049
DE
48
49 if (!insn)
50 {
51 const CGEN_INSN_LIST *insn_list;
52
53#ifdef CGEN_INT_INSN
54 switch (length)
55 {
56 case 8:
57 buf[0] = insn_value;
58 break;
59 case 16:
60 if (cgen_current_endian == CGEN_ENDIAN_BIG)
61 bfd_putb16 (insn_value, buf);
62 else
63 bfd_putl16 (insn_value, buf);
64 break;
65 case 32:
66 if (cgen_current_endian == CGEN_ENDIAN_BIG)
67 bfd_putb32 (insn_value, buf);
68 else
69 bfd_putl32 (insn_value, buf);
70 break;
71 default:
72 abort ();
73 }
74#else
75 abort (); /* FIXME: unfinished */
76#endif
77
78 /* The instructions are stored in hash lists.
79 Pick the first one and keep trying until we find the right one. */
80
81 insn_list = CGEN_DIS_LOOKUP_INSN (buf, insn_value);
82 while (insn_list != NULL)
83 {
84 insn = insn_list->insn;
85
390bd87d
DE
86 if (alias_p
87 || ! CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
ab0bd049 88 {
390bd87d
DE
89 /* Basic bit mask must be correct. */
90 /* ??? May wish to allow target to defer this check until the
91 extract handler. */
92 if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
93 {
94 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, fields);
95 if (length > 0)
96 return insn;
97 }
ab0bd049
DE
98 }
99
100 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
101 }
102 }
103 else
104 {
390bd87d
DE
105 /* Sanity check: can't pass an alias insn if ! alias_p. */
106 if (! alias_p
107 && CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
108 abort ();
109
ab0bd049
DE
110 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, fields);
111 if (length > 0)
112 return insn;
113 }
114
115 return NULL;
116}
117
118/* Fill in the operand instances used by insn INSN_VALUE.
119 If non-null INS is the insn table entry.
120 Otherwise INSN_VALUE is examined to compute it.
121 LENGTH is the number of bits in INSN_VALUE if known, otherwise 0.
bed9a23c
DE
122 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
123 in.
ab0bd049
DE
124 The result a pointer to the insn table entry, or NULL if the instruction
125 wasn't recognized. */
126
127const CGEN_INSN *
128@arch@_cgen_get_insn_operands (insn, insn_value, length, indices)
129 const CGEN_INSN *insn;
130 cgen_insn_t insn_value;
131 int length;
132 int *indices;
133{
134 CGEN_FIELDS fields;
135 const CGEN_OPERAND_INSTANCE *opinst;
136 int i;
137
390bd87d
DE
138 /* FIXME: ALIAS insns are in transition from being record in the insn table
139 to being recorded separately as macros. They don't have semantic code
140 so they can't be used here. Thus we currently always ignore the INSN
141 argument. */
142 insn = @arch@_cgen_lookup_insn (NULL, insn_value, length, &fields, 0);
ab0bd049
DE
143 if (! insn)
144 return NULL;
145
146 for (i = 0, opinst = CGEN_INSN_OPERANDS (insn);
b2f18612
DE
147 opinst != NULL
148 && CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END;
ab0bd049
DE
149 ++i, ++opinst)
150 {
151 const CGEN_OPERAND *op = CGEN_OPERAND_INSTANCE_OPERAND (opinst);
152 if (op == NULL)
153 indices[i] = CGEN_OPERAND_INSTANCE_INDEX (opinst);
154 else
155 indices[i] = @arch@_cgen_get_operand (CGEN_OPERAND_INDEX (op), &fields);
156 }
157
158 return insn;
159}
This page took 0.030152 seconds and 4 git commands to generate.