]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/arm/arminit.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / arm / arminit.c
1 /* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #include "armdefs.h"
19 #include "armemu.h"
20
21 /***************************************************************************\
22 * Definitions for the emulator architecture *
23 \***************************************************************************/
24
25 void ARMul_EmulateInit(void) ;
26 ARMul_State *ARMul_NewState(void) ;
27 void ARMul_Reset(ARMul_State *state) ;
28 ARMword ARMul_DoCycle(ARMul_State *state) ;
29 unsigned ARMul_DoCoPro(ARMul_State *state) ;
30 ARMword ARMul_DoProg(ARMul_State *state) ;
31 ARMword ARMul_DoInstr(ARMul_State *state) ;
32 void ARMul_Abort(ARMul_State *state, ARMword address) ;
33
34 unsigned ARMul_MultTable[32] = {1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
35 10,10,11,11,12,12,13,13,14,14,15,15,16,16,16} ;
36 ARMword ARMul_ImmedTable[4096] ; /* immediate DP LHS values */
37 char ARMul_BitList[256] ; /* number of bits in a byte table */
38
39 /***************************************************************************\
40 * Call this routine once to set up the emulator's tables. *
41 \***************************************************************************/
42
43 void ARMul_EmulateInit(void)
44 {unsigned long i, j ;
45
46 for (i = 0 ; i < 4096 ; i++) { /* the values of 12 bit dp rhs's */
47 ARMul_ImmedTable[i] = ROTATER(i & 0xffL,(i >> 7L) & 0x1eL) ;
48 }
49
50 for (i = 0 ; i < 256 ; ARMul_BitList[i++] = 0 ) ; /* how many bits in LSM */
51 for (j = 1 ; j < 256 ; j <<= 1)
52 for (i = 0 ; i < 256 ; i++)
53 if ((i & j) > 0 )
54 ARMul_BitList[i]++ ;
55
56 for (i = 0 ; i < 256 ; i++)
57 ARMul_BitList[i] *= 4 ; /* you always need 4 times these values */
58
59 }
60
61 /***************************************************************************\
62 * Returns a new instantiation of the ARMulator's state *
63 \***************************************************************************/
64
65 ARMul_State *ARMul_NewState(void)
66 {ARMul_State *state ;
67 unsigned i, j ;
68
69 state = (ARMul_State *)malloc(sizeof(ARMul_State)) ;
70 memset (state, 0, sizeof (ARMul_State));
71
72 state->Emulate = RUN ;
73 for (i = 0 ; i < 16 ; i++) {
74 state->Reg[i] = 0 ;
75 for (j = 0 ; j < 7 ; j++)
76 state->RegBank[j][i] = 0 ;
77 }
78 for (i = 0 ; i < 7 ; i++)
79 state->Spsr[i] = 0 ;
80 state->Mode = 0 ;
81
82 state->CallDebug = FALSE ;
83 state->Debug = FALSE ;
84 state->VectorCatch = 0 ;
85 state->Aborted = FALSE ;
86 state->Reseted = FALSE ;
87 state->Inted = 3 ;
88 state->LastInted = 3 ;
89
90 state->MemDataPtr = NULL ;
91 state->MemInPtr = NULL ;
92 state->MemOutPtr = NULL ;
93 state->MemSparePtr = NULL ;
94 state->MemSize = 0 ;
95
96 state->OSptr = NULL ;
97 state->CommandLine = NULL ;
98
99 state->EventSet = 0 ;
100 state->Now = 0 ;
101 state->EventPtr = (struct EventNode **)malloc((unsigned)EVENTLISTSIZE *
102 sizeof(struct EventNode *)) ;
103 for (i = 0 ; i < EVENTLISTSIZE ; i++)
104 *(state->EventPtr + i) = NULL ;
105
106 #ifdef ARM61
107 state->prog32Sig = LOW ;
108 state->data32Sig = LOW ;
109 #else
110 state->prog32Sig = HIGH ;
111 state->data32Sig = HIGH ;
112 #endif
113
114 state->lateabtSig = LOW ;
115 state->bigendSig = LOW ;
116
117 ARMul_Reset(state) ;
118 return(state) ;
119 }
120
121 /***************************************************************************\
122 * Call this routine to set ARMulator to model a certain processor *
123 \***************************************************************************/
124
125 void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
126 if (processor & ARM_Fix26_Prop) {
127 state->prog32Sig = LOW;
128 state->data32Sig = LOW;
129 }else{
130 state->prog32Sig = HIGH;
131 state->data32Sig = HIGH;
132 }
133
134 state->lateabtSig = LOW;
135 }
136
137 /***************************************************************************\
138 * Call this routine to set up the initial machine state (or perform a RESET *
139 \***************************************************************************/
140
141 void ARMul_Reset(ARMul_State *state)
142 {state->NextInstr = 0 ;
143 if (state->prog32Sig) {
144 state->Reg[15] = 0 ;
145 state->Cpsr = INTBITS | SVC32MODE ;
146 }
147 else {
148 state->Reg[15] = R15INTBITS | SVC26MODE ;
149 state->Cpsr = INTBITS | SVC26MODE ;
150 }
151 ARMul_CPSRAltered(state) ;
152 state->Bank = SVCBANK ;
153 FLUSHPIPE ;
154
155 state->EndCondition = 0 ;
156 state->ErrorCode = 0 ;
157
158 state->Exception = FALSE ;
159 state->NresetSig = HIGH ;
160 state->NfiqSig = HIGH ;
161 state->NirqSig = HIGH ;
162 state->NtransSig = (state->Mode & 3)?HIGH:LOW ;
163 state->abortSig = LOW ;
164 state->AbortAddr = 1 ;
165
166 state->NumInstrs = 0 ;
167 state->NumNcycles = 0 ;
168 state->NumScycles = 0 ;
169 state->NumIcycles = 0 ;
170 state->NumCcycles = 0 ;
171 state->NumFcycles = 0 ;
172 #ifdef ASIM
173 (void)ARMul_MemoryInit() ;
174 ARMul_OSInit(state) ;
175 #endif
176 }
177
178
179 /***************************************************************************\
180 * Emulate the execution of an entire program. Start the correct emulator *
181 * (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
182 * address of the last instruction that is executed. *
183 \***************************************************************************/
184
185 ARMword ARMul_DoProg(ARMul_State *state)
186 {ARMword pc = 0 ;
187
188 state->Emulate = RUN ;
189 while (state->Emulate != STOP) {
190 state->Emulate = RUN ;
191 if (state->prog32Sig && ARMul_MODE32BIT)
192 pc = ARMul_Emulate32(state) ;
193 else
194 pc = ARMul_Emulate26(state) ;
195 }
196 return(pc) ;
197 }
198
199 /***************************************************************************\
200 * Emulate the execution of one instruction. Start the correct emulator *
201 * (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
202 * address of the instruction that is executed. *
203 \***************************************************************************/
204
205 ARMword ARMul_DoInstr(ARMul_State *state)
206 {ARMword pc = 0 ;
207
208 state->Emulate = ONCE ;
209 if (state->prog32Sig && ARMul_MODE32BIT)
210 pc = ARMul_Emulate32(state) ;
211 else
212 pc = ARMul_Emulate26(state) ;
213
214 return(pc) ;
215 }
216
217 /***************************************************************************\
218 * This routine causes an Abort to occur, including selecting the correct *
219 * mode, register bank, and the saving of registers. Call with the *
220 * appropriate vector's memory address (0,4,8 ....) *
221 \***************************************************************************/
222
223 void ARMul_Abort(ARMul_State *state, ARMword vector)
224 {ARMword temp ;
225
226 state->Aborted = FALSE ;
227
228 if (ARMul_OSException(state,vector,ARMul_GetPC(state)))
229 return ;
230
231 if (state->prog32Sig)
232 if (ARMul_MODE26BIT)
233 temp = R15PC ;
234 else
235 temp = state->Reg[15] ;
236 else
237 temp = R15PC | ECC | ER15INT | EMODE ;
238
239 switch (vector) {
240 case ARMul_ResetV : /* RESET */
241 state->Spsr[SVCBANK] = CPSR ;
242 SETABORT(INTBITS,state->prog32Sig?SVC32MODE:SVC26MODE) ;
243 ARMul_CPSRAltered(state) ;
244 state->Reg[14] = temp ;
245 break ;
246 case ARMul_UndefinedInstrV : /* Undefined Instruction */
247 state->Spsr[state->prog32Sig?UNDEFBANK:SVCBANK] = CPSR ;
248 SETABORT(IBIT,state->prog32Sig?UNDEF32MODE:SVC26MODE) ;
249 ARMul_CPSRAltered(state) ;
250 state->Reg[14] = temp - 4 ;
251 break ;
252 case ARMul_SWIV : /* Software Interrupt */
253 state->Spsr[SVCBANK] = CPSR ;
254 SETABORT(IBIT,state->prog32Sig?SVC32MODE:SVC26MODE) ;
255 ARMul_CPSRAltered(state) ;
256 state->Reg[14] = temp - 4 ;
257 break ;
258 case ARMul_PrefetchAbortV : /* Prefetch Abort */
259 state->AbortAddr = 1 ;
260 state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
261 SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
262 ARMul_CPSRAltered(state) ;
263 state->Reg[14] = temp - 4 ;
264 break ;
265 case ARMul_DataAbortV : /* Data Abort */
266 state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
267 SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
268 ARMul_CPSRAltered(state) ;
269 state->Reg[14] = temp - 4 ; /* the PC must have been incremented */
270 break ;
271 case ARMul_AddrExceptnV : /* Address Exception */
272 state->Spsr[SVCBANK] = CPSR ;
273 SETABORT(IBIT,SVC26MODE) ;
274 ARMul_CPSRAltered(state) ;
275 state->Reg[14] = temp - 4 ;
276 break ;
277 case ARMul_IRQV : /* IRQ */
278 state->Spsr[IRQBANK] = CPSR ;
279 SETABORT(IBIT,state->prog32Sig?IRQ32MODE:IRQ26MODE) ;
280 ARMul_CPSRAltered(state) ;
281 state->Reg[14] = temp - 4 ;
282 break ;
283 case ARMul_FIQV : /* FIQ */
284 state->Spsr[FIQBANK] = CPSR ;
285 SETABORT(INTBITS,state->prog32Sig?FIQ32MODE:FIQ26MODE) ;
286 ARMul_CPSRAltered(state) ;
287 state->Reg[14] = temp - 4 ;
288 break ;
289 }
290 if (ARMul_MODE32BIT)
291 ARMul_SetR15(state,vector) ;
292 else
293 ARMul_SetR15(state,R15CCINTMODE | vector) ;
294 }