]> Git Repo - binutils.git/blob - sim/ppc/emul_generic.c
More scheduling stuff
[binutils.git] / sim / ppc / emul_generic.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1995, Andrew Cagney <[email protected]>
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_ */
This page took 0.03728 seconds and 4 git commands to generate.