sim: ft32: correct simulation of MEMCPY and MEMSET
[deliverable/binutils-gdb.git] / gdb / m32r-linux-nat.c
CommitLineData
9b32d526
KI
1/* Native-dependent code for GNU/Linux m32r.
2
32d0add0 3 Copyright (C) 2004-2015 Free Software Foundation, Inc.
9b32d526
KI
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
9b32d526
KI
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9b32d526
KI
19
20#include "defs.h"
21#include "inferior.h"
22#include "gdbcore.h"
23#include "regcache.h"
24#include "linux-nat.h"
10d6c8cd 25#include "target.h"
5826e159 26#include "nat/gdb_ptrace.h"
9b32d526
KI
27#include <sys/user.h>
28#include <sys/procfs.h>
29
30/* Prototypes for supply_gregset etc. */
31#include "gregset.h"
32
33#include "m32r-tdep.h"
34\f
35
36
37
38/* Since EVB register is not available for native debug, we reduce
39 the number of registers. */
40#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
41
42/* Mapping between the general-purpose registers in `struct user'
43 format and GDB's register array layout. */
44static int regmap[] = {
45 4, 5, 6, 7, 0, 1, 2, 8,
46 9, 10, 11, 12, 13, 24, 25, 23,
47 19, 19, 26, 23, 22, 20, 16, 15
48};
49
50#define PSW_REGMAP 19
51#define BBPSW_REGMAP 21
52#define SPU_REGMAP 23
53#define SPI_REGMAP 26
54
025bb325
MS
55/* Doee (??) apply to the corresponding SET requests as well. */
56#define GETREGS_SUPPLIES(regno) (0 <= (regno) \
57 && (regno) <= M32R_LINUX_NUM_REGS)
9b32d526
KI
58\f
59
60
61/* Transfering the general-purpose registers between GDB, inferiors
62 and core files. */
63
64/* Fill GDB's register array with the general-purpose register values
65 in *GREGSETP. */
66
67void
7f7fe91e 68supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
9b32d526 69{
7f7fe91e 70 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
9b32d526
KI
71 int i;
72 unsigned long psw, bbpsw;
73
74 psw = *(regp + PSW_REGMAP);
75 bbpsw = *(regp + BBPSW_REGMAP);
76
77 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
78 {
d817e083
UW
79 elf_greg_t regval;
80
9b32d526
KI
81 switch (i)
82 {
83 case PSW_REGNUM:
d817e083 84 regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
9b32d526
KI
85 break;
86 case CBR_REGNUM:
d817e083
UW
87 regval = ((psw >> 8) & 1);
88 break;
89 default:
90 regval = *(regp + regmap[i]);
9b32d526
KI
91 break;
92 }
93
94 if (i != M32R_SP_REGNUM)
7f7fe91e 95 regcache_raw_supply (regcache, i, &regval);
9b32d526 96 else if (psw & 0x8000)
7f7fe91e 97 regcache_raw_supply (regcache, i, regp + SPU_REGMAP);
9b32d526 98 else
7f7fe91e 99 regcache_raw_supply (regcache, i, regp + SPI_REGMAP);
9b32d526
KI
100 }
101}
102
103/* Fetch all general-purpose registers from process/thread TID and
104 store their values in GDB's register array. */
105
106static void
56be3814 107fetch_regs (struct regcache *regcache, int tid)
9b32d526
KI
108{
109 elf_gregset_t regs;
110
111 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 112 perror_with_name (_("Couldn't get registers"));
9b32d526 113
56be3814 114 supply_gregset (regcache, (const elf_gregset_t *) &regs);
9b32d526
KI
115}
116
117/* Fill register REGNO (if it is a general-purpose register) in
118 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
119 do this for all registers. */
120
121void
7f7fe91e
UW
122fill_gregset (const struct regcache *regcache,
123 elf_gregset_t * gregsetp, int regno)
9b32d526
KI
124{
125 elf_greg_t *regp = (elf_greg_t *) gregsetp;
126 int i;
127 unsigned long psw, bbpsw, tmp;
128
129 psw = *(regp + PSW_REGMAP);
130 bbpsw = *(regp + BBPSW_REGMAP);
131
132 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
133 {
134 if (regno != -1 && regno != i)
135 continue;
136
137 if (i == CBR_REGNUM || i == PSW_REGNUM)
138 continue;
139
140 if (i == SPU_REGNUM || i == SPI_REGNUM)
141 continue;
142
143 if (i != M32R_SP_REGNUM)
7f7fe91e 144 regcache_raw_collect (regcache, i, regp + regmap[i]);
9b32d526 145 else if (psw & 0x8000)
7f7fe91e 146 regcache_raw_collect (regcache, i, regp + SPU_REGMAP);
9b32d526 147 else
7f7fe91e 148 regcache_raw_collect (regcache, i, regp + SPI_REGMAP);
9b32d526
KI
149 }
150}
151
152/* Store all valid general-purpose registers in GDB's register array
153 into the process/thread specified by TID. */
154
155static void
56be3814 156store_regs (const struct regcache *regcache, int tid, int regno)
9b32d526
KI
157{
158 elf_gregset_t regs;
159
160 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 161 perror_with_name (_("Couldn't get registers"));
9b32d526 162
56be3814 163 fill_gregset (regcache, &regs, regno);
9b32d526
KI
164
165 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 166 perror_with_name (_("Couldn't write registers"));
9b32d526
KI
167}
168\f
169
170
171/* Transfering floating-point registers between GDB, inferiors and cores.
172 Since M32R has no floating-point registers, these functions do nothing. */
173
174void
7f7fe91e 175supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
9b32d526
KI
176{
177}
178
179void
7f7fe91e
UW
180fill_fpregset (const struct regcache *regcache,
181 gdb_fpregset_t *fpregs, int regno)
9b32d526
KI
182{
183}
184\f
185
186
187/* Transferring arbitrary registers between GDB and inferior. */
188
189/* Fetch register REGNO from the child process. If REGNO is -1, do
190 this for all registers (including the floating point and SSE
191 registers). */
192
10d6c8cd 193static void
28439f5e
PA
194m32r_linux_fetch_inferior_registers (struct target_ops *ops,
195 struct regcache *regcache, int regno)
9b32d526
KI
196{
197 int tid;
198
199 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 200 tid = ptid_get_lwp (inferior_ptid);
9b32d526 201 if (tid == 0)
dfd4cc63 202 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
9b32d526
KI
203
204 /* Use the PTRACE_GETREGS request whenever possible, since it
205 transfers more registers in one system call, and we'll cache the
206 results. */
207 if (regno == -1 || GETREGS_SUPPLIES (regno))
208 {
56be3814 209 fetch_regs (regcache, tid);
9b32d526
KI
210 return;
211 }
212
213 internal_error (__FILE__, __LINE__,
e2e0b3e5 214 _("Got request for bad register number %d."), regno);
9b32d526
KI
215}
216
217/* Store register REGNO back into the child process. If REGNO is -1,
218 do this for all registers (including the floating point and SSE
219 registers). */
10d6c8cd 220static void
28439f5e
PA
221m32r_linux_store_inferior_registers (struct target_ops *ops,
222 struct regcache *regcache, int regno)
9b32d526
KI
223{
224 int tid;
225
226 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63
LM
227 if ((tid = ptid_get_lwp (inferior_ptid)) == 0)
228 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
9b32d526
KI
229
230 /* Use the PTRACE_SETREGS request whenever possible, since it
231 transfers more registers in one system call. */
232 if (regno == -1 || GETREGS_SUPPLIES (regno))
233 {
56be3814 234 store_regs (regcache, tid, regno);
9b32d526
KI
235 return;
236 }
237
238 internal_error (__FILE__, __LINE__,
e2e0b3e5 239 _("Got request to store bad register number %d."), regno);
9b32d526 240}
10d6c8cd
DJ
241
242void _initialize_m32r_linux_nat (void);
243
244void
245_initialize_m32r_linux_nat (void)
246{
247 struct target_ops *t;
248
249 /* Fill in the generic GNU/Linux methods. */
250 t = linux_target ();
251
252 /* Add our register access methods. */
253 t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
254 t->to_store_registers = m32r_linux_store_inferior_registers;
255
256 /* Register the target. */
f973ed9c 257 linux_nat_add_target (t);
10d6c8cd 258}
This page took 0.869042 seconds and 4 git commands to generate.