OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [rx/] [reg.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* reg.c --- register set model for RX simulator.
2
 
3
   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
   Contributed by Red Hat, Inc.
5
 
6
   This file is part of the GNU simulators.
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 3 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, see <http://www.gnu.org/licenses/>.  */
20
 
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
 
26
#include "cpu.h"
27
#include "bfd.h"
28
#include "trace.h"
29
 
30
int verbose = 0;
31
int trace = 0;
32
int enable_counting = 0;
33
 
34
int rx_in_gdb = 1;
35
 
36
int rx_flagmask;
37
int rx_flagand;
38
int rx_flagor;
39
 
40
int rx_big_endian;
41
regs_type regs;
42
int step_result;
43
unsigned int heapbottom = 0;
44
unsigned int heaptop = 0;
45
 
46
char *reg_names[] = {
47
  /* general registers */
48
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
49
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
50
  /* control register */
51
  "psw", "pc", "usp", "fpsw", "RES", "RES", "RES", "RES",
52
  "bpsw", "bpc", "isp", "fintv", "intb", "RES", "RES", "RES",
53
  "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
54
  "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
55
  "temp", "acc", "acchi", "accmi", "acclo"
56
};
57
 
58
unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
59
unsigned int b2signbit[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
60
int b2maxsigned[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
61
int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
62
 
63
static regs_type oldregs;
64
 
65
void
66
init_regs (void)
67
{
68
  memset (&regs, 0, sizeof (regs));
69
  memset (&oldregs, 0, sizeof (oldregs));
70
}
71
 
72
static unsigned int
73
get_reg_i (int id)
74
{
75
  if (id == 0)
76
    return regs.r_psw & FLAGBIT_U ? regs.r_usp : regs.r_isp;
77
 
78
  if (id >= 1 && id <= 15)
79
    return regs.r[id];
80
 
81
  switch (id)
82
    {
83
    case psw:
84
      return regs.r_psw;
85
    case fpsw:
86
      return regs.r_fpsw;
87
    case isp:
88
      return regs.r_isp;
89
    case usp:
90
      return regs.r_usp;
91
    case bpc:
92
      return regs.r_bpc;
93
    case bpsw:
94
      return regs.r_bpsw;
95
    case fintv:
96
      return regs.r_fintv;
97
    case intb:
98
      return regs.r_intb;
99
    case pc:
100
      return regs.r_pc;
101
    case r_temp_idx:
102
      return regs.r_temp;
103
    case acchi:
104
      return (SI)(regs.r_acc >> 32);
105
    case accmi:
106
      return (SI)(regs.r_acc >> 16);
107
    case acclo:
108
      return (SI)regs.r_acc;
109
    }
110
  abort();
111
}
112
 
113
unsigned int
114
get_reg (int id)
115
{
116
  unsigned int rv = get_reg_i (id);
117
  if (trace > ((id != pc && id != sp) ? 0 : 1))
118
    printf ("get_reg (%s) = %08x\n", reg_names[id], rv);
119
  return rv;
120
}
121
 
122
static unsigned long long
123
get_reg64_i (int id)
124
{
125
  switch (id)
126
    {
127
    case acc64:
128
      return regs.r_acc;
129
    default:
130
      abort ();
131
    }
132
}
133
 
134
unsigned long long
135
get_reg64 (int id)
136
{
137
  unsigned long long rv = get_reg64_i (id);
138
  if (trace > ((id != pc && id != sp) ? 0 : 1))
139
    printf ("get_reg (%s) = %016llx\n", reg_names[id], rv);
140
  return rv;
141
}
142
 
143
static int highest_sp = 0, lowest_sp = 0xffffff;
144
 
145
void
146
stack_heap_stats ()
147
{
148
  if (heapbottom < heaptop)
149
    printf ("heap:  %08x - %08x (%d bytes)\n", heapbottom, heaptop,
150
            heaptop - heapbottom);
151
  if (lowest_sp < highest_sp)
152
    printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp, highest_sp,
153
            highest_sp - lowest_sp);
154
}
155
 
156
void
157
put_reg (int id, unsigned int v)
158
{
159
  if (trace > ((id != pc) ? 0 : 1))
160
    printf ("put_reg (%s) = %08x\n", reg_names[id], v);
161
 
162
 
163
  switch (id)
164
    {
165
    case psw:
166
      regs.r_psw = v;
167
      break;
168
    case fpsw:
169
      {
170
        SI anded;
171
        /* This is an odd one - The Cx flags are AND'd, and the FS flag
172
           is synthetic.  */
173
        anded = regs.r_fpsw & v;
174
        anded |= ~ FPSWBITS_CMASK;
175
        regs.r_fpsw = v & anded;
176
        if (regs.r_fpsw & FPSWBITS_FMASK)
177
          regs.r_fpsw |= FPSWBITS_FSUM;
178
        else
179
          regs.r_fpsw &= ~FPSWBITS_FSUM;
180
      }
181
      break;
182
    case isp:
183
      regs.r_isp = v;
184
      break;
185
    case usp:
186
      regs.r_usp = v;
187
      break;
188
    case bpc:
189
      regs.r_bpc = v;
190
      break;
191
    case bpsw:
192
      regs.r_bpsw = v;
193
      break;
194
    case fintv:
195
      regs.r_fintv = v;
196
      break;
197
    case intb:
198
      regs.r_intb = v;
199
      break;
200
    case pc:
201
      regs.r_pc = v;
202
      break;
203
 
204
    case acchi:
205
      regs.r_acc = (regs.r_acc & 0xffffffffULL) | ((DI)v << 32);
206
      break;
207
    case accmi:
208
      regs.r_acc = (regs.r_acc & ~0xffffffff0000ULL) | ((DI)v << 16);
209
      break;
210
    case acclo:
211
      regs.r_acc = (regs.r_acc & ~0xffffffffULL) | ((DI)v);
212
      break;
213
 
214
    case 0: /* Stack pointer is "in" R0.  */
215
      {
216
        if (v < heaptop)
217
          {
218
            unsigned int line;
219
            const char * dummy;
220
            const char * fname = NULL;
221
 
222
            sim_get_current_source_location (& dummy, & fname, &line);
223
 
224
            /* The setjmp and longjmp functions play tricks with the stack pointer.  */
225
            if (fname == NULL
226
                || (strcmp (fname, "_setjmp") != 0
227
                    && strcmp (fname, "_longjmp") != 0))
228
              {
229
                printf ("collision in %s: pc %08x heap %08x stack %08x\n",
230
                        fname, (unsigned int) regs.r_pc, heaptop, v);
231
                exit (1);
232
              }
233
          }
234
        else
235
          {
236
            if (v < lowest_sp)
237
              lowest_sp = v;
238
            if (v > highest_sp)
239
              highest_sp = v;
240
          }
241
 
242
        if (regs.r_psw & FLAGBIT_U)
243
          regs.r_usp = v;
244
        else
245
          regs.r_isp = v;
246
        break;
247
      }
248
 
249
    default:
250
      if (id >= 1 || id <= 15)
251
        regs.r[id] = v;
252
      else
253
        abort ();
254
    }
255
}
256
 
257
void
258
put_reg64 (int id, unsigned long long v)
259
{
260
  if (trace > ((id != pc) ? 0 : 1))
261
    printf ("put_reg (%s) = %016llx\n", reg_names[id], v);
262
 
263
  switch (id)
264
    {
265
    case acc64:
266
      regs.r_acc = v;
267
      break;
268
    default:
269
      abort ();
270
    }
271
}
272
 
273
int
274
condition_true (int cond_id)
275
{
276
  int f;
277
 
278
  static const char *cond_name[] = {
279
    "Z",
280
    "!Z",
281
    "C",
282
    "!C",
283
    "C&!Z",
284
    "!(C&!Z)",
285
    "!S",
286
    "S",
287
    "!(S^O)",
288
    "S^O",
289
    "!((S^O)|Z)",
290
    "(S^O)|Z",
291
    "O",
292
    "!O",
293
    "always",
294
    "never"
295
  };
296
  switch (cond_id & 15)
297
    {
298
    case 0:
299
      f = FLAG_Z;
300
      break;            /* EQ/Z */
301
    case 1:
302
      f = !FLAG_Z;
303
      break;            /* NE/NZ */
304
    case 2:
305
      f = FLAG_C;
306
      break;            /* GEU/C */
307
    case 3:
308
      f = !FLAG_C;
309
      break;            /* LTU/NC */
310
    case 4:
311
      f = FLAG_C & !FLAG_Z;
312
      break;            /* GTU */
313
    case 5:
314
      f = !(FLAG_C & !FLAG_Z);
315
      break;            /* LEU */
316
    case 6:
317
      f = !FLAG_S;
318
      break;            /* PZ */
319
    case 7:
320
      f = FLAG_S;
321
      break;            /* N */
322
 
323
    case 8:
324
      f = !(FLAG_S ^ FLAG_O);
325
      break;            /* GE */
326
    case 9:
327
      f = FLAG_S ^ FLAG_O;
328
      break;            /* LT */
329
    case 10:
330
      f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
331
      break;            /* GT */
332
    case 11:
333
      f = (FLAG_S ^ FLAG_O) | FLAG_Z;
334
      break;            /* LE */
335
    case 12:
336
      f = FLAG_O;
337
      break;            /* O */
338
    case 13:
339
      f = !FLAG_O;
340
      break;            /* NO */
341
    case 14:
342
      f = 1;            /* always */
343
      break;
344
    default:
345
      f = 0;             /* never */
346
      break;
347
    }
348
  if (trace && ((cond_id & 15) != 14))
349
    printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
350
            f ? "true" : "false");
351
  return f;
352
}
353
 
354
void
355
set_flags (int mask, int newbits)
356
{
357
  regs.r_psw &= rx_flagand;
358
  regs.r_psw |= rx_flagor;
359
  regs.r_psw |= (newbits & mask & rx_flagmask);
360
 
361
  if (trace)
362
    {
363
      int i;
364
      printf ("flags now \033[32m %d", (int)((regs.r_psw >> 24) & 7));
365
      for (i = 17; i >= 0; i--)
366
        if (0x3000f & (1 << i))
367
          {
368
            if (regs.r_psw & (1 << i))
369
              putchar ("CZSO------------IU"[i]);
370
            else
371
              putchar ('-');
372
          }
373
      printf ("\033[0m\n");
374
    }
375
}
376
 
377
void
378
set_oszc (long long value, int b, int c)
379
{
380
  int mask = b2mask[b];
381
  int f = 0;
382
 
383
  if (c)
384
    f |= FLAGBIT_C;
385
  if ((value & mask) == 0)
386
    f |= FLAGBIT_Z;
387
  if (value & b2signbit[b])
388
    f |= FLAGBIT_S;
389
  if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
390
    f |= FLAGBIT_O;
391
  set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
392
}
393
 
394
void
395
set_szc (long long value, int b, int c)
396
{
397
  int mask = b2mask[b];
398
  int f = 0;
399
 
400
  if (c)
401
    f |= FLAGBIT_C;
402
  if ((value & mask) == 0)
403
    f |= FLAGBIT_Z;
404
  if (value & b2signbit[b])
405
    f |= FLAGBIT_S;
406
  set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
407
}
408
 
409
void
410
set_osz (long long value, int b)
411
{
412
  int mask = b2mask[b];
413
  int f = 0;
414
 
415
  if ((value & mask) == 0)
416
    f |= FLAGBIT_Z;
417
  if (value & b2signbit[b])
418
    f |= FLAGBIT_S;
419
  if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
420
    f |= FLAGBIT_O;
421
  set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
422
}
423
 
424
void
425
set_sz (long long value, int b)
426
{
427
  int mask = b2mask[b];
428
  int f = 0;
429
 
430
  if ((value & mask) == 0)
431
    f |= FLAGBIT_Z;
432
  if (value & b2signbit[b])
433
    f |= FLAGBIT_S;
434
  set_flags (FLAGBIT_Z | FLAGBIT_S, f);
435
}
436
 
437
void
438
set_zc (int z, int c)
439
{
440
  set_flags (FLAGBIT_C | FLAGBIT_Z,
441
             (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
442
}
443
 
444
void
445
set_c (int c)
446
{
447
  set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
448
}
449
 
450
static char *
451
psw2str(int rpsw)
452
{
453
  static char buf[10];
454
  char *bp = buf;
455
  int i, ipl;
456
 
457
  ipl = (rpsw & FLAGBITS_IPL) >> FLAGSHIFT_IPL;
458
  if (ipl > 9)
459
    {
460
      *bp++ = (ipl / 10) + '0';
461
      ipl %= 10;
462
    }
463
  *bp++ = ipl + '0';
464
  for (i = 20; i >= 0; i--)
465
    if (0x13000f & (1 << i))
466
      {
467
        if (rpsw & (1 << i))
468
          *bp++ = "CZSO------------IU--P"[i];
469
        else
470
          *bp++ = '-';
471
      }
472
  *bp = 0;
473
  return buf;
474
}
475
 
476
static char *
477
fpsw2str(int rpsw)
478
{
479
  static char buf[100];
480
  char *bp = buf;
481
  int i;        /*   ---+---+---+---+---+---+---+---+ */
482
  const char s1[] = "FFFFFF-----------EEEEE-DCCCCCCRR";
483
  const char s2[] = "SXUZOV-----------XUZOV-NEXUZOV01";
484
  const char rm[4][3] = { "RC", "RZ", "RP", "RN" };
485
 
486
  for (i = 31; i >= 0; i--)
487
    if (0xfc007dfc & (1 << i))
488
      {
489
        if (rpsw & (1 << i))
490
          {
491
            if (bp > buf)
492
              *bp++ = '.';
493
            *bp++ = s1[31-i];
494
            *bp++ = s2[31-i];
495
          }
496
      }
497
  if (bp > buf)
498
    *bp++ = '.';
499
  strcpy (bp, rm[rpsw&3]);
500
  return buf;
501
}
502
 
503
#define TRC(f,n) \
504
  if (oldregs.f != regs.f) \
505
    { \
506
      if (tag) { printf (tag); tag = 0; } \
507
      printf("  %s %08x:%08x", n, \
508
             (unsigned int)oldregs.f, \
509
             (unsigned int)regs.f); \
510
      oldregs.f = regs.f; \
511
    }
512
 
513
void
514
trace_register_changes (void)
515
{
516
  char *tag = "\033[36mREGS:";
517
  int i;
518
 
519
  if (!trace)
520
    return;
521
  for (i=1; i<16; i++)
522
    TRC (r[i], reg_names[i]);
523
  TRC (r_intb, "intb");
524
  TRC (r_usp, "usp");
525
  TRC (r_isp, "isp");
526
  if (oldregs.r_psw != regs.r_psw)
527
    {
528
      if (tag) { printf (tag); tag = 0; }
529
      printf("  psw %s:", psw2str(oldregs.r_psw));
530
      printf("%s", psw2str(regs.r_psw));
531
      oldregs.r_psw = regs.r_psw;
532
    }
533
 
534
  if (oldregs.r_fpsw != regs.r_fpsw)
535
    {
536
      if (tag) { printf (tag); tag = 0; }
537
      printf("  fpsw %s:", fpsw2str(oldregs.r_fpsw));
538
      printf("%s", fpsw2str(regs.r_fpsw));
539
      oldregs.r_fpsw = regs.r_fpsw;
540
    }
541
 
542
  if (oldregs.r_acc != regs.r_acc)
543
    {
544
      if (tag) { printf (tag); tag = 0; }
545
      printf("  acc %016llx:", oldregs.r_acc);
546
      printf("%016llx", regs.r_acc);
547
      oldregs.r_acc = regs.r_acc;
548
    }
549
 
550
  if (tag == 0)
551
    printf ("\033[0m\n");
552
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.