1 /* SPIM S20 MIPS simulator.
2    Declarations of registers and code for accessing them.
3 
4    Copyright (c) 1990-2010, James R. Larus.
5    All rights reserved.
6 
7    Redistribution and use in source and binary forms, with or without modification,
8    are permitted provided that the following conditions are met:
9 
10    Redistributions of source code must retain the above copyright notice,
11    this list of conditions and the following disclaimer.
12 
13    Redistributions in binary form must reproduce the above copyright notice,
14    this list of conditions and the following disclaimer in the documentation and/or
15    other materials provided with the distribution.
16 
17    Neither the name of the James R. Larus nor the names of its contributors may be
18    used to endorse or promote products derived from this software without specific
19    prior written permission.
20 
21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 
34 typedef int32 /*@alt unsigned int @*/ reg_word;
35 typedef uint32 u_reg_word;
36 
37 
38 /* General purpose registers: */
39 
40 #define R_LENGTH	32
41 
42 extern reg_word R[R_LENGTH];
43 
44 extern reg_word HI, LO;
45 
46 extern mem_addr PC, nPC;
47 
48 
49 /* Argument passing registers */
50 
51 #define REG_V0		2
52 #define REG_A0		4
53 #define REG_A1		5
54 #define REG_A2		6
55 #define REG_A3		7
56 #define REG_FA0		12
57 #define REG_SP		29
58 
59 
60 /* Result registers */
61 
62 #define REG_RES		2
63 #define REG_FRES	0
64 
65 
66 /* $gp registers */
67 
68 #define REG_GP		28
69 
70 
71 
72 /* Coprocessor registers: */
73 
74 extern reg_word CCR[4][32], CPR[4][32];
75 
76 
77 
78 /* Exeception handling registers (Coprocessor 0): */
79 
80 /* BadVAddr register: */
81 #define CP0_BadVAddr_Reg 8
82 #define CP0_BadVAddr	(CPR[0][CP0_BadVAddr_Reg])
83 
84 /* Count register: */
85 #define CP0_Count_Reg	9
86 #define CP0_Count	(CPR[0][CP0_Count_Reg]) /* ToDo */
87 
88 /* Compare register: */
89 #define CP0_Compare_Reg	11
90 #define CP0_Compare	(CPR[0][CP0_Compare_Reg]) /* ToDo */
91 
92 /* Status register: */
93 #define CP0_Status_Reg	12
94 #define CP0_Status	(CPR[0][CP0_Status_Reg])
95 /* Implemented fields: */
96 #define CP0_Status_CU	0xf0000000
97 #define CP0_Status_IM	0x0000ff00
98 #define CP0_Status_IM7  0x00008000 /* HW Int 5 */
99 #define CP0_Status_IM6  0x00004000 /* HW Int 4 */
100 #define CP0_Status_IM5  0x00002000 /* HW Int 3 */
101 #define CP0_Status_IM4  0x00001000 /* HW Int 2 */
102 #define CP0_Status_IM3  0x00000800 /* HW Int 1 */
103 #define CP0_Status_IM2  0x00000400 /* HW Int 0 */
104 #define CP0_Status_IM1  0x00000200 /* SW Int 1 */
105 #define CP0_Status_IM0  0x00000100 /* SW Int 0 */
106 #define CP0_Status_UM	0x00000010
107 #define CP0_Status_EXL	0x00000002
108 #define CP0_Status_IE	0x00000001
109 #define CP0_Status_Mask (CP0_Status_CU		\
110 			 | CP0_Status_UM	\
111 			 | CP0_Status_IM	\
112 			 | CP0_Status_EXL	\
113 			 | CP0_Status_IE)
114 
115 /* Cause register: */
116 #define CP0_Cause_Reg	13
117 #define CP0_Cause	(CPR[0][CP0_Cause_Reg])
118 /* Implemented fields: */
119 #define CP0_Cause_BD	0x80000000
120 #define CP0_Cause_IP	0x0000ff00
121 #define CP0_Cause_IP7   0x00008000 /* HW Int 5 */
122 #define CP0_Cause_IP6   0x00004000 /* HW Int 4 */
123 #define CP0_Cause_IP5   0x00002000 /* HW Int 3 */
124 #define CP0_Cause_IP4   0x00001000 /* HW Int 2 */
125 #define CP0_Cause_IP3   0x00000800 /* HW Int 1 */
126 #define CP0_Cause_IP2   0x00000400 /* HW Int 0 */
127 #define CP0_Cause_IP1   0x00000200 /* SW Int 1 */
128 #define CP0_Cause_IP0   0x00000100 /* SW Int 0 */
129 #define CP0_Cause_ExcCode 0x0000007c
130 #define CP0_Cause_Mask	(CP0_Cause_BD		\
131 			 | CP0_Cause_IP		\
132 			 | CP0_Cause_IP7	\
133 			 | CP0_Cause_IP6	\
134 			 | CP0_Cause_IP5	\
135 			 | CP0_Cause_IP4	\
136 			 | CP0_Cause_IP3	\
137 			 | CP0_Cause_IP2	\
138 			 | CP0_Cause_ExcCode)
139 #define CP0_ExCode	((CP0_Cause & CP0_Cause_ExcCode) >> 2)
140 
141 /* EPC register: */
142 #define CP0_EPC_Reg	14
143 #define CP0_EPC		(CPR[0][CP0_EPC_Reg])
144 
145 /* Config register: */
146 #define CP0_Config_Reg	16
147 #define CP0_Config	(CPR[0][CP0_Config_Reg])
148 /* Implemented fields: */
149 #define CP0_Config_BE	0x000080000
150 #define CP0_Config_AT	0x000060000
151 #define CP0_Config_AR	0x00001c000
152 #define CP0_Config_MT	0x000000380
153 #define CP0_Config_Mask (CP0_Config_BE		\
154 			 | CP0_Config_AT	\
155 			 | CP0_Config_AR	\
156 			 | CP0_Config_MT)
157 
158 
159 
160 /* Floating Point Coprocessor (1) registers.
161 
162    This is the MIPS32, Revision 1 FPU register set. It contains 32, 32-bit
163    registers (either 32 single or 16 double precision), as in the R2010.
164    The MIPS32, Revision 2 or MIPS64 register set has 32 of each type of
165    register. */
166 
167 #define FGR_LENGTH	32
168 #define FPR_LENGTH	16
169 
170 extern double *FPR;		/* Dynamically allocate so overlay */
171 extern float *FGR;		/* is possible */
172 extern int *FWR;		/* is possible */
173 
174 
175 #define FPR_S(REGNO)	(FGR[REGNO])
176 
177 #define FPR_D(REGNO)	(((REGNO) & 0x1) \
178 			 ? (run_error ("Odd FP double register number\n") , 0.0) \
179 			 : FPR[(REGNO) / 2])
180 
181 #define FPR_W(REGNO)	(FWR[REGNO])
182 
183 
184 #define SET_FPR_S(REGNO, VALUE)	{FGR[REGNO] = (float) (VALUE);}
185 
186 #define SET_FPR_D(REGNO, VALUE) {if ((REGNO) & 0x1) \
187 				 run_error ("Odd FP double register number\n"); \
188 				 else FPR[(REGNO) / 2] = (double) (VALUE);}
189 
190 #define SET_FPR_W(REGNO, VALUE) {FWR[REGNO] = (int32) (VALUE);}
191 
192 
193 /* Floating point control registers: */
194 
195 #define FCR		(CPR[1])
196 
197 
198 #define FIR_REG		0
199 #define FIR		(FCR[FIR_REG])
200 /* Implemented fields: */
201 #define FIR_W		0x0008000
202 #define FIR_D		0x0001000
203 #define FIR_S		0x0000800
204 #define FIR_MASK	(FIR_W | FIR_D | FIR_S)
205 
206 #define FCCR_REG	25
207 #define FCCR		(FCR[FCCR_REG])
208 /* Implemented fields: */
209 #define FCCR_FCC	0x000000ff
210 #define FCCR_MASK	(FCCR_FCC)
211 
212 #define FEXR_REG	26
213 #define FEXR		(FCR[FEXR_REG])
214 /* No implemented fields */
215 
216 #define FENR_REG	28
217 #define FENR		(FCR[FENR_REG])
218 /* No implemented fields */
219 
220 #define FCSR_REG	31
221 #define FCSR		(FCR[FCSR_REG])
222 /* Implemented fields: */
223 #define FCSR_FCC	0xfe800000
224 #define FCSR_MASK	(FCSR_FCC)
225 /* Floating point Cause (not implemented): */
226 #define FCSR_Cause_E	0x00020000
227 #define FCSR_Cause_V	0x00010000
228 #define FCSR_Cause_Z	0x00008000
229 #define FCSR_Cause_O	0x00004000
230 #define FCSR_Cause_U	0x00002000
231 #define FCSR_Cause_I	0x00001000
232 /* Floating point Enables (not implemented): */
233 #define FCSR_Enable_V	0x00000800
234 #define FCSR_Enable_Z	0x00000400
235 #define FCSR_Enable_O	0x00000200
236 #define FCSR_Enable_U	0x00000100
237 #define FCSR_Enable_I	0x00000080
238 /* Floating point Flags (not implemented): */
239 #define FCSR_Flag_V	0x00000040
240 #define FCSR_Flag_Z	0x00000020
241 #define FCSR_Flag_O	0x00000010
242 #define FCSR_Flag_U	0x00000008
243 #define FCSR_Flag_I	0x00000004
244