9ef7b1cbacaa35338bbb0441978f6aaf2f8f5d72
[external/binutils.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 }