1 /* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
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.
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.
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. */
21 /***************************************************************************\
22 * Definitions for the emulator architecture *
23 \***************************************************************************/
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) ;
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 */
39 /***************************************************************************\
40 * Call this routine once to set up the emulator's tables. *
41 \***************************************************************************/
43 void ARMul_EmulateInit(void)
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) ;
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++)
56 for (i = 0 ; i < 256 ; i++)
57 ARMul_BitList[i] *= 4 ; /* you always need 4 times these values */
61 /***************************************************************************\
62 * Returns a new instantiation of the ARMulator's state *
63 \***************************************************************************/
65 ARMul_State *ARMul_NewState(void)
69 state = (ARMul_State *)malloc(sizeof(ARMul_State)) ;
70 memset (state, 0, sizeof (ARMul_State));
72 state->Emulate = RUN ;
73 for (i = 0 ; i < 16 ; i++) {
75 for (j = 0 ; j < 7 ; j++)
76 state->RegBank[j][i] = 0 ;
78 for (i = 0 ; i < 7 ; i++)
82 state->CallDebug = FALSE ;
83 state->Debug = FALSE ;
84 state->VectorCatch = 0 ;
85 state->Aborted = FALSE ;
86 state->Reseted = FALSE ;
88 state->LastInted = 3 ;
90 state->MemDataPtr = NULL ;
91 state->MemInPtr = NULL ;
92 state->MemOutPtr = NULL ;
93 state->MemSparePtr = NULL ;
97 state->CommandLine = NULL ;
101 state->EventPtr = (struct EventNode **)malloc((unsigned)EVENTLISTSIZE *
102 sizeof(struct EventNode *)) ;
103 for (i = 0 ; i < EVENTLISTSIZE ; i++)
104 *(state->EventPtr + i) = NULL ;
107 state->prog32Sig = LOW ;
108 state->data32Sig = LOW ;
110 state->prog32Sig = HIGH ;
111 state->data32Sig = HIGH ;
114 state->lateabtSig = LOW ;
115 state->bigendSig = LOW ;
121 /***************************************************************************\
122 * Call this routine to set ARMulator to model a certain processor *
123 \***************************************************************************/
125 void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
126 if (processor & ARM_Fix26_Prop) {
127 state->prog32Sig = LOW;
128 state->data32Sig = LOW;
130 state->prog32Sig = HIGH;
131 state->data32Sig = HIGH;
134 state->lateabtSig = LOW;
137 /***************************************************************************\
138 * Call this routine to set up the initial machine state (or perform a RESET *
139 \***************************************************************************/
141 void ARMul_Reset(ARMul_State *state)
142 {state->NextInstr = 0 ;
143 if (state->prog32Sig) {
145 state->Cpsr = INTBITS | SVC32MODE ;
148 state->Reg[15] = R15INTBITS | SVC26MODE ;
149 state->Cpsr = INTBITS | SVC26MODE ;
151 ARMul_CPSRAltered(state) ;
152 state->Bank = SVCBANK ;
155 state->EndCondition = 0 ;
156 state->ErrorCode = 0 ;
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 ;
166 state->NumInstrs = 0 ;
167 state->NumNcycles = 0 ;
168 state->NumScycles = 0 ;
169 state->NumIcycles = 0 ;
170 state->NumCcycles = 0 ;
171 state->NumFcycles = 0 ;
173 (void)ARMul_MemoryInit() ;
174 ARMul_OSInit(state) ;
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 \***************************************************************************/
185 ARMword ARMul_DoProg(ARMul_State *state)
188 state->Emulate = RUN ;
189 while (state->Emulate != STOP) {
190 state->Emulate = RUN ;
191 if (state->prog32Sig && ARMul_MODE32BIT)
192 pc = ARMul_Emulate32(state) ;
194 pc = ARMul_Emulate26(state) ;
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 \***************************************************************************/
205 ARMword ARMul_DoInstr(ARMul_State *state)
208 state->Emulate = ONCE ;
209 if (state->prog32Sig && ARMul_MODE32BIT)
210 pc = ARMul_Emulate32(state) ;
212 pc = ARMul_Emulate26(state) ;
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 \***************************************************************************/
223 void ARMul_Abort(ARMul_State *state, ARMword vector)
226 state->Aborted = FALSE ;
228 if (ARMul_OSException(state,vector,ARMul_GetPC(state)))
231 if (state->prog32Sig)
235 temp = state->Reg[15] ;
237 temp = R15PC | ECC | ER15INT | EMODE ;
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 ;
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 ;
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 ;
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 ;
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 */
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 ;
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 ;
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 ;
291 ARMul_SetR15(state,vector) ;
293 ARMul_SetR15(state,R15CCINTMODE | vector) ;