]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/emul_generic.c
first stage in function unit support; add new switches & latest code from andrew
[thirdparty/binutils-gdb.git] / sim / ppc / emul_generic.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 ----
20
21 Code to output system call traces Copyright (C) 1991 Gordon Irlam.
22 All rights reserved.
23
24 This tool is part of the Spa(7) package. The Spa(7) package
25 may be redistributed and/or modified under the terms of the
26 GNU General Public License Version 2 (GPL(7)) as published
27 by the Free Software Foundation.
28
29 */
30
31
32 #ifndef _EMUL_GENERIC_C_
33 #define _EMUL_GENERIC_C_
34
35 #include "emul_generic.h"
36
37 #ifndef STATIC_INLINE_EMUL_GENERIC
38 #define STATIC_INLINE_EMUL_GENERIC STATIC_INLINE
39 #endif
40
41
42 INLINE_EMUL_GENERIC void
43 emul_enter_call(emulation *emul,
44 int call,
45 int arg0,
46 cpu *processor,
47 unsigned_word cia)
48 {
49 printf_filtered("%d:0x%x:%s(",
50 cpu_nr(processor) + 1,
51 cia,
52 emul->call_descriptor[call].name);
53 }
54
55
56 INLINE_EMUL_GENERIC void
57 emul_exit_call(emulation *emul,
58 int call,
59 int arg0,
60 cpu *processor,
61 unsigned_word cia)
62 {
63 int status = cpu_registers(processor)->gpr[3];
64 int error = cpu_registers(processor)->gpr[0];
65 printf_filtered(")=%d", status);
66 if (error > 0 && error < emul->nr_error_names)
67 printf_filtered("[%s]",
68 emul->error_names[cpu_registers(processor)->gpr[0]]);
69 printf_filtered("\n");
70 }
71
72
73 INLINE_EMUL_GENERIC unsigned64
74 emul_read_gpr64(cpu *processor,
75 int g)
76 {
77 unsigned32 hi;
78 unsigned32 lo;
79 if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
80 hi = cpu_registers(processor)->gpr[g];
81 lo = cpu_registers(processor)->gpr[g+1];
82 }
83 else {
84 lo = cpu_registers(processor)->gpr[g];
85 hi = cpu_registers(processor)->gpr[g+1];
86 }
87 return (INSERTED64(hi, 0, 31) | INSERTED64(lo, 32, 63));
88 }
89
90
91 INLINE_EMUL_GENERIC void
92 emul_write_gpr64(cpu *processor,
93 int g,
94 unsigned64 val)
95 {
96 unsigned32 hi = EXTRACTED64(val, 0, 31);
97 unsigned32 lo = EXTRACTED64(val, 32, 63);
98 if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
99 cpu_registers(processor)->gpr[g] = hi;
100 cpu_registers(processor)->gpr[g+1] = lo;
101 }
102 else {
103 cpu_registers(processor)->gpr[g] = lo;
104 cpu_registers(processor)->gpr[g+1] = hi;
105 }
106 }
107
108
109 INLINE_EMUL_GENERIC char *
110 emul_read_string(char *dest,
111 unsigned_word addr,
112 unsigned nr_bytes,
113 cpu *processor,
114 unsigned_word cia)
115 {
116 unsigned nr_moved = 0;
117 if (addr == 0)
118 return NULL;
119 while (1) {
120 if (vm_data_map_read_buffer(cpu_data_map(processor),
121 &dest[nr_moved],
122 addr + nr_moved,
123 sizeof(dest[nr_moved]))
124 != sizeof(dest[nr_moved]))
125 return NULL;
126 if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
127 break;
128 nr_moved++;
129 }
130 dest[nr_moved] = '\0';
131 return dest;
132 }
133
134
135 INLINE_EMUL_GENERIC void
136 emul_write_status(cpu *processor,
137 int status,
138 int errno)
139 {
140 cpu_registers(processor)->gpr[3] = status;
141 if (status < 0)
142 cpu_registers(processor)->gpr[0] = errno;
143 else
144 cpu_registers(processor)->gpr[0] = 0;
145 }
146
147
148 INLINE_EMUL_GENERIC void
149 emul_write_word(unsigned_word addr,
150 unsigned_word buf,
151 cpu *processor,
152 unsigned_word cia)
153 {
154 int nr_moved;
155 H2T(buf);
156 nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
157 &buf,
158 addr,
159 sizeof(buf),
160 0/*violate_ro*/);
161 if (nr_moved != sizeof(buf)) {
162 printf_filtered("emul_write_word() write failed, %d out of %d written\n",
163 nr_moved, sizeof(buf));
164 cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
165 }
166 }
167
168
169 INLINE_EMUL_GENERIC void
170 emul_write_buffer(const void *source,
171 unsigned_word addr,
172 unsigned nr_bytes,
173 cpu *processor,
174 unsigned_word cia)
175 {
176 int nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
177 source,
178 addr,
179 nr_bytes,
180 0/*violate_ro*/);
181 if (nr_moved != nr_bytes) {
182 printf_filtered("emul_write_buffer() write failed %d out of %d written\n",
183 nr_moved, nr_bytes);
184 cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
185 }
186 }
187
188
189 INLINE_EMUL_GENERIC void
190 emul_read_buffer(void *dest,
191 unsigned_word addr,
192 unsigned nr_bytes,
193 cpu *processor,
194 unsigned_word cia)
195 {
196 int nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
197 dest,
198 addr,
199 nr_bytes);
200 if (nr_moved != nr_bytes) {
201 printf_filtered("emul_read_buffer() read failed %d out of %d read\n",
202 nr_moved, nr_bytes);
203 cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
204 }
205 }
206
207
208 INLINE_EMUL_GENERIC void
209 emul_do_call(emulation *emul,
210 unsigned call,
211 const int arg0,
212 cpu *processor,
213 unsigned_word cia)
214 {
215 emul_call_handler *handler = NULL;
216 if (call >= emul->nr_system_calls)
217 error("do_call() os_emul call %d out-of-range\n", call);
218
219 handler = emul->call_descriptor[call].handler;
220 if (handler == NULL)
221 error("do_call() unimplemented call %d\n", call);
222
223 ENTER_CALL;
224 cpu_registers(processor)->gpr[0] = 0; /* default success */
225 handler(emul, call, arg0, processor, cia);
226 EXIT_CALL;
227 }
228
229
230 #endif /* _SYSTEM_C_ */