Update FSF address.
[external/binutils.git] / gdb / remote-vxsparc.c
1 /* sparc-dependent portions of the RPC protocol
2    used with a VxWorks target 
3
4 Contributed by Wind River Systems.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include <stdio.h>
23 #include "defs.h"
24
25 #include "vx-share/regPacket.h"  
26 #include "frame.h"
27 #include "inferior.h"
28 #include "wait.h"
29 #include "target.h"
30 #include "gdbcore.h"
31 #include "command.h"
32 #include "symtab.h"
33 #include "symfile.h"            /* for struct complaint */
34
35 #include "gdb_string.h"
36 #include <errno.h>
37 #include <signal.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/time.h>
41 #include <sys/socket.h>
42
43 #ifdef _AIX                     /* IBM claims "void *malloc()" not char * */
44 #define malloc bogon_malloc
45 #endif
46
47 #include <rpc/rpc.h>
48 #include <sys/time.h>           /* UTek's <rpc/rpc.h> doesn't #incl this */
49 #include <netdb.h>
50 #include "vx-share/ptrace.h"
51 #include "vx-share/xdr_ptrace.h"
52 #include "vx-share/xdr_ld.h"
53 #include "vx-share/xdr_rdb.h"
54 #include "vx-share/dbgRpcLib.h"
55
56 /* get rid of value.h if possible */
57 #include <value.h>
58 #include <symtab.h>
59
60 /* Flag set if target has fpu */
61
62 extern int target_has_fp;
63
64 /* sparc floating point format descriptor, from "sparc-tdep.c."  */
65
66 extern struct ext_format ext_format_sparc;
67
68 /* Generic register read/write routines in remote-vx.c.  */
69
70 extern void net_read_registers ();
71 extern void net_write_registers ();
72
73 /* Read a register or registers from the VxWorks target.
74    REGNO is the register to read, or -1 for all; currently,
75    it is ignored.  FIXME look at regno to improve efficiency.  */
76
77 void
78 vx_read_register (regno)
79      int regno;
80 {
81   char sparc_greg_packet[SPARC_GREG_PLEN];
82   char sparc_fpreg_packet[SPARC_FPREG_PLEN];
83   CORE_ADDR sp;
84
85   /* Get general-purpose registers.  When copying values into
86      registers [], don't assume that a location in registers []
87      is properly aligned for the target data type.  */
88
89   net_read_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_GETREGS);
90
91   /* Now copy the register values into registers[].
92      Note that this code depends on the ordering of the REGNUMs
93      as defined in "tm-sparc.h".  */
94
95   bcopy (&sparc_greg_packet[SPARC_R_G0],
96          &registers[REGISTER_BYTE (G0_REGNUM)], 32 * SPARC_GREG_SIZE);
97   bcopy (&sparc_greg_packet[SPARC_R_Y],
98          &registers[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE);
99
100   /* Now write the local and in registers to the register window
101      spill area in the frame.  VxWorks does not do this for the
102      active frame automatically; it greatly simplifies debugging
103      (FRAME_FIND_SAVED_REGS, in particular, depends on this).  */
104
105   sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)], 
106         REGISTER_RAW_SIZE (CORE_ADDR));
107   write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
108                 16 * REGISTER_RAW_SIZE (L0_REGNUM));
109
110   /* If the target has floating point registers, fetch them.
111      Otherwise, zero the floating point register values in
112      registers[] for good measure, even though we might not
113      need to.  */
114
115   if (target_has_fp)
116     {
117       net_read_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
118                           PTRACE_GETFPREGS);
119       bcopy (&sparc_fpreg_packet[SPARC_R_FP0], 
120              &registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
121       bcopy (&sparc_fpreg_packet[SPARC_R_FSR],
122              &registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
123     }
124   else
125     { 
126       bzero (&registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
127       bzero (&registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
128     }
129
130   /* Mark the register cache valid.  */
131
132   registers_fetched ();
133 }
134
135 /* Store a register or registers into the VxWorks target.
136    REGNO is the register to store, or -1 for all; currently,
137    it is ignored.  FIXME look at regno to improve efficiency.  */
138
139 void
140 vx_write_register (regno)
141      int regno;
142 {
143   char sparc_greg_packet[SPARC_GREG_PLEN];
144   char sparc_fpreg_packet[SPARC_FPREG_PLEN];
145   int in_gp_regs;
146   int in_fp_regs;
147   CORE_ADDR sp;
148
149   /* Store general purpose registers.  When copying values from
150      registers [], don't assume that a location in registers []
151      is properly aligned for the target data type.  */
152
153   in_gp_regs = 1;
154   in_fp_regs = 1;
155   if (regno >= 0)
156     {
157       if ((G0_REGNUM <= regno && regno <= I7_REGNUM)
158           || (Y_REGNUM <= regno && regno <= NPC_REGNUM))
159         in_fp_regs = 0;
160       else
161         in_gp_regs = 0;
162     }
163   if (in_gp_regs)
164     {
165       bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
166              &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE);
167       bcopy (&registers[REGISTER_BYTE (Y_REGNUM)],
168              &sparc_greg_packet[SPARC_R_Y], 6 * SPARC_GREG_SIZE);
169
170       net_write_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_SETREGS);
171
172       /* If this is a local or in register, or we're storing all
173          registers, update the register window spill area.  */
174
175       if (regno < 0 || (L0_REGNUM <= regno && regno <= I7_REGNUM))
176         {
177           sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)], 
178                 REGISTER_RAW_SIZE (CORE_ADDR));
179           write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
180                         16 * REGISTER_RAW_SIZE (L0_REGNUM));
181         }
182     }
183
184   /* Store floating point registers if the target has them.  */
185
186   if (in_fp_regs && target_has_fp)
187     {
188       bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], 
189              &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE);
190       bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)], 
191              &sparc_fpreg_packet[SPARC_R_FSR], 1 * SPARC_FPREG_SIZE);
192
193       net_write_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
194                            PTRACE_SETFPREGS);
195     }
196 }
197
198 /* Convert from an extended float to a double.
199    The extended float is stored as raw data pointed to by FROM.
200    Return the converted value as raw data in the double pointed to by TO.  */
201
202 void
203 vx_convert_to_virtual (regno, from, to)
204      int regno;
205      char *from;
206      char *to;
207 {
208   if (REGISTER_CONVERTIBLE (regno)) 
209     {
210       if (target_has_fp)
211         ieee_extended_to_double (&ext_format_sparc, from, to);
212       else
213         bzero (to, sizeof (double));
214     }
215   else
216     bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
217 }
218
219 /* The converse:  convert from a double to an extended float.
220    The double is stored as raw data pointed to by FROM.
221    Return the converted value as raw data in the extended
222    float pointed to by TO.  */
223
224 void
225 vx_convert_from_virtual (regno, from, to)
226      int regno;
227      char *from;
228      char *to;
229 {
230   if (REGISTER_CONVERTIBLE (regno)) 
231     {
232       if (target_has_fp)
233         double_to_ieee_extended (&ext_format_sparc, from, to);
234       else
235         bzero (to, REGISTER_RAW_SIZE (FP0_REGNUM));
236     }
237   else
238     bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
239 }