Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: SS_InstrCtr.py | |
4 | # Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
5 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
6 | # | |
7 | # The above named program is free software; you can redistribute it and/or | |
8 | # modify it under the terms of the GNU General Public | |
9 | # License version 2 as published by the Free Software Foundation. | |
10 | # | |
11 | # The above named program is distributed in the hope that it will be | |
12 | # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | # General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public | |
17 | # License along with this work; if not, write to the Free Software | |
18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | # | |
20 | # ========== Copyright Header End ============================================ | |
21 | ||
22 | from SS_Instr import * | |
23 | from SS_Setup import * | |
24 | ||
25 | import SS_StateAsr | |
26 | import SS_StatePrf | |
27 | import SS_StateHrf | |
28 | ||
29 | setup = setups[sys.argv[1]] | |
30 | ||
31 | #============================================================================ | |
32 | # SS_rdctr(reg) | |
33 | #============================================================================ | |
34 | ||
35 | class SS_rdctr(SS_InstrCpp): | |
36 | def __init__(self,reg): | |
37 | SS_InstrCpp.__init__(self,'rd'+reg.table+'_'+reg.name) | |
38 | self.out = ['rd','g0'] | |
39 | self.reg = reg | |
40 | ||
41 | def run_exe_c(self,file): | |
42 | for out in self.out: | |
43 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
44 | ||
45 | if self.check_tl_zero(): | |
46 | file.write(' if (s->tl() == 0)\n') | |
47 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
48 | file.write(' uint32_t opc = i->opc();\n') | |
49 | self.ill_ibe(file,' ') | |
50 | ||
51 | elif self.reg.name == 'tick' or self.reg.name == 'stick': | |
52 | if setup.product == 'N2': | |
53 | file.write(' if (s->'+self.reg.name+'.npt() && (s->sim_state.priv() == SS_Strand::SS_USER))\n') | |
54 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_ACTION);\n') | |
55 | ||
56 | elif self.reg.name == 'gsr': | |
57 | file.write(' if (s->sim_state.fp_disabled())\n') | |
58 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
59 | ||
60 | elif (setup.product in ['N2']) and self.reg.name == 'pic': | |
61 | file.write(' if (((%s_Strand*)s)->pcr.priv() && (s->sim_state.priv() == SS_Strand::SS_USER))\n' % (self.reg.class_prefix)) | |
62 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_ACTION);\n') | |
63 | ||
64 | if out == 'rd': | |
65 | if (setup.product in ['N2']) and (self.reg.name in ['tick_cmpr','stick_cmpr','hstick_cmpr']): | |
66 | file.write(' '+setup.product+'_Strand* _s = ('+setup.product+'_Strand*)s;\n') | |
67 | file.write(' if (_s->sim_state.ras_enabled())\n') | |
68 | file.write(' {\n') | |
69 | file.write(' '+setup.product+'_MemErrDetector& n2_med = ('+setup.product+'_MemErrDetector&) _s->mem_err_detector;\n') | |
70 | file.write(' SS_Trap::Type tt = n2_med.n2_tick_cmpr_precise_err_detector(s,N2_TickAccess::'+self.reg.name.upper()+'_INDX);\n') | |
71 | file.write(' if (tt != SS_Trap::NO_TRAP)\n') | |
72 | file.write(' return (s->trap)(pc,npc,s,i,tt);\n') | |
73 | file.write(' }\n') | |
74 | else: | |
75 | type = self.reg.class_prefix+'_Strand*' | |
76 | file.write(' '+type+' _s = ('+type+')s;\n') | |
77 | ||
78 | if self.reg.name == 'pc': | |
79 | file.write(' SS_Vaddr _pc = pc & _s->mask_pstate_am;\n') | |
80 | if setup.va_bits != 64: | |
81 | file.write(' _pc = (_pc << (64 - '+str(setup.va_bits)+')) >> (64 - '+str(setup.va_bits)+');\n') | |
82 | file.write(' _s->get_irf(i->rd) = _pc;\n') | |
83 | elif self.reg.name == 'tpc' or self.reg.name == 'tnpc': | |
84 | file.write(' SS_Vaddr va = _s->'+self.reg.name+'();\n') | |
85 | if setup.va_bits != 64: | |
86 | file.write(' va = (va << (64 - '+str(setup.va_bits)+')) >> (64 - '+str(setup.va_bits)+');\n') | |
87 | file.write(' _s->get_irf(i->rd) = va;\n') | |
88 | elif self.reg.name == 'tick': | |
89 | if setup.product == 'N2': | |
90 | file.write(' _s->get_irf(i->rd) = _s->tick();\n') | |
91 | file.write('#ifdef COMPILE_FOR_COSIM\n') | |
92 | file.write(' if (_s->ctr_sync)\n') | |
93 | file.write(' {\n') | |
94 | file.write(' std::map<SS_Registers::Index,uint64_t>::const_iterator x = _s->ctr_sync->find(SS_Registers::ASR_TICK);\n') | |
95 | file.write(' if (x != _s->ctr_sync->end())\n') | |
96 | file.write(' _s->get_irf(i->rd) = (((*x).second << 1) >> 1) | (s->tick.npt() << 63);\n') | |
97 | file.write(' }\n') | |
98 | file.write('#endif\n') | |
99 | elif self.reg.name == 'stick': | |
100 | if setup.product == 'N2': | |
101 | file.write(' _s->get_irf(i->rd) = _s->stick();\n') | |
102 | file.write('#ifdef COMPILE_FOR_COSIM\n') | |
103 | file.write(' if (_s->ctr_sync)\n') | |
104 | file.write(' {\n') | |
105 | file.write(' std::map<SS_Registers::Index,uint64_t>::const_iterator x = _s->ctr_sync->find(SS_Registers::ASR_STICK);\n') | |
106 | file.write(' if (x != _s->ctr_sync->end())\n') | |
107 | file.write(' _s->get_irf(i->rd) = (((*x).second << 1) >> 1) | (s->stick.npt() << 63);\n') | |
108 | file.write(' }\n') | |
109 | file.write('#endif\n') | |
110 | elif self.reg.name == 'halt': | |
111 | file.write(' _s->get_irf(i->rd) = 0;\n') # Why waist space in the state vector. | |
112 | elif self.reg.name == 'asi_reg': | |
113 | file.write(' _s->get_irf(i->rd) = _s->asi();\n') | |
114 | else: | |
115 | file.write(' _s->get_irf(i->rd) = _s->'+self.reg.name+'();\n') | |
116 | ||
117 | if self.reg.name == 'pcr' and (setup.product in ['N2']): | |
118 | file.write('#ifdef COMPILE_FOR_COSIM\n') | |
119 | file.write(' if (_s->ctr_sync)\n') | |
120 | file.write(' {\n') | |
121 | file.write(' std::map<SS_Registers::Index,uint64_t>::const_iterator x = _s->ctr_sync->find(SS_Registers::ASR_PCR);\n') | |
122 | file.write(' if (x != _s->ctr_sync->end())\n') | |
123 | file.write(' _s->get_irf(i->rd) = (*x).second;\n') | |
124 | file.write(' }\n') | |
125 | file.write('#endif\n') | |
126 | elif self.reg.name == 'pic' and (setup.product in ['N2']): | |
127 | file.write('#ifdef COMPILE_FOR_COSIM\n') | |
128 | file.write(' if (_s->ctr_sync)\n') | |
129 | file.write(' {\n') | |
130 | file.write(' std::map<SS_Registers::Index,uint64_t>::const_iterator x = _s->ctr_sync->find(SS_Registers::ASR_PIC);\n') | |
131 | file.write(' if (x != _s->ctr_sync->end())\n') | |
132 | file.write(' _s->get_irf(i->rd) = (*x).second;\n') | |
133 | file.write(' }\n') | |
134 | file.write('#endif\n') | |
135 | ||
136 | else: | |
137 | if self.reg.name == 'pcr' and (setup.product in ['N2']): | |
138 | type = self.reg.class_prefix+'_Strand*' | |
139 | file.write(' '+type+' _s = ('+type+')s;\n') | |
140 | elif (setup.product in ['N2']) and (self.reg.name in ['tick_cmpr','stick_cmpr','hstick_cmpr']): | |
141 | file.write(' '+setup.product+'_Strand* _s = ('+setup.product+'_Strand*)s;\n') | |
142 | file.write(' if (_s->sim_state.ras_enabled())\n') | |
143 | file.write(' {\n') | |
144 | file.write(' '+setup.product+'_MemErrDetector& n2_med = ('+setup.product+'_MemErrDetector&) _s->mem_err_detector;\n') | |
145 | file.write(' SS_Trap::Type tt = n2_med.n2_tick_cmpr_precise_err_detector(s,N2_TickAccess::'+self.reg.name.upper()+'_INDX);\n') | |
146 | file.write(' if (tt != SS_Trap::NO_TRAP)\n') | |
147 | file.write(' return (s->trap)(pc,npc,s,i,tt);\n') | |
148 | file.write(' }\n') | |
149 | ||
150 | ||
151 | file.write(' s->npc = npc + 4; return npc;\n') | |
152 | self.c_code_end(file) | |
153 | ||
154 | def run_dec_c(self,file): | |
155 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
156 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
157 | ||
158 | file.write(' if (o.is_zero_13_0())\n') | |
159 | file.write(' {\n') | |
160 | ||
161 | if self.reg.access.user_read_ill_inst() or self.reg.access.user_read_priv_opc(): | |
162 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
163 | if self.reg.access.user_read_ill_inst(): | |
164 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
165 | elif self.reg.access.user_read_priv_opc(): | |
166 | file.write(' {\n') | |
167 | self.ill_ibe(file,' ') | |
168 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
169 | file.write(' }\n') | |
170 | if self.reg.access.priv_read_ill_inst(): | |
171 | file.write(' else if (s->sim_state.priv() == SS_Strand::SS_PRIV)\n') | |
172 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
173 | file.write('\n') | |
174 | ||
175 | # for tt,tpc,tnpc,tstate,htstate we need to check current tl value, | |
176 | # hence we need to postpone checks until excecute time | |
177 | ||
178 | if not self.check_tl_zero(): | |
179 | self.ill_ibe(file,' ') | |
180 | file.write('\n') | |
181 | ||
182 | file.write(' if (o.get_rd_irf())\n') | |
183 | self.dec_r00(file,' ','idx_exe_'+self.name+'_rd') | |
184 | file.write(' else\n') | |
185 | self.dec_000(file,' ','idx_exe_'+self.name+'_g0') | |
186 | file.write(' }\n') | |
187 | file.write(' else\n') | |
188 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
189 | self.c_code_end(file) | |
190 | ||
191 | def exe_idx_s(self,file): | |
192 | for out in self.out: | |
193 | self.exe_idx_s_name(file,self.name+'_'+out) | |
194 | ||
195 | def gen_exe_tbl(self,file,mode): | |
196 | for out in self.out: | |
197 | if mode == 'trc': | |
198 | file.write(' trc_exe_r00, /* '+self.name+'_'+out+' */\n') | |
199 | elif mode == 'v8_run': | |
200 | file.write(' run_exe_'+self.name+'_'+out+',\n') | |
201 | else: | |
202 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
203 | ||
204 | def check_tl_zero(self): | |
205 | return self.reg.name == 'tpc' or self.reg.name == 'tnpc' or \ | |
206 | self.reg.name == 'tstate' or self.reg.name == 'tt' or self.reg.name == 'htstate' | |
207 | ||
208 | #============================================================================ | |
209 | # SS_wrctr(reg) | |
210 | #============================================================================ | |
211 | ||
212 | class SS_wrctr(SS_InstrCpp): | |
213 | def __init__(self,reg): | |
214 | SS_InstrCpp.__init__(self,'wr'+reg.table+'_'+reg.name) | |
215 | self.imm = ['i0','i1'] | |
216 | self.reg = reg | |
217 | ||
218 | def run_exe_c(self,file): | |
219 | for imm in self.imm: | |
220 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm) | |
221 | self.fail_chkpt(file) | |
222 | ||
223 | if imm == 'i0': | |
224 | file.write(' uint64_t val = s->get_irf(i->rs1) ^ s->get_irf(i->rs2);\n') | |
225 | else: | |
226 | file.write(' uint64_t val = s->get_irf(i->rs1) ^ i->rs2;\n') | |
227 | ||
228 | if self.reg.name == 'asi_reg': | |
229 | file.write(' s->asi = val;\n') | |
230 | ||
231 | elif self.reg.name == 'tl': | |
232 | file.write(' s->tl_save();\n') | |
233 | file.write(' // make sure val is properly masked by tl register\n') | |
234 | file.write(' s->tl.set(val);\n') | |
235 | file.write(' val = s->tl();\n') | |
236 | file.write(' if (s->sim_state.priv() > SS_Strand::SS_PRIV)\n') | |
237 | file.write(' s->tl = (val > s->max_tl()) ? s->max_tl() : val;\n') | |
238 | file.write(' else\n') | |
239 | file.write(' s->tl = (val > s->max_ptl()) ? s->max_ptl() : val;\n') | |
240 | file.write(' s->tl_load();\n') | |
241 | file.write(' (s->sim_update)(s);\n') | |
242 | ||
243 | elif self.check_tl_zero(): | |
244 | file.write(' if (s->tl() == 0)\n') | |
245 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
246 | file.write(' else\n') | |
247 | file.write(' {\n') | |
248 | file.write(' uint32_t opc = i->opc();\n') | |
249 | self.ill_ibe(file,' ') | |
250 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
251 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
252 | type = self.reg.class_prefix+'_Strand*' | |
253 | file.write(' '+type+' _s = ('+type+')s;\n') | |
254 | if setup.va_bits < 64: | |
255 | sft = '(64-'+str(setup.va_bits)+')' | |
256 | file.write(' val = int64_t(val << '+sft+') >> '+sft+';\n') | |
257 | file.write(' _s->'+self.reg.name+'.set(val);\n') | |
258 | file.write(' }\n') | |
259 | ||
260 | elif self.reg.name == 'gl': | |
261 | file.write(' s->gl_save();\n') | |
262 | file.write(' // make sure val is properly masked by gl register\n') | |
263 | file.write(' s->gl.set(val);\n') | |
264 | file.write(' val = s->gl();\n') | |
265 | file.write(' if (s->sim_state.priv() > SS_Strand::SS_PRIV)\n') | |
266 | file.write(' s->gl = (val > s->max_gl()) ? s->max_gl() : val;\n') | |
267 | file.write(' else\n') | |
268 | file.write(' s->gl = (val > s->max_pgl()) ? s->max_pgl() : val;\n') | |
269 | file.write(' s->gl_load();\n') | |
270 | ||
271 | elif (setup.va_bits < 64) and (self.reg.name == 'tba' or self.reg.name == 'htba'): | |
272 | sft = '(64-'+str(setup.va_bits)+')' | |
273 | file.write(' s->'+self.reg.name+'.set(int64_t(val << '+sft+') >> '+sft+');\n') | |
274 | ||
275 | elif self.reg.name == 'cwp': | |
276 | file.write(' s->cwp_save();\n') | |
277 | file.write(' s->cwp.set(val % (s->max_wp() + 1));\n') | |
278 | file.write(' s->cwp_load();\n') | |
279 | ||
280 | elif self.reg.name == 'cansave' or self.reg.name == 'canrestore' \ | |
281 | or self.reg.name == 'cleanwin' or self.reg.name == 'otherwin': | |
282 | file.write(' s->'+self.reg.name+'.set(val % (s->max_wp() + 1));\n') | |
283 | ||
284 | elif self.reg.name == 'fprs' or self.reg.name == 'pstate' or self.reg.name == 'hpstate': | |
285 | file.write(' s->'+self.reg.name+'.set(val);\n') | |
286 | file.write(' (s->sim_update)(s);\n') | |
287 | ||
288 | elif self.reg.name == 'pil': | |
289 | file.write(' s->pil.set(val);\n') | |
290 | file.write(' s->irq.check(s);\n') | |
291 | ||
292 | elif self.reg.name == 'softint': | |
293 | file.write(' s->softint.set(val);\n') | |
294 | file.write(' s->irq.update_softint(s);\n') | |
295 | ||
296 | elif self.reg.name == 'softint_set': | |
297 | file.write(' s->softint.set(s->softint() | val);\n') | |
298 | file.write(' s->irq.update_softint(s);\n') | |
299 | ||
300 | elif self.reg.name == 'softint_clr': | |
301 | file.write(' s->softint.set(s->softint() &~ val);\n') | |
302 | file.write(' s->irq.update_softint(s);\n') | |
303 | ||
304 | elif self.reg.name == 'hintp': | |
305 | file.write(' s->hintp.set(val);\n') | |
306 | file.write(' if (s->hintp.hsp())\n') | |
307 | file.write(' s->irq.raise(s,SS_Interrupt::BIT_HSTICK_MATCH);\n') | |
308 | file.write(' else\n') | |
309 | file.write(' s->irq.retract(SS_Interrupt::BIT_HSTICK_MATCH);\n') | |
310 | file.write(' if (s->hintp())\n') | |
311 | file.write(' s->irq.check(s);\n') | |
312 | ||
313 | elif self.reg.name == 'halt': | |
314 | # The halt sets running=false and let the strand wait | |
315 | # for an interrupt and then wakes it. | |
316 | file.write(' if (!s->softint.sm() && !s->softint.tm() && !s->hintp.hsp())\n') | |
317 | file.write(' {\n') | |
318 | file.write(' s->halted = true;\n') | |
319 | file.write(' if (!s->sim_state.cosim())\n') | |
320 | file.write(' {\n') | |
321 | file.write(' s->sim_state.running(false);\n') | |
322 | file.write(' if (s->change_running)\n') | |
323 | file.write(' (s->change_running)(s);\n') | |
324 | file.write(' s->running = false;\n') | |
325 | file.write(' s->msg.set_reenter_loop();\n') | |
326 | file.write(' }\n') | |
327 | file.write(' }\n') | |
328 | ||
329 | elif self.reg.name == 'gsr': | |
330 | file.write(' if (s->sim_state.fp_disabled())\n') | |
331 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
332 | file.write(' s->gsr.set(val);\n') | |
333 | ||
334 | elif (setup.product in ['N2']) and self.reg.name == 'pic': | |
335 | file.write(' if (((%s_Strand*)s)->pcr.priv() && (s->sim_state.priv() == SS_Strand::SS_USER))\n' % (self.reg.class_prefix)) | |
336 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_ACTION);\n') | |
337 | type = self.reg.class_prefix+'_Strand*' | |
338 | file.write(' '+type+' _s = ('+type+')s;\n') | |
339 | file.write(' _s->'+self.reg.name+'.set(val);\n') | |
340 | ||
341 | elif (setup.product in ['N2']) and self.reg.name == 'pcr': | |
342 | file.write(' %s_Strand* n2 = (%s_Strand*)s;\n' % (self.reg.class_prefix, self.reg.class_prefix)) | |
343 | file.write(' uint64_t ov0 = n2->pcr.ov0();\n') | |
344 | file.write(' uint64_t ov1 = n2->pcr.ov1();\n') | |
345 | file.write(' if (n2->sim_state.priv() > SS_Strand::SS_PRIV)\n') | |
346 | file.write(' {\n') | |
347 | file.write(' n2->pcr.set(val);\n') | |
348 | file.write(' }\n') | |
349 | file.write(' else\n') | |
350 | file.write(' {\n') | |
351 | file.write(' uint64_t ht = n2->pcr.ht();\n') | |
352 | file.write(' n2->pcr.set(val);\n') | |
353 | file.write(' n2->pcr.ht(ht);\n') | |
354 | file.write(' }\n') | |
355 | file.write(' n2->pcr.ov0(n2->pcr.ov0wr() ? n2->pcr.ov0() : ov0);\n') | |
356 | file.write(' n2->pcr.ov1(n2->pcr.ov1wr() ? n2->pcr.ov1() : ov1);\n') | |
357 | file.write(' n2->pcr.ov0wr(0).ov1wr(0);\n') | |
358 | ||
359 | elif self.reg.name == 'tick' or self.reg.name == 'stick': | |
360 | if setup.product in ['N2']: | |
361 | file.write(' s->stick.set(val);\n') | |
362 | file.write(' s->tick.set(val);\n') | |
363 | else: | |
364 | file.write(' s->'+self.reg.name+'.set(val);\n') | |
365 | ||
366 | elif (setup.product in ['N2']) and (self.reg.name in ['tick_cmpr','stick_cmpr','hstick_cmpr']): | |
367 | file.write(' '+setup.product+'_Strand* _s = ('+setup.product+'_Strand*)s;\n') | |
368 | file.write(' if (_s->sim_state.ras_enabled())\n') | |
369 | file.write(' {\n') | |
370 | file.write(' '+setup.product+'_MemErrDetector& n2_med = ('+setup.product+'_MemErrDetector&) _s->mem_err_detector;\n') | |
371 | file.write(' _s->tick_cmpr_array_ecc[N2_TickAccess::'+self.reg.name.upper()+'_INDX] = n2_med.n2_tick_cmpr_err_injector(s,val);\n') | |
372 | file.write(' }\n') | |
373 | file.write(' _s->'+self.reg.name+'.set(val);\n') | |
374 | ||
375 | else: | |
376 | type = self.reg.class_prefix+'_Strand*' | |
377 | file.write(' '+type+' _s = ('+type+')s;\n') | |
378 | file.write(' _s->'+self.reg.name+'.set(val);\n') | |
379 | ||
380 | file.write(' s->npc = npc + 4; return npc;\n') | |
381 | self.c_code_end(file) | |
382 | ||
383 | def run_dec_c(self,file): | |
384 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
385 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
386 | ||
387 | if self.reg.access.user_write_ill_inst() or self.reg.access.user_write_priv_opc(): | |
388 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
389 | if self.reg.access.user_write_ill_inst(): | |
390 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
391 | elif self.reg.access.user_write_priv_opc(): | |
392 | file.write(' {\n') | |
393 | self.ill_ibe(file,' ') | |
394 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
395 | file.write(' }\n') | |
396 | if self.reg.access.priv_write_ill_inst(): | |
397 | file.write(' else if (s->sim_state.priv() == SS_Strand::SS_PRIV)\n') | |
398 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
399 | ||
400 | file.write(' if (o.get_i())\n') | |
401 | file.write(' {\n') | |
402 | if not self.check_tl_zero(): | |
403 | self.ill_ibe(file,' ') | |
404 | self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1') | |
405 | file.write(' }\n') | |
406 | file.write(' else if (o.is_zero_12_5())\n') | |
407 | file.write(' {\n') | |
408 | if not self.check_tl_zero(): | |
409 | self.ill_ibe(file,' ') | |
410 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0') | |
411 | file.write(' }\n') | |
412 | file.write(' else\n') | |
413 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
414 | self.c_code_end(file) | |
415 | ||
416 | def gen_exe_tbl(self,file,mode): | |
417 | for imm in self.imm: | |
418 | if mode == 'trc': | |
419 | if imm == 'i0': | |
420 | file.write(' trc_exe_0rr, /* '+self.name+'_'+imm+' */\n') | |
421 | else: | |
422 | file.write(' trc_exe_0r0, /* '+self.name+'_'+imm+' */\n') | |
423 | elif mode == 'v8_run': | |
424 | file.write(' run_exe_'+self.name+'_'+imm+',\n') | |
425 | else: | |
426 | file.write(' '+mode+'_exe_'+self.name+'_'+imm+',\n') | |
427 | ||
428 | def check_tl_zero(self): | |
429 | return self.reg.name == 'tpc' or self.reg.name == 'tnpc' or \ | |
430 | self.reg.name == 'tstate' or self.reg.name == 'tt' or self.reg.name == 'htstate' | |
431 | ||
432 | #============================================================================ | |
433 | # SS_membar() | |
434 | #============================================================================ | |
435 | ||
436 | class SS_membar(SS_InstrCpp): | |
437 | def __init__(self): | |
438 | SS_InstrCpp.__init__(self,'membar') | |
439 | ||
440 | def run_exe_c(self,file): | |
441 | self.c_code_beg_name(file,'run_exe_membar') | |
442 | self.fail_chkpt(file) | |
443 | file.write(' s->npc = npc + 4; return npc;\n') | |
444 | self.c_code_end(file) | |
445 | ||
446 | def run_dec_p(self): | |
447 | return '' | |
448 | ||
449 | def gen_exe_tbl(self,file,mode): | |
450 | self.gen_exe_passthrough(file,mode) | |
451 | ||
452 | ||
453 | #============================================================================ | |
454 | # SS_stbar() | |
455 | #============================================================================ | |
456 | ||
457 | class SS_stbar(SS_InstrCpp): | |
458 | def __init__(self): | |
459 | SS_InstrCpp.__init__(self,'stbar') | |
460 | ||
461 | def run_exe_c(self,file): | |
462 | self.c_code_beg_name(file,'run_exe_stbar') | |
463 | self.fail_chkpt(file) | |
464 | file.write(' s->npc = npc + 4; return npc;\n') | |
465 | self.c_code_end(file) | |
466 | ||
467 | def run_dec_p(self): | |
468 | return '' | |
469 | ||
470 | def gen_exe_tbl(self,file,mode): | |
471 | self.gen_exe_passthrough(file,mode) | |
472 | ||
473 | ||
474 | #============================================================================ | |
475 | # SS_rdasr15() | |
476 | #============================================================================ | |
477 | ||
478 | class SS_rdasr15(SS_InstrCpp): | |
479 | def __init__(self): | |
480 | SS_InstrCpp.__init__(self,'rdasr15') | |
481 | ||
482 | def run_dec_c(self,file): | |
483 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
484 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
485 | file.write(' if (o.get_rd() == 0)\n') | |
486 | file.write(' {\n') | |
487 | file.write(' if (o.is_zero_13_0())\n') | |
488 | file.write(' {\n') | |
489 | self.ill_ibe(file,' ') | |
490 | self.dec_000(file,' ','idx_exe_stbar') | |
491 | file.write(' }\n') | |
492 | file.write(' else if (o.get_i() && o.is_zero_12_7())\n') | |
493 | file.write(' {\n') | |
494 | self.ill_ibe(file,' ') | |
495 | self.dec_007(file,' ','idx_exe_membar') | |
496 | file.write(' }\n') | |
497 | file.write(' else\n') | |
498 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
499 | file.write(' }\n') | |
500 | file.write(' else\n') | |
501 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
502 | self.c_code_end(file) | |
503 | ||
504 | def exe_idx_s(self,file): | |
505 | pass | |
506 | ||
507 | def gen_exe_tbl(self,file,mode): | |
508 | pass | |
509 | ||
510 | #============================================================================ | |
511 | # SS_sir() | |
512 | #============================================================================ | |
513 | ||
514 | class SS_sir(SS_InstrCpp): | |
515 | def __init__(self): | |
516 | SS_InstrCpp.__init__(self,'sir') | |
517 | ||
518 | def run_exe_c(self,file): | |
519 | self.c_code_beg_name(file,'run_exe_sir') | |
520 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::SOFTWARE_INITIATED_RESET);\n') | |
521 | self.c_code_end(file) | |
522 | ||
523 | def run_dec_c(self,file): | |
524 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
525 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
526 | file.write(' if (s->sim_state.priv() < SS_Strand::SS_HPRV)\n') | |
527 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
528 | file.write(' else if ((o.get_rs1() == 0) && o.get_i())\n') | |
529 | file.write(' {\n') | |
530 | if not setup.product in ['N2']: | |
531 | self.ill_ibe(file,' ') | |
532 | self.dec_0013(file,' ','idx_exe_sir') | |
533 | file.write(' }\n') | |
534 | file.write(' else\n') | |
535 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
536 | self.c_code_end(file) | |
537 | ||
538 | def gen_exe_tbl(self,file,mode): | |
539 | self.gen_exe_passthrough(file,mode) | |
540 | ||
541 | #============================================================================ | |
542 | # ss_rdasr/ss_wrasr | |
543 | #============================================================================ | |
544 | ||
545 | ss_rdasr = SS_InstrGroup('10_101000_rdasr',14,0x1f) | |
546 | ss_wrasr = SS_InstrGroup('10_110000_wrasr',25,0x1f) | |
547 | ||
548 | for i in range(0,32): | |
549 | if i == 15: | |
550 | ss_rdasr.append(SS_rdasr15()) | |
551 | ss_rdasr.append(SS_membar()) | |
552 | ss_rdasr.append(SS_stbar()) | |
553 | ss_wrasr.append(SS_sir()) | |
554 | else: | |
555 | r = SS_StateAsr.ctr_table.reg_at(i) | |
556 | ||
557 | if r == None or r.access.is_wo(): | |
558 | ss_rdasr.append(SS_ill()) | |
559 | else: | |
560 | ss_rdasr.append(SS_rdctr(r)) | |
561 | ||
562 | if r == None or r.access.is_ro(): | |
563 | ss_wrasr.append(SS_ill()) | |
564 | else: | |
565 | ss_wrasr.append(SS_wrctr(r)) | |
566 | ||
567 | ||
568 | #============================================================================ | |
569 | # ss_rdprf/ss_wrprf | |
570 | #============================================================================ | |
571 | ||
572 | ss_rdprf = SS_InstrGroup('10_101010_rdprf',14,0x1f) | |
573 | ss_wrprf = SS_InstrGroup('10_110010_wrprf',25,0x1f) | |
574 | ||
575 | for i in range(0,32): | |
576 | r = SS_StatePrf.ctr_table.reg_at(i) | |
577 | ||
578 | if r == None or r.access.is_wo(): | |
579 | ss_rdprf.append(SS_ill()) | |
580 | else: | |
581 | ss_rdprf.append(SS_rdctr(r)) | |
582 | ||
583 | if r == None or r.access.is_ro(): | |
584 | ss_wrprf.append(SS_ill()) | |
585 | else: | |
586 | ss_wrprf.append(SS_wrctr(r)) | |
587 | ||
588 | ||
589 | #============================================================================ | |
590 | # ss_rdhrf/ss_wrhrf | |
591 | #============================================================================ | |
592 | ||
593 | ss_rdhrf = SS_InstrGroup('10_101001_rdhrf',14,0x1f) | |
594 | ss_wrhrf = SS_InstrGroup('10_110011_wrhrf',25,0x1f) | |
595 | ||
596 | for i in range(0,32): | |
597 | r = SS_StateHrf.ctr_table.reg_at(i) | |
598 | ||
599 | if r == None or r.access.is_wo(): | |
600 | ss_rdhrf.append(SS_ill()) | |
601 | else: | |
602 | ss_rdhrf.append(SS_rdctr(r)) | |
603 | ||
604 | if r == None or r.access.is_ro(): | |
605 | ss_wrhrf.append(SS_ill()) | |
606 | else: | |
607 | ss_wrhrf.append(SS_wrctr(r)) |