* mn10300.igen (OP_F0F4): Need to load contents of register AN0
[platform/upstream/binutils.git] / gdb / i386gnu-nat.c
1 /* Low level interface to I386 running the GNU Hurd
2    Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "inferior.h"
22 #include "floatformat.h"
23
24 #include <stdio.h>
25 #include <errno.h>
26
27 #include <mach.h>
28 #include <mach/message.h>
29 #include <mach/exception.h>
30 #include <mach_error.h>
31
32 #include "gnu-nat.h"
33
34 /* Hmmm... Should this not be here?
35  * Now for i386_float_info() target_has_execution
36  */
37 #include <target.h>
38
39 /* @@@ Should move print_387_status() to i387-tdep.c */
40 extern void print_387_control_word ();          /* i387-tdep.h */
41 extern void print_387_status_word ();
42 \f
43 /* Find offsets to thread states at compile time.
44  * If your compiler does not grok this, calculate offsets
45  * offsets yourself and use them (or get a compatible compiler :-)
46  */
47
48 #define  REG_OFFSET(reg) (int)(&((struct i386_thread_state *)0)->reg)
49
50 /* at reg_offset[i] is the offset to the i386_thread_state
51  * location where the gdb registers[i] is stored.
52  */
53
54 static int reg_offset[] = 
55 {
56   REG_OFFSET(eax),  REG_OFFSET(ecx), REG_OFFSET(edx), REG_OFFSET(ebx),
57   REG_OFFSET(uesp), REG_OFFSET(ebp), REG_OFFSET(esi), REG_OFFSET(edi),
58   REG_OFFSET(eip),  REG_OFFSET(efl), REG_OFFSET(cs),  REG_OFFSET(ss),
59   REG_OFFSET(ds),   REG_OFFSET(es),  REG_OFFSET(fs),  REG_OFFSET(gs)
60 };
61
62 #define REG_ADDR(state,regnum) ((char *)(state)+reg_offset[regnum])
63
64 /* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
65  * Caller knows that the regs handled in one transaction are of same size.
66  */
67 #define FETCH_REGS(state, regnum, count) \
68   memcpy (&registers[REGISTER_BYTE (regnum)], \
69           REG_ADDR (state, regnum), \
70           count * REGISTER_RAW_SIZE (regnum))
71
72 /* Store COUNT contiguous registers to thread STATE starting from REGNUM */
73 #define STORE_REGS(state, regnum, count) \
74   memcpy (REG_ADDR (state, regnum), \
75           &registers[REGISTER_BYTE (regnum)], \
76           count * REGISTER_RAW_SIZE (regnum))
77 \f
78 /*
79  * Fetch inferiors registers for gdb.
80  * REG specifies which (as gdb views it) register, -1 for all.
81  */
82 void
83 gnu_fetch_registers (int reg)
84 {
85   struct proc *thread;
86   thread_state_t state;
87   
88   inf_update_procs (current_inferior); /* Make sure we know about new threads.  */
89
90   thread = inf_tid_to_thread (current_inferior, inferior_pid);
91   if (! thread)
92     error ("fetch inferior registers: %d: Invalid thread", inferior_pid);
93
94   state = proc_get_state (thread, 0);
95
96   if (! state)
97     warning ("Couldn't fetch register %s from %s (invalid thread).",
98              reg_names[reg], proc_string (thread));
99   else if (reg >= 0)
100     {
101       proc_debug (thread, "fetching register: %s", reg_names[reg]);
102       supply_register (reg, REG_ADDR(state, reg));
103       thread->fetched_regs |= (1 << reg);
104     }
105   else
106     {
107       proc_debug (thread, "fetching all registers");
108       for (reg = 0; reg < NUM_REGS; reg++) 
109         supply_register (reg, REG_ADDR(state, reg));
110       thread->fetched_regs = ~0;
111     }
112 }
113 \f
114 /* Store our register values back into the inferior.
115  * If REG is -1, do this for all registers.
116  * Otherwise, REG specifies which register
117  *
118  * On mach3 all registers are always saved in one call.
119  */
120 void
121 gnu_store_registers (reg)
122      int reg;
123 {
124   struct proc *thread;
125   int was_aborted, was_valid;
126   thread_state_t state;
127   thread_state_data_t old_state;
128   
129   inf_update_procs (current_inferior); /* Make sure we know about new threads.  */
130
131   thread = inf_tid_to_thread (current_inferior, inferior_pid);
132   if (! thread)
133     error ("store inferior registers: %d: Invalid thread", inferior_pid);
134
135   proc_debug (thread, "storing register %s.", reg_names[reg]);
136
137   was_aborted = thread->aborted;
138   was_valid = thread->state_valid;
139   if (! was_aborted && was_valid)
140     bcopy (&thread->state, &old_state, sizeof (old_state));
141
142   state = proc_get_state (thread, 1);
143
144   if (! state)
145     warning ("Couldn't store register %s from %s (invalid thread).",
146              reg_names[reg], proc_string (thread));
147   else
148     {
149       if (! was_aborted && was_valid)
150         /* See which registers have changed after aborting the thread.  */
151         {
152           int check_reg;
153           for (check_reg = 0; check_reg < NUM_REGS; check_reg++)
154             if ((thread->fetched_regs & (1 << check_reg))
155                 && bcmp (REG_ADDR (&old_state, check_reg),
156                          REG_ADDR (state, check_reg),
157                          REGISTER_RAW_SIZE (check_reg)))
158               /* Register CHECK_REG has changed!  Ack!  */
159               {
160                 warning ("Register %s changed after thread was aborted.",
161                          reg_names [check_reg]);
162                 if (reg >= 0 && reg != check_reg)
163                   /* Update gdb's copy of the register.  */
164                   supply_register (check_reg, REG_ADDR (state, check_reg));
165                 else
166                   warning ("... also writing this register!  Suspicious...");
167               }
168         }
169
170       if (reg >= 0)
171         {
172           proc_debug (thread, "storing register: %s", reg_names[reg]);
173           STORE_REGS (state, reg, 1);
174         }
175       else
176         {
177           proc_debug (thread, "storing all registers");
178           for (reg = 0; reg < NUM_REGS; reg++) 
179             STORE_REGS (state, reg, 1);
180         }
181     }
182 }
183 \f
184 /* jtv@hut.fi: I copied and modified this 387 code from
185  * gdb/i386-xdep.c. Modifications for Mach 3.0.
186  *
187  * i387 status dumper. See also i387-tdep.c
188  */
189 struct env387 
190 {
191   unsigned short control;
192   unsigned short r0;
193   unsigned short status;
194   unsigned short r1;
195   unsigned short tag;
196   unsigned short r2;
197   unsigned long eip;
198   unsigned short code_seg;
199   unsigned short opcode;
200   unsigned long operand;
201   unsigned short operand_seg;
202   unsigned short r3;
203   unsigned char regs[8][10];
204 };
205 /* This routine is machine independent?
206  * Should move it to i387-tdep.c but you need to export struct env387
207  */
208 static
209 print_387_status (status, ep)
210      unsigned short status;
211      struct env387 *ep;
212 {
213   int i;
214   int bothstatus;
215   int top;
216   int fpreg;
217   unsigned char *p;
218   
219   bothstatus = ((status != 0) && (ep->status != 0));
220   if (status != 0) 
221     {
222       if (bothstatus)
223         printf_unfiltered ("u: ");
224       print_387_status_word (status);
225     }
226   
227   if (ep->status != 0) 
228     {
229       if (bothstatus)
230         printf_unfiltered ("e: ");
231       print_387_status_word (ep->status);
232     }
233   
234   print_387_control_word (ep->control);
235   printf_unfiltered ("last exception: ");
236   printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
237   printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
238   printf_unfiltered ("%s; ", local_hex_string(ep->eip));
239   printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg));
240   printf_unfiltered (":%s\n", local_hex_string(ep->operand));
241   
242   top = (ep->status >> 11) & 7;
243   
244   printf_unfiltered ("regno  tag  msb              lsb  value\n");
245   for (fpreg = 7; fpreg >= 0; fpreg--) 
246     {
247       double val;
248       
249       printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
250       
251       switch ((ep->tag >> (fpreg * 2)) & 3) 
252         {
253         case 0: printf_unfiltered ("valid "); break;
254         case 1: printf_unfiltered ("zero  "); break;
255         case 2: printf_unfiltered ("trap  "); break;
256         case 3: printf_unfiltered ("empty "); break;
257         }
258       for (i = 9; i >= 0; i--)
259         printf_unfiltered ("%02x", ep->regs[fpreg][i]);
260       
261       floatformat_to_double (&floatformat_i387_ext, (char *)ep->regs[fpreg],
262                                &val);
263       printf_unfiltered ("  %g\n", val);
264     }
265   if (ep->r0)
266     printf_unfiltered ("warning: reserved0 is %s\n", local_hex_string(ep->r0));
267   if (ep->r1)
268     printf_unfiltered ("warning: reserved1 is %s\n", local_hex_string(ep->r1));
269   if (ep->r2)
270     printf_unfiltered ("warning: reserved2 is %s\n", local_hex_string(ep->r2));
271   if (ep->r3)
272     printf_unfiltered ("warning: reserved3 is %s\n", local_hex_string(ep->r3));
273 }
274         
275 /*
276  * values that go into fp_kind (from <i386/fpreg.h>)
277  */
278 #define FP_NO   0       /* no fp chip, no emulator (no fp support)      */
279 #define FP_SW   1       /* no fp chip, using software emulator          */
280 #define FP_HW   2       /* chip present bit                             */
281 #define FP_287  2       /* 80287 chip present                           */
282 #define FP_387  3       /* 80387 chip present                           */
283
284 typedef struct fpstate {
285 #if 1
286   unsigned char state[FP_STATE_BYTES]; /* "hardware" state */
287 #else
288   struct env387 state;  /* Actually this */
289 #endif
290   int status;           /* Duplicate status */
291 } *fpstate_t;
292
293 /* Mach 3 specific routines.
294  */
295 static int
296 get_i387_state (fstate)
297      struct fpstate *fstate;
298 {
299   error_t err;
300   thread_state_data_t state;
301   unsigned int fsCnt = i386_FLOAT_STATE_COUNT;
302   struct i386_float_state *fsp;
303   struct proc *thread = inf_tid_to_thread (current_inferior, inferior_pid);
304   
305   if (!thread)
306     error ("get_i387_state: Invalid thread");
307
308   proc_abort (thread, 0);       /* Make sure THREAD's in a reasonable state. */
309
310   err = thread_get_state (thread->port, i386_FLOAT_STATE, state, &fsCnt);
311   if (err)
312     {
313       warning ("Can not get live floating point state: %s",
314                mach_error_string (err));
315       return 0;
316     }
317
318   fsp = (struct i386_float_state *)state;
319   /* The 387 chip (also 486 counts) or a software emulator? */
320   if (!fsp->initialized || (fsp->fpkind != FP_387 && fsp->fpkind != FP_SW))
321     return 0;
322
323   /* Clear the target then copy thread's float state there.
324      Make a copy of the status word, for some reason?
325    */
326   memset (fstate, 0, sizeof (struct fpstate));
327
328   fstate->status = fsp->exc_status;
329
330   memcpy (fstate->state, (char *)&fsp->hw_state, FP_STATE_BYTES);
331
332   return 1;
333 }
334
335 /*
336  * This is called by "info float" command
337  */
338 void
339 i386_mach3_float_info()
340 {
341   char buf [sizeof (struct fpstate) + 2 * sizeof (int)];
342   int valid = 0;
343   fpstate_t fps;
344   
345   if (target_has_execution)
346     valid = get_i387_state (buf);
347
348   if (!valid) 
349     {
350       warning ("no floating point status saved");
351       return;
352     }
353   
354   fps = (fpstate_t) buf;
355
356   print_387_status (fps->status, (struct env387 *)fps->state);
357 }