* A few more improvements to gx jit prototype.
[deliverable/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
b9c8cd10 1/* Support code for various pieces of CGEN simulators.
b500809f 2 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
b9c8cd10
DE
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "sim-main.h"
22#include "dis-asm.h"
23#include "cpu-opc.h"
b9c8cd10
DE
24
25#define MEMOPS_DEFINE_INLINE
b500809f 26#include "cgen-mem.h"
b9c8cd10
DE
27
28#define SEMOPS_DEFINE_INLINE
b500809f 29#include "cgen-ops.h"
b9c8cd10
DE
30
31const char *mode_names[] = {
32 "VM",
33 "BI",
34 "QI",
35 "HI",
36 "SI",
37 "DI",
38 "UBI",
39 "UQI",
40 "UHI",
41 "USI",
42 "UDI",
43 "SF",
44 "DF",
45 "XF",
46 "TF",
47};
48
260b2c47
DE
49/* Initialize cgen things.
50 This is called after sim_post_argv_init. */
51
52void
53cgen_init (SIM_DESC sd)
54{
55 int i, c;
56 int run_fast_p = 1;
57
58 /* If no profiling or tracing has been enabled, run in fast mode. */
59 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
60 {
61 sim_cpu *cpu = STATE_CPU (sd, c);
62
63 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
64 if (CPU_PROFILE_FLAGS (cpu) [i])
65 {
66 run_fast_p = 0;
67 break;
68 }
69 for (i = 0; i < MAX_TRACE_VALUES; ++i)
70 if (CPU_TRACE_FLAGS (cpu) [i])
71 {
72 run_fast_p = 0;
73 break;
74 }
75 if (! run_fast_p)
76 break;
77 }
78 STATE_RUN_FAST_P (sd) = run_fast_p;
79}
80\f
b9c8cd10
DE
81/* Disassembly support.
82 ??? While executing an instruction, the insn has been decoded and all its
83 fields have been extracted. It is certainly possible to do the disassembly
84 with that data. This seems simpler, but maybe in the future the already
85 extracted fields will be used. */
86
87/* Pseudo FILE object for strings. */
88typedef struct {
89 char *buffer;
90 char *current;
91} SFILE;
92
93/* sprintf to a "stream" */
94
95static int
96disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
97{
98#ifndef __STDC__
99 SFILE *f;
100 const char *format;
101#endif
102 int n;
103 va_list args;
104
105 VA_START (args, format);
106#ifndef __STDC__
107 f = va_arg (args, SFILE *);
108 format = va_arg (args, char *);
109#endif
110 vsprintf (f->current, format, args);
111 f->current += n = strlen (f->current);
112 va_end (args);
113 return n;
114}
115
116void
260b2c47
DE
117sim_disassemble_insn (SIM_CPU *cpu, const struct cgen_insn *insn,
118 const struct argbuf *abuf, PCADDR pc, char *buf)
b9c8cd10 119{
b500809f 120 unsigned int length;
b9c8cd10
DE
121 unsigned long insn_value;
122 struct disassemble_info disasm_info;
123 struct cgen_fields fields;
124 SFILE sfile;
b500809f
DE
125 union {
126 unsigned8 bytes[16];
127 unsigned16 shorts[8];
128 unsigned32 words[4];
129 } insn_buf;
260b2c47 130 SIM_DESC sd = CPU_STATE (cpu);
b9c8cd10
DE
131
132 sfile.buffer = sfile.current = buf;
133 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
134 (fprintf_ftype) disasm_sprintf);
135 disasm_info.endian =
260b2c47
DE
136 (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
137 : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
b9c8cd10
DE
138 : BFD_ENDIAN_UNKNOWN);
139
b500809f
DE
140 length = sim_core_read_buffer (sd, cpu, sim_core_read_map, &insn_buf, pc,
141 CGEN_INSN_BITSIZE (insn) / 8);
142
143 switch (length)
b9c8cd10 144 {
b500809f
DE
145 case 1 : insn_value = insn_buf.bytes[0]; break;
146 case 2 : insn_value = T2H_2 (insn_buf.shorts[0]); break;
147 case 4 : insn_value = T2H_4 (insn_buf.words[0]); break;
148 default: abort ();
b9c8cd10
DE
149 }
150
151 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
b500809f
DE
152 /* Result of extract fn is in bits. */
153 /* ??? This assumes that each instruction has a fixed length (and thus
154 for insns with multiple versions of variable lengths they would each
155 have their own table entry). */
156 if (length == CGEN_INSN_BITSIZE (insn))
b9c8cd10
DE
157 {
158 (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length);
159 }
160 else
161 {
162 /* This shouldn't happen, but aborting is too drastic. */
163 strcpy (buf, "***unknown***");
164 }
165}
166\f
167#ifdef DI_FN_SUPPORT
168
169DI
170make_struct_di (hi, lo)
171 SI hi, lo;
172{
173 DI result;
174
175 result.hi = hi;
176 result.lo = lo;
177 return result;
178}
179
180DI
181ANDDI (a, b)
182 DI a, b;
183{
184 SI ahi = GETHIDI (a);
185 SI alo = GETLODI (a);
186 SI bhi = GETHIDI (b);
187 SI blo = GETLODI (b);
188 return MAKEDI (ahi & bhi, alo & blo);
189}
190
191DI
192ORDI (a, b)
193 DI a, b;
194{
195 SI ahi = GETHIDI (a);
196 SI alo = GETLODI (a);
197 SI bhi = GETHIDI (b);
198 SI blo = GETLODI (b);
199 return MAKEDI (ahi | bhi, alo | blo);
200}
201
202DI
203ADDDI (a, b)
204 DI a, b;
205{
206 USI ahi = GETHIDI (a);
207 USI alo = GETLODI (a);
208 USI bhi = GETHIDI (b);
209 USI blo = GETLODI (b);
210 USI x = alo + blo;
211 return MAKEDI (ahi + bhi + (x < alo), x);
212}
213
214DI
215MULDI (a, b)
216 DI a, b;
217{
218 USI ahi = GETHIDI (a);
219 USI alo = GETLODI (a);
220 USI bhi = GETHIDI (b);
221 USI blo = GETLODI (b);
222 USI rhi,rlo;
223 USI x0, x1, x2, x3;
224
225 x0 = alo * blo;
226 x1 = alo * bhi;
227 x2 = ahi * blo;
228 x3 = ahi * bhi;
229
230#define SI_TYPE_SIZE 32
231#define BITS4 (SI_TYPE_SIZE / 4)
232#define ll_B (1L << (SI_TYPE_SIZE / 2))
233#define ll_lowpart(t) ((USI) (t) % ll_B)
234#define ll_highpart(t) ((USI) (t) / ll_B)
235 x1 += ll_highpart (x0); /* this can't give carry */
236 x1 += x2; /* but this indeed can */
237 if (x1 < x2) /* did we get it? */
238 x3 += ll_B; /* yes, add it in the proper pos. */
239
240 rhi = x3 + ll_highpart (x1);
241 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
242 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
243}
244
245DI
246SHLDI (val, shift)
247 DI val;
248 SI shift;
249{
250 USI hi = GETHIDI (val);
251 USI lo = GETLODI (val);
252 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
253 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
254}
255
256DI
257SLADI (val, shift)
258 DI val;
259 SI shift;
260{
261 SI hi = GETHIDI (val);
262 USI lo = GETLODI (val);
263 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
264 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
265}
266
267DI
268SRADI (val, shift)
269 DI val;
270 SI shift;
271{
272 SI hi = GETHIDI (val);
273 USI lo = GETLODI (val);
274 /* We use SRASI because the result is implementation defined if hi < 0. */
275 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
276 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
277}
278
279int
280GEDI (a, b)
281 DI a, b;
282{
283 SI ahi = GETHIDI (a);
284 USI alo = GETLODI (a);
285 SI bhi = GETHIDI (b);
286 USI blo = GETLODI (b);
287 if (ahi > bhi)
288 return 1;
289 if (ahi == bhi)
290 return alo >= blo;
291 return 0;
292}
293
294int
295LEDI (a, b)
296 DI a, b;
297{
298 SI ahi = GETHIDI (a);
299 USI alo = GETLODI (a);
300 SI bhi = GETHIDI (b);
301 USI blo = GETLODI (b);
302 if (ahi < bhi)
303 return 1;
304 if (ahi == bhi)
305 return alo <= blo;
306 return 0;
307}
308
309DI
310CONVHIDI (val)
311 HI val;
312{
313 if (val < 0)
314 return MAKEDI (-1, val);
315 else
316 return MAKEDI (0, val);
317}
318
319DI
320CONVSIDI (val)
321 SI val;
322{
323 if (val < 0)
324 return MAKEDI (-1, val);
325 else
326 return MAKEDI (0, val);
327}
328
329SI
330CONVDISI (val)
331 DI val;
332{
333 return GETLODI (val);
334}
335
336#endif /* DI_FN_SUPPORT */
This page took 0.081089 seconds and 4 git commands to generate.