* elf32-m32c.c (m32c_elf_relax_delete_bytes): Adjust symbol sizes
[deliverable/binutils-gdb.git] / sim / m32c / mem.c
CommitLineData
d45a4bef
JB
1/* mem.c --- memory for M32C simulator.
2
e4d013fc 3Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
d45a4bef
JB
4Contributed by Red Hat, Inc.
5
6This file is part of the GNU simulators.
7
4744ac1b
JB
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
d45a4bef 12
4744ac1b
JB
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
d45a4bef
JB
17
18You should have received a copy of the GNU General Public License
4744ac1b 19along with this program. If not, see <http://www.gnu.org/licenses/>. */
d45a4bef
JB
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
3877a145
DD
25#include <ctype.h>
26#include <sys/time.h>
27#include <sys/types.h>
28#include <unistd.h>
29#include <sys/select.h>
30#include <termios.h>
d45a4bef
JB
31
32#include "mem.h"
33#include "cpu.h"
34#include "syscalls.h"
35#include "misc.h"
3877a145
DD
36#ifdef TIMER_A
37#include "int.h"
38#include "timer_a.h"
39#endif
d45a4bef
JB
40
41#define L1_BITS (10)
42#define L2_BITS (10)
43#define OFF_BITS (12)
44
45#define L1_LEN (1 << L1_BITS)
46#define L2_LEN (1 << L2_BITS)
47#define OFF_LEN (1 << OFF_BITS)
48
49static unsigned char **pt[L1_LEN];
50
3877a145
DD
51int m32c_console_ifd = 0;
52int m32c_console_ofd = 1;
e7ddc197 53int m32c_use_raw_console = 0;
3877a145
DD
54
55#ifdef TIMER_A
56Timer_A timer_a;
57#endif
58
d45a4bef 59/* [ get=0/put=1 ][ byte size ] */
3877a145 60static unsigned int mem_counters[2][5];
d45a4bef
JB
61
62#define COUNT(isput,bytes) \
63 if (verbose && enable_counting) mem_counters[isput][bytes]++
64
65void
66init_mem (void)
67{
68 int i, j;
69
70 for (i = 0; i < L1_LEN; i++)
71 if (pt[i])
72 {
73 for (j = 0; j < L2_LEN; j++)
74 if (pt[i][j])
75 free (pt[i][j]);
76 free (pt[i]);
77 }
78 memset (pt, 0, sizeof (pt));
79 memset (mem_counters, 0, sizeof (mem_counters));
80}
81
82static unsigned char *
83mem_ptr (address)
84{
3877a145 85 static int recursing = 0;
d45a4bef
JB
86 int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
87 int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
88 int pto = address & ((1 << OFF_BITS) - 1);
89
3877a145 90 if (address == 0 && !recursing)
d45a4bef 91 {
3877a145
DD
92 recursing = 1;
93 put_reg (pc, m32c_opcode_pc);
94 printf ("NULL pointer dereference at pc=0x%x\n", get_reg (pc));
95 step_result = M32C_MAKE_HIT_BREAK ();
96#if 0
97 /* This code can be re-enabled to help diagnose NULL pointer
98 bugs that aren't debuggable in GDB. */
99 m32c_dump_all_registers ();
d45a4bef 100 exit (1);
3877a145 101#endif
d45a4bef
JB
102 }
103
104 if (pt[pt1] == 0)
105 pt[pt1] = (unsigned char **) calloc (L2_LEN, sizeof (char **));
106 if (pt[pt1][pt2] == 0)
107 {
108 pt[pt1][pt2] = (unsigned char *) malloc (OFF_LEN);
109 memset (pt[pt1][pt2], 0, OFF_LEN);
110 }
111
112 return pt[pt1][pt2] + pto;
113}
114
115static void
116used (int rstart, int i, int j)
117{
118 int rend = i << (L2_BITS + OFF_BITS);
119 rend += j << OFF_BITS;
120 if (rstart == 0xe0000 && rend == 0xe1000)
121 return;
122 printf ("mem: %08x - %08x (%dk bytes)\n", rstart, rend - 1,
123 (rend - rstart) / 1024);
124}
125
126static char *
127mcs (int isput, int bytes)
128{
129 return comma (mem_counters[isput][bytes]);
130}
131
132void
133mem_usage_stats ()
134{
135 int i, j;
136 int rstart = 0;
137 int pending = 0;
138
139 for (i = 0; i < L1_LEN; i++)
140 if (pt[i])
141 {
142 for (j = 0; j < L2_LEN; j++)
143 if (pt[i][j])
144 {
145 if (!pending)
146 {
147 pending = 1;
148 rstart = (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS);
149 }
150 }
151 else if (pending)
152 {
153 pending = 0;
154 used (rstart, i, j);
155 }
156 }
157 else
158 {
159 if (pending)
160 {
161 pending = 0;
162 used (rstart, i, 0);
163 }
164 }
165 /* mem foo: 123456789012 123456789012 123456789012 123456789012
166 123456789012 */
167 printf (" byte short pointer long"
3877a145 168 " fetch\n");
d45a4bef
JB
169 printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
170 mcs (0, 3), mcs (0, 4), mcs (0, 0));
171 printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
172 mcs (1, 3), mcs (1, 4));
173}
174
175static int tpr = 0;
176static void
177s (int address, char *dir)
178{
179 if (tpr == 0)
180 printf ("MEM[%0*x] %s", membus_mask == 0xfffff ? 5 : 6, address, dir);
181 tpr++;
182}
183
184#define S(d) if (trace) s(address, d)
185static void
186e ()
187{
188 if (!trace)
189 return;
190 tpr--;
191 if (tpr == 0)
192 printf ("\n");
193}
194
195#define E() if (trace) e()
196
3877a145
DD
197extern int m32c_disassemble;
198
d45a4bef
JB
199void
200mem_put_byte (int address, unsigned char value)
201{
202 unsigned char *m;
203 address &= membus_mask;
204 m = mem_ptr (address);
205 if (trace)
206 printf (" %02x", value);
207 *m = value;
208 switch (address)
209 {
210 case 0x00e1:
211 {
212 static int old_led = -1;
213 static char *led_on[] =
214 { "\033[31m O ", "\033[32m O ", "\033[34m O " };