* Makefile.in: Add mips-linux-nat.c, mips-linux-tdep.c,
[external/binutils.git] / sim / d30v / cpu.c
1 /* Mitsubishi Electric Corp. D30V Simulator.
2    Copyright (C) 1997, Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
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
9 the Free Software Foundation; either version 2, or (at your option)
10 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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21
22 #ifndef _CPU_C_
23 #define _CPU_C_
24
25 #include "sim-main.h"
26
27 \f
28 int
29 is_wrong_slot (SIM_DESC sd,
30                address_word cia,
31                itable_index index)
32 {
33   switch (STATE_CPU (sd, 0)->unit)
34     {
35     case memory_unit:
36       return !itable[index].option[itable_option_mu];
37     case integer_unit:
38       return !itable[index].option[itable_option_iu];
39     case any_unit:
40       return 0;
41     default:
42       sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
43                         "internal error - is_wrong_slot - bad switch");
44       return -1;
45     }
46 }
47
48 int
49 is_condition_ok (SIM_DESC sd,
50                  address_word cia,
51                  int cond)
52 {
53   switch (cond)
54     {
55     case 0x0:
56       return 1;
57     case 0x1:
58       return PSW_VAL(PSW_F0);
59     case 0x2:
60       return !PSW_VAL(PSW_F0);
61     case 0x3:
62       return PSW_VAL(PSW_F1);
63     case 0x4:
64       return !PSW_VAL(PSW_F1);
65     case 0x5:
66       return PSW_VAL(PSW_F0) && PSW_VAL(PSW_F1);
67     case 0x6:
68       return PSW_VAL(PSW_F0) && !PSW_VAL(PSW_F1);
69     case 0x7:
70       sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
71                         "is_condition_ok - bad instruction condition bits");
72       return 0;
73     default:
74       sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
75                         "internal error - is_condition_ok - bad switch");
76       return -1;
77     }
78 }
79 \f
80 /* If --trace-call, trace calls, remembering the current state of
81    registers.  */
82
83 typedef struct _call_stack {
84   struct _call_stack *prev;
85   registers regs;
86 } call_stack;
87
88 static call_stack *call_stack_head = (call_stack *)0;
89 static int call_depth = 0;
90
91 void call_occurred (SIM_DESC sd,
92                     sim_cpu *cpu,
93                     address_word cia,
94                     address_word nia)
95 {
96   call_stack *ptr = ZALLOC (call_stack);
97   ptr->regs = cpu->regs;
98   ptr->prev = call_stack_head;
99   call_stack_head = ptr;
100
101   trace_one_insn (sd, cpu, nia, 1, "", 0, "call",
102                   "Depth %3d, Return 0x%.8lx, Args 0x%.8lx 0x%.8lx",
103                   ++call_depth, (unsigned long)cia+8, (unsigned long)GPR[2],
104                   (unsigned long)GPR[3]);
105 }
106
107 /* If --trace-call, trace returns, checking if any saved register was changed.  */
108
109 void return_occurred (SIM_DESC sd,
110                       sim_cpu *cpu,
111                       address_word cia,
112                       address_word nia)
113 {
114   char buffer[1024];
115   char *buf_ptr = buffer;
116   call_stack *ptr = call_stack_head;
117   int regno;
118   char *prefix = ", Registers that differ: ";
119
120   *buf_ptr = '\0';
121   for (regno = 34; regno <= 63; regno++) {
122     if (cpu->regs.general_purpose[regno] != ptr->regs.general_purpose[regno]) {
123       sprintf (buf_ptr, "%sr%d", prefix, regno);
124       buf_ptr += strlen (buf_ptr);
125       prefix = " ";
126     }
127   }
128
129   if (cpu->regs.accumulator[1] != ptr->regs.accumulator[1]) {
130     sprintf (buf_ptr, "%sa1", prefix);
131     buf_ptr += strlen (buf_ptr);
132     prefix = " ";
133   }
134
135   trace_one_insn (sd, cpu, cia, 1, "", 0, "return",
136                   "Depth %3d, Return 0x%.8lx, Ret. 0x%.8lx 0x%.8lx%s",
137                   call_depth--, (unsigned long)nia, (unsigned long)GPR[2],
138                   (unsigned long)GPR[3], buffer);
139
140   call_stack_head = ptr->prev;
141   zfree (ptr);
142 }
143
144 \f
145 /* Read/write functions for system call interface.  */
146 int
147 d30v_read_mem (host_callback *cb,
148                struct cb_syscall *sc,
149                unsigned long taddr,
150                char *buf,
151                int bytes)
152 {
153   SIM_DESC sd = (SIM_DESC) sc->p1;
154   sim_cpu *cpu = STATE_CPU (sd, 0);
155
156   return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
157 }
158
159 int
160 d30v_write_mem (host_callback *cb,
161                 struct cb_syscall *sc,
162                 unsigned long taddr,
163                 const char *buf,
164                 int bytes)
165 {
166   SIM_DESC sd = (SIM_DESC) sc->p1;
167   sim_cpu *cpu = STATE_CPU (sd, 0);
168
169   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
170 }
171
172 #endif /* _CPU_C_ */