1/*  armemu.h -- ARMulator emulation macros:  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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
17
18extern ARMword isize;
19
20/* Condition code values.  */
21#define EQ 0
22#define NE 1
23#define CS 2
24#define CC 3
25#define MI 4
26#define PL 5
27#define VS 6
28#define VC 7
29#define HI 8
30#define LS 9
31#define GE 10
32#define LT 11
33#define GT 12
34#define LE 13
35#define AL 14
36#define NV 15
37
38/* Shift Opcodes.  */
39#define LSL 0
40#define LSR 1
41#define ASR 2
42#define ROR 3
43
44/* Macros to twiddle the status flags and mode.  */
45#define NBIT ((unsigned)1L << 31)
46#define ZBIT (1L << 30)
47#define CBIT (1L << 29)
48#define VBIT (1L << 28)
49#define SBIT (1L << 27)
50#define IBIT (1L << 7)
51#define FBIT (1L << 6)
52#define IFBITS (3L << 6)
53#define R15IBIT (1L << 27)
54#define R15FBIT (1L << 26)
55#define R15IFBITS (3L << 26)
56
57#define POS(i) ( (~(i)) >> 31 )
58#define NEG(i) ( (i) >> 31 )
59
60#ifdef MODET			/* Thumb support.  */
61/* ??? This bit is actually in the low order bit of the PC in the hardware.
62   It isn't clear if the simulator needs to model that or not.  */
63#define TBIT (1L << 5)
64#define TFLAG state->TFlag
65#define SETT state->TFlag = 1
66#define CLEART state->TFlag = 0
67#define ASSIGNT(res) state->TFlag = res
68#define INSN_SIZE (TFLAG ? 2 : 4)
69#else
70#define INSN_SIZE 4
71#endif
72
73#define NFLAG state->NFlag
74#define SETN state->NFlag = 1
75#define CLEARN state->NFlag = 0
76#define ASSIGNN(res) state->NFlag = res
77
78#define ZFLAG state->ZFlag
79#define SETZ state->ZFlag = 1
80#define CLEARZ state->ZFlag = 0
81#define ASSIGNZ(res) state->ZFlag = res
82
83#define CFLAG state->CFlag
84#define SETC state->CFlag = 1
85#define CLEARC state->CFlag = 0
86#define ASSIGNC(res) state->CFlag = res
87
88#define VFLAG state->VFlag
89#define SETV state->VFlag = 1
90#define CLEARV state->VFlag = 0
91#define ASSIGNV(res) state->VFlag = res
92
93#define SFLAG state->SFlag
94#define SETS state->SFlag = 1
95#define CLEARS state->SFlag = 0
96#define ASSIGNS(res) state->SFlag = res
97
98#define IFLAG (state->IFFlags >> 1)
99#define FFLAG (state->IFFlags & 1)
100#define IFFLAGS state->IFFlags
101#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3)
102#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ;
103
104#define PSR_FBITS (0xff000000L)
105#define PSR_SBITS (0x00ff0000L)
106#define PSR_XBITS (0x0000ff00L)
107#define PSR_CBITS (0x000000ffL)
108
109#if defined MODE32 || defined MODET
110#define CCBITS (0xf8000000L)
111#else
112#define CCBITS (0xf0000000L)
113#endif
114
115#define INTBITS (0xc0L)
116
117#if defined MODET && defined MODE32
118#define PCBITS (0xffffffffL)
119#else
120#define PCBITS (0xfffffffcL)
121#endif
122
123#define MODEBITS (0x1fL)
124#define R15INTBITS (3L << 26)
125
126#if defined MODET && defined MODE32
127#define R15PCBITS (0x03ffffffL)
128#else
129#define R15PCBITS (0x03fffffcL)
130#endif
131
132#define R15PCMODEBITS (0x03ffffffL)
133#define R15MODEBITS (0x3L)
134
135#ifdef MODE32
136#define PCMASK PCBITS
137#define PCWRAP(pc) (pc)
138#else
139#define PCMASK R15PCBITS
140#define PCWRAP(pc) ((pc) & R15PCBITS)
141#endif
142
143#define PC (state->Reg[15] & PCMASK)
144#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS))
145#define R15INT (state->Reg[15] & R15INTBITS)
146#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS))
147#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS))
148#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS))
149#define R15PC (state->Reg[15] & R15PCBITS)
150#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
151#define R15MODE (state->Reg[15] & R15MODEBITS)
152
153#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27))
154#define EINT (IFFLAGS << 6)
155#define ER15INT (IFFLAGS << 26)
156#define EMODE (state->Mode)
157
158#ifdef MODET
159#define CPSR (ECC | EINT | EMODE | (TFLAG << 5))
160#else
161#define CPSR (ECC | EINT | EMODE)
162#endif
163
164#ifdef MODE32
165#define PATCHR15
166#else
167#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC
168#endif
169
170#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE))
171#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS)
172#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS)
173#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS)
174#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS)
175
176#define SETR15PSR(s) 								\
177  do										\
178    {										\
179      if (state->Mode == USER26MODE)						\
180        {									\
181          state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE;		\
182          ASSIGNN ((state->Reg[15] & NBIT) != 0);				\
183          ASSIGNZ ((state->Reg[15] & ZBIT) != 0);				\
184          ASSIGNC ((state->Reg[15] & CBIT) != 0);				\
185          ASSIGNV ((state->Reg[15] & VBIT) != 0);				\
186        }									\
187      else									\
188        {									\
189          state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS));	\
190          ARMul_R15Altered (state);						\
191       }									\
192    }										\
193  while (0)
194
195#define SETABORT(i, m, d)						\
196  do									\
197    { 									\
198      int SETABORT_mode = (m);						\
199									\
200      ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state));	\
201      ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT))	\
202			     | (i) | SETABORT_mode));			\
203      state->Reg[14] = temp - (d);					\
204    }									\
205  while (0)
206
207#ifndef MODE32
208#define VECTORS 0x20
209#define LEGALADDR 0x03ffffff
210#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
211#define ADDREXCEPT(address)   (address > LEGALADDR && !state->data32Sig)
212#endif
213
214#define INTERNALABORT(address)			\
215  do						\
216    {						\
217      if (address < VECTORS)			\
218	state->Aborted = ARMul_DataAbortV;	\
219      else					\
220	state->Aborted = ARMul_AddrExceptnV;	\
221    }						\
222  while (0)
223
224#ifdef MODE32
225#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV)
226#else
227#define TAKEABORT 					\
228  do							\
229    {							\
230      if (state->Aborted == ARMul_AddrExceptnV) 	\
231	ARMul_Abort (state, ARMul_AddrExceptnV); 	\
232      else 						\
233	ARMul_Abort (state, ARMul_DataAbortV);		\
234    }							\
235  while (0)
236#endif
237
238#define CPTAKEABORT					\
239  do							\
240    {							\
241      if (!state->Aborted)				\
242	ARMul_Abort (state, ARMul_UndefinedInstrV); 	\
243      else if (state->Aborted == ARMul_AddrExceptnV) 	\
244	ARMul_Abort (state, ARMul_AddrExceptnV); 	\
245      else 						\
246	ARMul_Abort (state, ARMul_DataAbortV);		\
247    }							\
248  while (0);
249
250
251/* Different ways to start the next instruction.  */
252#define SEQ           0
253#define NONSEQ        1
254#define PCINCEDSEQ    2
255#define PCINCEDNONSEQ 3
256#define PRIMEPIPE     4
257#define RESUME        8
258
259#define NORMALCYCLE state->NextInstr = 0
260#define BUSUSEDN    state->NextInstr |= 1  /* The next fetch will be an N cycle.  */
261#define BUSUSEDINCPCS						\
262  do								\
263    {								\
264      if (! state->is_v4)					\
265        {							\
266	  /* A standard PC inc and an S cycle.  */		\
267	  state->Reg[15] += isize;				\
268	  state->NextInstr = (state->NextInstr & 0xff) | 2;	\
269	}							\
270    }								\
271  while (0)
272
273#define BUSUSEDINCPCN					\
274  do							\
275    {							\
276      if (state->is_v4)					\
277	BUSUSEDN;					\
278      else						\
279	{						\
280	  /* A standard PC inc and an N cycle.  */	\
281	  state->Reg[15] += isize;			\
282	  state->NextInstr |= 3;			\
283	}						\
284    }							\
285  while (0)
286
287#define INCPC 			\
288  do				\
289    {				\
290      /* A standard PC inc.  */	\
291      state->Reg[15] += isize;	\
292      state->NextInstr |= 2;	\
293    }				\
294  while (0)
295
296#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
297
298/* Cycle based emulation.  */
299
300#define OUTPUTCP(i,a,b)
301#define NCYCLE
302#define SCYCLE
303#define ICYCLE
304#define CCYCLE
305#define NEXTCYCLE(c)
306
307/* Macros to extract parts of instructions.  */
308#define DESTReg (BITS (12, 15))
309#define LHSReg  (BITS (16, 19))
310#define RHSReg  (BITS ( 0,  3))
311
312#define DEST (state->Reg[DESTReg])
313
314#ifdef MODE32
315#ifdef MODET
316#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC): (state->Reg[LHSReg]))
317#else
318#define LHS (state->Reg[LHSReg])
319#endif
320#else
321#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]))
322#endif
323
324#define MULDESTReg (BITS (16, 19))
325#define MULLHSReg  (BITS ( 0,  3))
326#define MULRHSReg  (BITS ( 8, 11))
327#define MULACCReg  (BITS (12, 15))
328
329#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)])
330#define DPSImmRHS temp = BITS(0,11) ; \
331                  rhs = ARMul_ImmedTable[temp] ; \
332                  if (temp > 255) /* There was a shift.  */ \
333                     ASSIGNC (rhs >> 31) ;
334
335#ifdef MODE32
336#define DPRegRHS  ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
337                                      : GetDPRegRHS (state, instr))
338#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
339                                      : GetDPSRegRHS (state, instr))
340#else
341#define DPRegRHS  ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
342                                       : GetDPRegRHS (state, instr))
343#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
344                                       : GetDPSRegRHS (state, instr))
345#endif
346
347#define LSBase state->Reg[LHSReg]
348#define LSImmRHS (BITS(0,11))
349
350#ifdef MODE32
351#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \
352                                      : GetLSRegRHS (state, instr))
353#else
354#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
355                                      : GetLSRegRHS (state, instr))
356#endif
357
358#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \
359                    (ARMword) ARMul_BitList[BITS (8, 15)] )
360#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \
361                      (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0))
362
363#define SWAPSRC (state->Reg[RHSReg])
364
365#define LSCOff (BITS (0, 7) << 2)
366#define CPNum   BITS (8, 11)
367
368/* Determine if access to coprocessor CP is permitted.
369   The XScale has a register in CP15 which controls access to CP0 - CP13.  */
370#define CP_ACCESS_ALLOWED(STATE, CP)			\
371    (   ((CP) >= 14)					\
372     || (! (STATE)->is_XScale)				\
373     || (read_cp15_reg (15, 0, 1) & (1 << (CP))))
374
375/* Macro to rotate n right by b bits.  */
376#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
377
378/* Macros to store results of instructions.  */
379#define WRITEDEST(d)				\
380  do						\
381    {						\
382      if (DESTReg == 15) 			\
383	WriteR15 (state, d); 			\
384      else 					\
385	DEST = d;				\
386    }						\
387  while (0)
388
389#define WRITESDEST(d)				\
390  do						\
391    {						\
392      if (DESTReg == 15)			\
393	WriteSR15 (state, d);			\
394      else					\
395	{					\
396	  DEST = d;				\
397	  ARMul_NegZero (state, d);		\
398	}					\
399    }						\
400  while (0)
401
402#define WRITEDESTB(d)				\
403  do						\
404    {						\
405      if (DESTReg == 15)			\
406	WriteR15Branch (state, d);		\
407      else					\
408	DEST = d;				\
409    }						\
410  while (0)
411
412#define BYTETOBUS(data) ((data & 0xff) | \
413                        ((data & 0xff) << 8) | \
414                        ((data & 0xff) << 16) | \
415                        ((data & 0xff) << 24))
416
417#define BUSTOBYTE(address, data)				\
418  do								\
419    {								\
420      if (state->bigendSig) 					\
421	temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff;	\
422      else							\
423	temp = (data >> ((address & 3) << 3)) & 0xff;		\
424    }								\
425  while (0)
426
427#define LOADMULT(instr,   address, wb)  LoadMult   (state, instr, address, wb)
428#define LOADSMULT(instr,  address, wb)  LoadSMult  (state, instr, address, wb)
429#define STOREMULT(instr,  address, wb)  StoreMult  (state, instr, address, wb)
430#define STORESMULT(instr, address, wb)  StoreSMult (state, instr, address, wb)
431
432#define POSBRANCH ((instr & 0x7fffff) << 2)
433#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2)
434
435
436/* Values for Emulate.  */
437#define STOP            0	/* stop */
438#define CHANGEMODE      1	/* change mode */
439#define ONCE            2	/* execute just one interation */
440#define RUN             3	/* continuous execution */
441
442/* Stuff that is shared across modes.  */
443extern unsigned ARMul_MultTable[];	/* Number of I cycles for a mult.  */
444extern ARMword  ARMul_ImmedTable[];	/* Immediate DP LHS values.  */
445extern char     ARMul_BitList[];	/* Number of bits in a byte table.  */
446
447#define EVENTLISTSIZE 1024L
448
449/* Thumb support.  */
450typedef enum
451{
452  t_undefined,		/* Undefined Thumb instruction.  */
453  t_decoded,		/* Instruction decoded to ARM equivalent.  */
454  t_branch		/* Thumb branch (already processed).  */
455}
456tdstate;
457
458/* Macros to scrutinize instructions.  */
459#define UNDEF_Test
460#define UNDEF_Shift
461#define UNDEF_MSRPC
462#define UNDEF_MRSPC
463#define UNDEF_MULPCDest
464#define UNDEF_MULDestEQOp1
465#define UNDEF_LSRBPC
466#define UNDEF_LSRBaseEQOffWb
467#define UNDEF_LSRBaseEQDestWb
468#define UNDEF_LSRPCBaseWb
469#define UNDEF_LSRPCOffWb
470#define UNDEF_LSMNoRegs
471#define UNDEF_LSMPCBase
472#define UNDEF_LSMUserBankWb
473#define UNDEF_LSMBaseInListWb
474#define UNDEF_SWPPC
475#define UNDEF_CoProHS
476#define UNDEF_MCRPC
477#define UNDEF_LSCPCBaseWb
478#define UNDEF_UndefNotBounced
479#define UNDEF_ShortInt
480#define UNDEF_IllegalMode
481#define UNDEF_Prog32SigChange
482#define UNDEF_Data32SigChange
483
484/* Prototypes for exported functions.  */
485extern unsigned ARMul_NthReg        (ARMword, unsigned);
486extern int      AddOverflow         (ARMword, ARMword, ARMword);
487extern int      SubOverflow         (ARMword, ARMword, ARMword);
488extern ARMword  ARMul_Emulate26     (ARMul_State *);
489extern ARMword  ARMul_Emulate32     (ARMul_State *);
490extern unsigned IntPending          (ARMul_State *);
491extern void     ARMul_CPSRAltered   (ARMul_State *);
492extern void     ARMul_R15Altered    (ARMul_State *);
493extern ARMword  ARMul_GetPC         (ARMul_State *);
494extern ARMword  ARMul_GetNextPC     (ARMul_State *);
495extern ARMword  ARMul_GetR15        (ARMul_State *);
496extern ARMword  ARMul_GetCPSR       (ARMul_State *);
497extern void     ARMul_EnvokeEvent   (ARMul_State *);
498extern unsigned long ARMul_Time     (ARMul_State *);
499extern void     ARMul_NegZero       (ARMul_State *, ARMword);
500extern void     ARMul_SetPC         (ARMul_State *, ARMword);
501extern void     ARMul_SetR15        (ARMul_State *, ARMword);
502extern void     ARMul_SetCPSR       (ARMul_State *, ARMword);
503extern ARMword  ARMul_GetSPSR       (ARMul_State *, ARMword);
504extern void     ARMul_Abort26       (ARMul_State *, ARMword);
505extern void     ARMul_Abort32       (ARMul_State *, ARMword);
506extern ARMword  ARMul_MRC           (ARMul_State *, ARMword);
507extern void     ARMul_CDP           (ARMul_State *, ARMword);
508extern void     ARMul_LDC           (ARMul_State *, ARMword, ARMword);
509extern void     ARMul_STC           (ARMul_State *, ARMword, ARMword);
510extern void     ARMul_MCR           (ARMul_State *, ARMword, ARMword);
511extern void     ARMul_SetSPSR       (ARMul_State *, ARMword, ARMword);
512extern ARMword  ARMul_SwitchMode    (ARMul_State *, ARMword, ARMword);
513extern ARMword  ARMul_Align         (ARMul_State *, ARMword, ARMword);
514extern ARMword  ARMul_SwitchMode    (ARMul_State *, ARMword, ARMword);
515extern void     ARMul_MSRCpsr       (ARMul_State *, ARMword, ARMword);
516extern void     ARMul_SubOverflow   (ARMul_State *, ARMword, ARMword, ARMword);
517extern void     ARMul_AddOverflow   (ARMul_State *, ARMword, ARMword, ARMword);
518extern void     ARMul_SubCarry      (ARMul_State *, ARMword, ARMword, ARMword);
519extern void     ARMul_AddCarry      (ARMul_State *, ARMword, ARMword, ARMword);
520extern tdstate  ARMul_ThumbDecode   (ARMul_State *, ARMword, ARMword, ARMword *);
521extern ARMword  ARMul_GetReg        (ARMul_State *, unsigned, unsigned);
522extern void     ARMul_SetReg        (ARMul_State *, unsigned, unsigned, ARMword);
523extern void     ARMul_ScheduleEvent (ARMul_State *, unsigned long, unsigned (*) (ARMul_State *));
524/* Coprocessor support functions.  */
525extern unsigned ARMul_CoProInit     (ARMul_State *);
526extern void     ARMul_CoProExit     (ARMul_State *);
527extern void     ARMul_CoProAttach   (ARMul_State *, unsigned, ARMul_CPInits *, ARMul_CPExits *,
528				     ARMul_LDCs *, ARMul_STCs *, ARMul_MRCs *, ARMul_MCRs *,
529				     ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
530extern void     ARMul_CoProDetach   (ARMul_State *, unsigned);
531extern ARMword  read_cp15_reg       (unsigned, unsigned, unsigned);
532
533extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
534extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
535extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
536extern unsigned	DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
537extern unsigned	DSPCDP4 (ARMul_State *, unsigned, ARMword);
538extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
539extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
540extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
541extern unsigned	DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
542extern unsigned	DSPCDP5 (ARMul_State *, unsigned, ARMword);
543extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
544extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
545extern unsigned	DSPCDP6 (ARMul_State *, unsigned, ARMword);
546