Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: SS_InstrCti.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 | # SS_Cti.py | |
23 | # | |
24 | # All Control Transfer Instruction (CTI) decode and implementation | |
25 | #============================================================================ | |
26 | ||
27 | from SS_Instr import * | |
28 | from SS_Setup import * | |
29 | ||
30 | setup = setups[sys.argv[1]] | |
31 | ||
32 | #============================================================================ | |
33 | # The not-annulled versions (_a0) of the branches do | |
34 | # | |
35 | # n : pc = npc , npc = npc+4 | |
36 | # a : pc = npc , npc = ea | |
37 | # c : pc = npc , npc = c ? ea : npc+4 | |
38 | # | |
39 | # annulled versions (_a1) of the branches do | |
40 | # | |
41 | # n : pc = npc+4 , npc = npc+8 | |
42 | # a : pc = ea , npc = ea+4 | |
43 | # c : pc = c ? npc : npc+4 , npc = c ? ea : npc+8 | |
44 | #============================================================================ | |
45 | ||
46 | #============================================================================ | |
47 | # SS_bp_a0(cc,ccr) | |
48 | #============================================================================ | |
49 | ||
50 | class SS_bp_a0(SS_InstrAsm): | |
51 | def __init__(self,cc,ccr): | |
52 | SS_InstrAsm.__init__(self,'bp'+cc+'_'+ccr+'_a0') | |
53 | self.cc = cc | |
54 | self.ccr = ccr | |
55 | ||
56 | def run_exe_s(self,file): | |
57 | self.asm_function(file,'run_exe_'+self.name) | |
58 | if (self.cc == 'n'): | |
59 | self.mov(file,self.NPC,self.PC) | |
60 | self.add(file,self.NPC,4,self.NPC) | |
61 | self.retl_st_npc(file,self.NPC) | |
62 | elif (self.cc == 'a'): | |
63 | self.mov(file,self.NPC,self.PC) | |
64 | self.ld_ea_rd(file,self.NPC) | |
65 | self.retl_st_npc(file,self.NPC) | |
66 | else: | |
67 | self.mov(file,self.NPC,self.PC) | |
68 | self.ld_ccr(file,'%g1') | |
69 | self.add(file,self.NPC,4,self.NPC) | |
70 | self.ld_ea_rd(file,'%g2') | |
71 | self.wr_ccr(file,'%g1') | |
72 | self.movcc(file,self.cc,'%'+self.ccr,'%g2',self.NPC) | |
73 | self.retl_st_npc(file,self.NPC) | |
74 | self.asm_codesize(file,'run_exe_'+self.name) | |
75 | ||
76 | self.asm_function(file,'run_tct_'+self.name) | |
77 | if (self.cc == 'n'): | |
78 | self.mov(file,self.NPC,self.PC) | |
79 | self.add(file,self.NPC,'4',self.NPC) | |
80 | self.retl_st_npc(file,self.NPC) | |
81 | elif (self.cc == 'a'): | |
82 | self.ld_trap(file,'%g5') | |
83 | self.jmpl(file,'%g5','%g0','%g0') | |
84 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
85 | else: | |
86 | self.ld_ccr(file,'%g1') | |
87 | self.ld_trap(file,'%g5') | |
88 | self.add(file,self.NPC,4,'%g4') | |
89 | self.wr_ccr(file,'%g1') | |
90 | self.branch(file,self.cc,'%'+self.ccr,'1f') | |
91 | self.nop(file) | |
92 | self.mov(file,self.NPC,self.PC) | |
93 | self.retl(file) | |
94 | self.st_npc(file,'%g4') | |
95 | file.write('1:\n') | |
96 | self.jmpl(file,'%g5','%g0','%g0') | |
97 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
98 | self.asm_codesize(file,'run_tct_'+self.name) | |
99 | ||
100 | def gen_exe_tbl(self,file,mode): | |
101 | if mode == 'trc': | |
102 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
103 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
104 | elif mode == 'v8_run': | |
105 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
106 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
107 | else: | |
108 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
109 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
110 | ||
111 | def idx_exe_s(self,file): | |
112 | self.idx_exe_s_name(file,'exe_'+self.name) | |
113 | self.idx_exe_s_name(file,'tct_'+self.name) | |
114 | ||
115 | def run_exe_c(self,file): | |
116 | file.write('#if defined(ARCH_X64)\n') | |
117 | self.c_code_beg(file,'run_exe_') | |
118 | file.write(' pc = npc;\n') | |
119 | self.test_icc(file,' ') | |
120 | file.write(' s->npc = (SS_Vaddr&)i->rd;\n') | |
121 | file.write(' else\n') | |
122 | file.write(' s->npc = npc+4;\n') | |
123 | file.write(' return pc;\n') | |
124 | self.c_code_end(file) | |
125 | self.c_code_beg(file,'run_tct_') | |
126 | self.test_icc(file,' ') | |
127 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
128 | file.write(' else {\n') | |
129 | file.write(' pc = npc;\n') | |
130 | file.write(' s->npc = npc+4;\n') | |
131 | file.write(' return pc;\n') | |
132 | file.write(' }\n') | |
133 | self.c_code_end(file) | |
134 | file.write('#else\n') | |
135 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
136 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
137 | file.write('#endif\n') | |
138 | ||
139 | def run_dec_c(self,file): | |
140 | self.c_code_dec_beg(file,'run_dec_') | |
141 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
142 | self.ill_ibe(file) | |
143 | file.write(' if (s->pstate.tct())\n') | |
144 | file.write(' idx = idx_tct_%s;\n' % self.name) | |
145 | file.write(' else\n') | |
146 | file.write(' idx = idx_exe_%s;\n' % self.name) | |
147 | file.write(' i->exe_tbl_idx = idx;\n') | |
148 | file.write(' i->exe = s->exe_table[idx];\n') | |
149 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n') | |
150 | self.c_code_dec_end(file) | |
151 | ||
152 | #============================================================================ | |
153 | # bp_a1 | |
154 | #============================================================================ | |
155 | ||
156 | class SS_bp_a1(SS_InstrAsm): | |
157 | def __init__(self,cc,ccr): | |
158 | SS_InstrAsm.__init__(self,'bp'+cc+'_'+ccr+'_a1') | |
159 | self.cc = cc | |
160 | self.ccr = ccr | |
161 | ||
162 | def run_exe_s(self,file): | |
163 | self.asm_function(file,'run_exe_'+self.name) | |
164 | if (self.cc == 'n'): | |
165 | self.add(file,self.NPC,4,self.PC) | |
166 | self.add(file,self.NPC,8,self.NPC) | |
167 | self.retl_st_npc(file,self.NPC) | |
168 | elif (self.cc == 'a'): | |
169 | self.ld_ea_rd(file,self.PC) | |
170 | self.add(file,self.PC,4,self.NPC) | |
171 | self.retl_st_npc(file,self.NPC) | |
172 | else: | |
173 | self.ld_ccr(file,'%g1') | |
174 | self.add(file,self.NPC,4,self.PC) | |
175 | self.ld_ea_rd(file,'%g2') | |
176 | self.wr_ccr(file,'%g1') | |
177 | self.movcc(file,self.cc,'%'+self.ccr,self.NPC,self.PC) | |
178 | self.add(file,self.NPC,8,self.NPC) | |
179 | self.movcc(file,self.cc,'%'+self.ccr,'%g2',self.NPC) | |
180 | self.retl_st_npc(file,self.NPC) | |
181 | self.asm_codesize(file,'run_exe_'+self.name) | |
182 | ||
183 | self.asm_function(file,'run_tct_'+self.name) | |
184 | if (self.cc == 'n'): | |
185 | self.add(file,self.NPC,4,self.PC) | |
186 | self.add(file,self.NPC,8,self.NPC) | |
187 | self.retl_st_npc(file,self.NPC) | |
188 | elif (self.cc == 'a'): | |
189 | self.ld_trap(file,'%g5') | |
190 | self.jmpl(file,'%g5','%g0','%g0') | |
191 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
192 | else: | |
193 | self.ld_ccr(file,'%g1') | |
194 | self.ld_trap(file,'%g5') | |
195 | self.add(file,self.NPC,8,'%g4') | |
196 | self.wr_ccr(file,'%g1') | |
197 | self.branch(file,self.cc,'%'+self.ccr,'1f') | |
198 | self.nop(file) | |
199 | self.add(file,self.NPC,4,self.PC) | |
200 | self.retl(file) | |
201 | self.st_npc(file,'%g4') | |
202 | file.write('1:\n') | |
203 | self.jmpl(file,'%g5','%g0','%g0') | |
204 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
205 | self.asm_codesize(file,'run_tct_'+self.name) | |
206 | ||
207 | def gen_exe_tbl(self,file,mode): | |
208 | if mode == 'trc': | |
209 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
210 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
211 | elif mode == 'v8_run': | |
212 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
213 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
214 | else: | |
215 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
216 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
217 | ||
218 | def idx_exe_s(self,file): | |
219 | self.idx_exe_s_name(file,'exe_'+self.name) | |
220 | self.idx_exe_s_name(file,'tct_'+self.name) | |
221 | ||
222 | def run_exe_c(self,file): | |
223 | file.write('#if defined(ARCH_X64)\n') | |
224 | self.c_code_beg(file,'run_exe_') | |
225 | if (self.cc == 'a'): | |
226 | file.write(' SS_Vaddr target = (SS_Vaddr&)i->rd;\n') | |
227 | file.write(' pc = target;\n') | |
228 | file.write(' s->npc = target+4;\n') | |
229 | else: | |
230 | self.test_icc(file,' ') | |
231 | file.write(' {\n') | |
232 | file.write(' pc = npc;\n') | |
233 | file.write(' s->npc = (SS_Vaddr&)i->rd;\n') | |
234 | file.write(' }\n') | |
235 | file.write(' else {\n') | |
236 | file.write(' pc = npc + 4;\n') | |
237 | file.write(' s->npc = npc + 8;\n') | |
238 | file.write(' }\n') | |
239 | file.write(' return pc;\n') | |
240 | self.c_code_end(file) | |
241 | self.c_code_beg(file,'run_tct_') | |
242 | self.test_icc(file,' ') | |
243 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
244 | file.write(' else {\n') | |
245 | file.write(' pc = npc + 4;\n') | |
246 | file.write(' s->npc = npc + 8;\n') | |
247 | file.write(' return pc;\n') | |
248 | file.write(' }\n') | |
249 | self.c_code_end(file) | |
250 | file.write('#else\n') | |
251 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
252 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
253 | file.write('#endif\n') | |
254 | ||
255 | def run_dec_c(self,file): | |
256 | self.c_code_dec_beg(file,'run_dec_') | |
257 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
258 | self.ill_ibe(file) | |
259 | file.write(' if (s->pstate.tct())\n') | |
260 | file.write(' idx = idx_tct_%s;\n' % self.name) | |
261 | file.write(' else\n') | |
262 | file.write(' idx = idx_exe_%s;\n' % self.name) | |
263 | file.write(' i->exe_tbl_idx = idx;\n') | |
264 | file.write(' i->exe = s->exe_table[idx];\n') | |
265 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n') | |
266 | self.c_code_dec_end(file) | |
267 | ||
268 | #============================================================================ | |
269 | # bi_a0 | |
270 | #============================================================================ | |
271 | ||
272 | class SS_bi_a0(SS_InstrAsm): | |
273 | def __init__(self,cc): | |
274 | SS_InstrAsm.__init__(self,'bi'+cc+'_a0') | |
275 | self.cc = cc | |
276 | ||
277 | def idx_exe_s(self,file): | |
278 | pass | |
279 | ||
280 | def gen_exe_tbl(self,file,mode): | |
281 | pass | |
282 | ||
283 | def run_dec_c(self,file): | |
284 | self.c_code_dec_beg(file,'run_dec_') | |
285 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
286 | self.ill_ibe(file) | |
287 | file.write(' if (s->pstate.tct())\n') | |
288 | file.write(' idx = idx_tct_bp%s_icc_a0;\n' % self.cc) | |
289 | file.write(' else\n') | |
290 | file.write(' idx = idx_exe_bp%s_icc_a0;\n' % self.cc) | |
291 | file.write(' i->exe_tbl_idx = idx;\n') | |
292 | file.write(' i->exe = s->exe_table[idx];\n') | |
293 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n') | |
294 | self.c_code_dec_end(file) | |
295 | ||
296 | #============================================================================ | |
297 | # bi_a1 | |
298 | #============================================================================ | |
299 | ||
300 | class SS_bi_a1(SS_InstrAsm): | |
301 | def __init__(self,cc): | |
302 | SS_InstrAsm.__init__(self,'bi'+cc+'_a1') | |
303 | self.cc = cc | |
304 | ||
305 | def idx_exe_s(self,file): | |
306 | pass | |
307 | ||
308 | def gen_exe_tbl(self,file,mode): | |
309 | pass | |
310 | ||
311 | def run_dec_c(self,file): | |
312 | self.c_code_dec_beg(file,'run_dec_') | |
313 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
314 | self.ill_ibe(file) | |
315 | file.write(' if (s->pstate.tct())\n') | |
316 | file.write(' idx = idx_tct_bp%s_icc_a1;\n' % self.cc) | |
317 | file.write(' else\n') | |
318 | file.write(' idx = idx_exe_bp%s_icc_a1;\n' % self.cc) | |
319 | file.write(' i->exe_tbl_idx = idx;\n') | |
320 | file.write(' i->exe = s->exe_table[idx];\n') | |
321 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n') | |
322 | self.c_code_dec_end(file) | |
323 | ||
324 | #============================================================================ | |
325 | # br_a0 | |
326 | #============================================================================ | |
327 | ||
328 | class SS_br_a0(SS_InstrAsm): | |
329 | def __init__(self,cc): | |
330 | SS_InstrAsm.__init__(self,'br'+cc+'_a0') | |
331 | self.cc = cc | |
332 | ||
333 | def run_exe_s(self,file): | |
334 | self.asm_function(file,'run_exe_'+self.name) | |
335 | self.mov(file,self.PC,'%g3') | |
336 | self.mov(file,self.NPC,self.PC) | |
337 | self.ld_rs1(file,'%g1') | |
338 | self.ld_imm(file,'%g2') | |
339 | self.add(file,self.PC,4,self.NPC) | |
340 | self.ld_irf(file,'%g1','%g1') | |
341 | self.opr(file,'sllx','%g2','2','%g2') | |
342 | self.add(file,'%g2','%g3','%g2') | |
343 | self.movr(file,self.cc,'%g1','%g2',self.NPC) | |
344 | self.retl_st_npc(file,self.NPC) | |
345 | self.asm_codesize(file,'run_exe_'+self.name) | |
346 | ||
347 | self.asm_function(file,'run_tct_'+self.name) | |
348 | self.ld_rs1(file,'%g1') | |
349 | self.ld_trap(file,'%g5') | |
350 | self.ld_irf(file,'%g1','%g1') | |
351 | self.add(file,self.NPC,4,'%g4') | |
352 | self.branch(file,'r'+self.cc,'%g1','1f') | |
353 | self.nop(file) | |
354 | self.mov(file,self.NPC,self.PC) | |
355 | self.retl(file) | |
356 | self.st_npc(file,'%g4') | |
357 | file.write('1:\n') | |
358 | self.jmpl(file,'%g5','%g0','%g0') | |
359 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
360 | self.asm_codesize(file,'run_tct_'+self.name) | |
361 | ||
362 | def gen_exe_tbl(self,file,mode): | |
363 | if mode == 'trc': | |
364 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
365 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
366 | elif mode == 'v8_run': | |
367 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
368 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
369 | else: | |
370 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
371 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
372 | ||
373 | def idx_exe_s(self,file): | |
374 | self.idx_exe_s_name(file,'exe_'+self.name) | |
375 | self.idx_exe_s_name(file,'tct_'+self.name) | |
376 | ||
377 | def run_exe_c(self,file): | |
378 | file.write('#if defined(ARCH_X64)\n') | |
379 | self.c_code_beg(file,'run_exe_') | |
380 | self.test_r(file,' ') | |
381 | file.write(' {\n') | |
382 | file.write(' int off = i->rs2;\n') | |
383 | file.write(' off <<= 2;\n') | |
384 | file.write(' uint64_t ea = pc + off;\n') | |
385 | file.write(' pc = npc;\n') | |
386 | file.write(' s->npc = ea;\n') | |
387 | file.write(' }\n') | |
388 | file.write(' else {\n') | |
389 | file.write(' pc = npc;\n') | |
390 | file.write(' s->npc = npc + 4;\n') | |
391 | file.write(' }\n') | |
392 | file.write(' return pc;\n') | |
393 | self.c_code_end(file) | |
394 | self.c_code_beg(file,'run_tct_') | |
395 | self.test_r(file,' ') | |
396 | file.write(' {\n') | |
397 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
398 | file.write(' }\n') | |
399 | file.write(' else {\n') | |
400 | file.write(' pc = npc;\n') | |
401 | file.write(' s->npc = npc + 4;\n') | |
402 | file.write(' }\n') | |
403 | file.write(' return pc;\n') | |
404 | self.c_code_end(file) | |
405 | file.write('#else\n') | |
406 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
407 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
408 | file.write('#endif\n') | |
409 | ||
410 | def run_dec_c(self,file): | |
411 | self.c_code_dec_beg(file,'run_dec_') | |
412 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
413 | self.ill_ibe(file) | |
414 | file.write(' if (s->pstate.tct())\n') | |
415 | self.dec_0r16(file,' ','idx_tct_'+self.name) | |
416 | file.write(' else\n') | |
417 | self.dec_0r16(file,' ','idx_exe_'+self.name) | |
418 | self.c_code_end(file) | |
419 | ||
420 | #============================================================================ | |
421 | # br_a1 | |
422 | #============================================================================ | |
423 | ||
424 | class SS_br_a1(SS_InstrAsm): | |
425 | def __init__(self,cc): | |
426 | SS_InstrAsm.__init__(self,'br'+cc+'_a1') | |
427 | self.cc = cc | |
428 | ||
429 | def run_exe_s(self,file): | |
430 | self.asm_function(file,'run_exe_'+self.name) | |
431 | self.mov(file,self.PC,'%g3') | |
432 | self.add(file,self.NPC,4,self.PC) | |
433 | self.ld_rs1(file,'%g1') | |
434 | self.ld_imm(file,'%g2') | |
435 | self.ld_irf(file,'%g1','%g1') | |
436 | self.movr(file,self.cc,'%g1',self.NPC,self.PC) | |
437 | self.add(file,self.NPC,8,self.NPC) | |
438 | self.opr(file,'sllx','%g2','2','%g2') | |
439 | self.add(file,'%g2','%g3','%g2') | |
440 | self.movr(file,self.cc,'%g1','%g2',self.NPC) | |
441 | self.retl_st_npc(file,self.NPC) | |
442 | self.asm_codesize(file,'run_exe_'+self.name) | |
443 | ||
444 | self.asm_function(file,'run_tct_'+self.name) | |
445 | self.ld_rs1(file,'%g1') | |
446 | self.ld_trap(file,'%g5') | |
447 | self.ld_irf(file,'%g1','%g1') | |
448 | self.add(file,self.NPC,8,'%g4') | |
449 | self.branch(file,'r'+self.cc,'%g1','1f') | |
450 | self.nop(file) | |
451 | self.add(file,self.NPC,4,self.PC) | |
452 | self.retl(file) | |
453 | self.st_npc(file,'%g4') | |
454 | file.write('1:\n') | |
455 | self.jmpl(file,'%g5','%g0','%g0') | |
456 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
457 | self.asm_codesize(file,'run_tct_'+self.name) | |
458 | ||
459 | def gen_exe_tbl(self,file,mode): | |
460 | if mode == 'trc': | |
461 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
462 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
463 | elif mode == 'v8_run': | |
464 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
465 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
466 | else: | |
467 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
468 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
469 | ||
470 | def idx_exe_s(self,file): | |
471 | self.idx_exe_s_name(file,'exe_'+self.name) | |
472 | self.idx_exe_s_name(file,'tct_'+self.name) | |
473 | ||
474 | def run_exe_c(self,file): | |
475 | file.write('#if defined(ARCH_X64)\n') | |
476 | self.c_code_beg(file,'run_exe_') | |
477 | self.test_r(file,' ') | |
478 | file.write(' {\n') | |
479 | file.write(' int off = i->rs2;\n') | |
480 | file.write(' off <<= 2;\n') | |
481 | file.write(' uint64_t ea = pc + off;\n') | |
482 | file.write(' pc = npc;\n') | |
483 | file.write(' s->npc = ea;\n') | |
484 | file.write(' }\n') | |
485 | file.write(' else {\n') | |
486 | file.write(' pc = npc + 4;\n') | |
487 | file.write(' s->npc = npc + 8;\n') | |
488 | file.write(' }\n') | |
489 | file.write(' return pc;\n') | |
490 | self.c_code_end(file) | |
491 | self.c_code_beg(file,'run_tct_') | |
492 | self.test_r(file,' ') | |
493 | file.write(' {\n') | |
494 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
495 | file.write(' }\n') | |
496 | file.write(' else {\n') | |
497 | file.write(' pc = npc + 4;\n') | |
498 | file.write(' s->npc = npc + 8;\n') | |
499 | file.write(' }\n') | |
500 | file.write(' return pc;\n') | |
501 | self.c_code_end(file) | |
502 | file.write('#else\n') | |
503 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
504 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
505 | file.write('#endif\n') | |
506 | ||
507 | def run_dec_c(self,file): | |
508 | self.c_code_dec_beg(file,'run_dec_') | |
509 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
510 | self.ill_ibe(file) | |
511 | file.write(' if (s->pstate.tct())\n') | |
512 | self.dec_0r16(file,' ','idx_tct_'+self.name) | |
513 | file.write(' else\n') | |
514 | self.dec_0r16(file,' ','idx_exe_'+self.name) | |
515 | self.c_code_end(file) | |
516 | ||
517 | #============================================================================ | |
518 | # fbp_a0 | |
519 | #============================================================================ | |
520 | ||
521 | class SS_fbp_a0(SS_InstrAsm): | |
522 | def __init__(self,cc,ccr): | |
523 | SS_InstrAsm.__init__(self,'fbp'+cc+'_'+ccr+'_a0') | |
524 | self.cc = cc | |
525 | self.ccr = ccr | |
526 | ||
527 | def run_exe_s(self,file): | |
528 | self.asm_function(file,'run_exe_'+self.name) | |
529 | if (self.cc == 'n'): | |
530 | self.ld_sim(file,'%g5') | |
531 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
532 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
533 | self.nop(file) | |
534 | self.mov(file,self.NPC,self.PC) | |
535 | self.add(file,self.NPC,4,self.NPC) | |
536 | self.retl_st_npc(file,self.NPC) | |
537 | elif (self.cc == 'a'): | |
538 | self.ld_sim(file,'%g5') | |
539 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
540 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
541 | self.nop(file) | |
542 | self.mov(file,self.NPC,self.PC) | |
543 | self.ld_ea_rd(file,self.NPC) | |
544 | self.retl_st_npc(file,self.NPC) | |
545 | else: | |
546 | self.ld_sim(file,'%g5') | |
547 | self.st_fsr_cpu(file,'%fsr') | |
548 | self.ld_ea_rd(file,'%g2') | |
549 | self.ld_fsr_run(file,'%fsr') | |
550 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
551 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr') | |
552 | self.nop(file) | |
553 | self.mov(file,self.NPC,self.PC) | |
554 | self.add(file,self.NPC,4,self.NPC) | |
555 | self.movcc(file,self.cc,'%'+self.ccr,'%g2',self.NPC) | |
556 | self.ld_fsr_cpu(file,'%fsr') | |
557 | self.retl_st_npc(file,self.NPC) | |
558 | self.asm_codesize(file,'run_exe_'+self.name) | |
559 | ||
560 | self.asm_function(file,'run_tct_'+self.name) | |
561 | if (self.cc == 'n'): | |
562 | self.ld_sim(file,'%g5') | |
563 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
564 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
565 | self.nop(file) | |
566 | self.mov(file,self.NPC,self.PC) | |
567 | self.add(file,self.NPC,4,self.NPC) | |
568 | self.retl_st_npc(file,self.NPC) | |
569 | elif (self.cc == 'a'): | |
570 | self.ld_sim(file,'%g5') | |
571 | self.ld_trap(file,'%g4') | |
572 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
573 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
574 | self.nop(file) | |
575 | self.jmpl(file,'%g4','%g0','%g0') | |
576 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
577 | else: | |
578 | self.ld_sim(file,'%g5') | |
579 | self.st_fsr_cpu(file,'%fsr') | |
580 | self.ld_trap(file,'%g4') | |
581 | self.ld_fsr_run(file,'%fsr') | |
582 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
583 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr') | |
584 | self.nop(file) | |
585 | self.branch(file,self.cc,'%'+self.ccr,'1f') | |
586 | self.nop(file) | |
587 | self.ld_fsr_cpu(file,'%fsr') | |
588 | self.mov(file,self.NPC,self.PC) | |
589 | self.add(file,self.NPC,4,self.NPC) | |
590 | self.retl_st_npc(file,self.NPC) | |
591 | file.write('1:\n') | |
592 | self.jmpl(file,'%g4','%g0','%g0') | |
593 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
594 | self.asm_codesize(file,'run_tct_'+self.name) | |
595 | ||
596 | ||
597 | def gen_exe_tbl(self,file,mode): | |
598 | if mode == 'trc': | |
599 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
600 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
601 | elif mode == 'v8_run': | |
602 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
603 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
604 | else: | |
605 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
606 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
607 | ||
608 | def idx_exe_s(self,file): | |
609 | self.idx_exe_s_name(file,'exe_'+self.name) | |
610 | self.idx_exe_s_name(file,'tct_'+self.name) | |
611 | ||
612 | def run_exe_c(self,file): | |
613 | file.write('#if defined(ARCH_X64)\n') | |
614 | self.c_code_beg(file,'run_exe_') | |
615 | file.write(' if (s->sim_state.fp_disabled())\n') | |
616 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
617 | file.write(' pc = npc;\n') | |
618 | self.test_fcc(file,' ') | |
619 | file.write(' s->npc = (SS_Vaddr&)i->rd;\n') | |
620 | file.write(' else\n') | |
621 | file.write(' s->npc = npc + 4;\n') | |
622 | file.write(' return pc;\n') | |
623 | self.c_code_end(file) | |
624 | self.c_code_beg(file,'run_tct_') | |
625 | file.write(' if (s->sim_state.fp_disabled())\n') | |
626 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
627 | self.test_fcc(file,' ') | |
628 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
629 | file.write(' else {\n') | |
630 | file.write(' pc = npc;\n') | |
631 | file.write(' s->npc = npc + 4;\n') | |
632 | file.write(' }\n') | |
633 | file.write(' return pc;\n') | |
634 | self.c_code_end(file) | |
635 | file.write('#else\n') | |
636 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
637 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
638 | file.write('#endif\n') | |
639 | ||
640 | def run_dec_c(self,file): | |
641 | self.c_code_dec_beg(file,'run_dec_') | |
642 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
643 | self.ill_ibe(file) | |
644 | file.write(' if (s->pstate.tct())\n') | |
645 | file.write(' idx = idx_tct_%s;\n' % self.name) | |
646 | file.write(' else\n') | |
647 | file.write(' idx = idx_exe_%s;\n' % self.name) | |
648 | file.write(' i->exe_tbl_idx = idx;\n') | |
649 | file.write(' i->exe = s->exe_table[idx];\n') | |
650 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n') | |
651 | self.c_code_dec_end(file) | |
652 | ||
653 | #============================================================================ | |
654 | # fbp_a1 | |
655 | #============================================================================ | |
656 | ||
657 | class SS_fbp_a1(SS_InstrAsm): | |
658 | def __init__(self,cc,ccr): | |
659 | SS_InstrAsm.__init__(self,'fbp'+cc+'_'+ccr+'_a1') | |
660 | self.cc = cc | |
661 | self.ccr = ccr | |
662 | ||
663 | def run_exe_s(self,file): | |
664 | self.asm_function(file,'run_exe_'+self.name) | |
665 | if (self.cc == 'n'): | |
666 | self.ld_sim(file,'%g5') | |
667 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
668 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
669 | self.nop(file) | |
670 | self.add(file,self.NPC,4,self.PC) | |
671 | self.add(file,self.NPC,8,self.NPC) | |
672 | self.retl_st_npc(file,self.NPC) | |
673 | elif (self.cc == 'a'): | |
674 | self.ld_sim(file,'%g5') | |
675 | self.ld_ea_rd(file,'%g2') | |
676 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
677 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
678 | self.nop(file) | |
679 | self.mov(file,'%g2',self.PC) | |
680 | self.add(file,'%g2',4,self.NPC) | |
681 | self.retl_st_npc(file,self.NPC) | |
682 | else: | |
683 | self.ld_sim(file,'%g5') | |
684 | self.st_fsr_cpu(file,'%fsr') | |
685 | self.ld_ea_rd(file,'%g2') | |
686 | self.ld_fsr_run(file,'%fsr') | |
687 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
688 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr') | |
689 | self.nop(file) | |
690 | self.add(file,self.NPC,4,self.PC) | |
691 | self.movcc(file,self.cc,'%'+self.ccr,self.NPC,self.PC) | |
692 | self.add(file,self.NPC,8,self.NPC) | |
693 | self.movcc(file,self.cc,'%'+self.ccr,'%g2',self.NPC) | |
694 | self.ld_fsr_cpu(file,'%fsr') | |
695 | self.retl_st_npc(file,self.NPC) | |
696 | self.asm_codesize(file,'run_exe_'+self.name) | |
697 | ||
698 | self.asm_function(file,'run_tct_'+self.name) | |
699 | if (self.cc == 'n'): | |
700 | self.ld_sim(file,'%g5') | |
701 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
702 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
703 | self.nop(file) | |
704 | self.add(file,self.NPC,4,self.PC) | |
705 | self.add(file,self.NPC,8,self.NPC) | |
706 | self.retl_st_npc(file,self.NPC) | |
707 | elif (self.cc == 'a'): | |
708 | self.ld_sim(file,'%g5') | |
709 | self.ld_trap(file,'%g4') | |
710 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
711 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
712 | self.nop(file) | |
713 | self.jmpl(file,'%g4','%g0','%g0') | |
714 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
715 | else: | |
716 | self.ld_sim(file,'%g5') | |
717 | self.st_fsr_cpu(file,'%fsr') | |
718 | self.ld_trap(file,'%g4') | |
719 | self.ld_fsr_run(file,'%fsr') | |
720 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
721 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr') | |
722 | self.nop(file) | |
723 | self.branch(file,self.cc,'%'+self.ccr,'1f') | |
724 | self.nop(file) | |
725 | self.ld_fsr_cpu(file,'%fsr') | |
726 | self.add(file,self.NPC,4,self.PC) | |
727 | self.add(file,self.NPC,8,self.NPC) | |
728 | self.retl_st_npc(file,self.NPC) | |
729 | file.write('1:\n') | |
730 | self.jmpl(file,'%g4','%g0','%g0') | |
731 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
732 | self.asm_codesize(file,'run_tct_'+self.name) | |
733 | ||
734 | ||
735 | def gen_exe_tbl(self,file,mode): | |
736 | if mode == 'trc': | |
737 | file.write(' trc_exe_passthrough, /* exe_'+self.name+' */\n') | |
738 | file.write(' trc_exe_passthrough, /* tct_'+self.name+' */\n') | |
739 | elif mode == 'v8_run': | |
740 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
741 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+' */\n') | |
742 | else: | |
743 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
744 | file.write(' %s_tct_%s,\n' % (mode,self.name)) | |
745 | ||
746 | def idx_exe_s(self,file): | |
747 | self.idx_exe_s_name(file,'exe_'+self.name) | |
748 | self.idx_exe_s_name(file,'tct_'+self.name) | |
749 | ||
750 | def run_exe_c(self,file): | |
751 | file.write('#if defined(ARCH_X64)\n') | |
752 | self.c_code_beg(file,'run_exe_') | |
753 | file.write(' if (s->sim_state.fp_disabled())\n') | |
754 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
755 | if (self.cc == 'a'): | |
756 | file.write(' SS_Vaddr target = (SS_Vaddr&)i->rd;\n') | |
757 | file.write(' pc = target;\n') | |
758 | file.write(' s->npc = target + 4;\n') | |
759 | else: | |
760 | self.test_fcc(file,' ') | |
761 | file.write(' {\n') | |
762 | file.write(' pc = npc;\n') | |
763 | file.write(' s->npc = (SS_Vaddr&)i->rd;\n') | |
764 | file.write(' }\n') | |
765 | file.write(' else {\n') | |
766 | file.write(' pc = npc + 4;\n') | |
767 | file.write(' s->npc = npc + 8;\n') | |
768 | file.write(' }\n') | |
769 | file.write(' return pc;\n') | |
770 | self.c_code_end(file) | |
771 | self.c_code_beg(file,'run_tct_') | |
772 | file.write(' if (s->sim_state.fp_disabled())\n') | |
773 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
774 | self.test_fcc(file,' ') | |
775 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
776 | file.write(' else {\n') | |
777 | file.write(' pc = npc + 4;\n') | |
778 | file.write(' s->npc = npc + 8;\n') | |
779 | file.write(' }\n') | |
780 | file.write(' return pc;\n') | |
781 | self.c_code_end(file) | |
782 | file.write('#else\n') | |
783 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
784 | file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self.name) | |
785 | file.write('#endif\n') | |
786 | ||
787 | def run_dec_c(self,file): | |
788 | self.c_code_dec_beg(file,'run_dec_') | |
789 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
790 | self.ill_ibe(file) | |
791 | file.write(' if (s->pstate.tct())\n') | |
792 | file.write(' idx = idx_tct_%s;\n' % self.name) | |
793 | file.write(' else\n') | |
794 | file.write(' idx = idx_exe_%s;\n' % self.name) | |
795 | file.write(' i->exe_tbl_idx = idx;\n') | |
796 | file.write(' i->exe = s->exe_table[idx];\n') | |
797 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n') | |
798 | self.c_code_dec_end(file) | |
799 | ||
800 | #============================================================================ | |
801 | # fbi_a0 | |
802 | #============================================================================ | |
803 | ||
804 | class SS_fbi_a0(SS_InstrAsm): | |
805 | def __init__(self,cc): | |
806 | SS_InstrAsm.__init__(self,'fbi'+cc+'_a0') | |
807 | self.cc = cc | |
808 | ||
809 | def idx_exe_s(self,file): | |
810 | pass | |
811 | ||
812 | def gen_exe_tbl(self,file,mode): | |
813 | pass | |
814 | ||
815 | def run_dec_c(self,file): | |
816 | self.c_code_dec_beg(file,'run_dec_') | |
817 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
818 | self.ill_ibe(file) | |
819 | file.write(' if (s->pstate.tct())\n') | |
820 | file.write(' idx = idx_tct_fbp%s_fcc0_a0;\n' % self.cc) | |
821 | file.write(' else\n') | |
822 | file.write(' idx = idx_exe_fbp%s_fcc0_a0;\n' % self.cc) | |
823 | file.write(' i->exe_tbl_idx = idx;\n') | |
824 | file.write(' i->exe = s->exe_table[idx];\n') | |
825 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n') | |
826 | self.c_code_dec_end(file) | |
827 | ||
828 | #============================================================================ | |
829 | # fbi_a1 | |
830 | #============================================================================ | |
831 | ||
832 | class SS_fbi_a1(SS_InstrAsm): | |
833 | def __init__(self,cc): | |
834 | SS_InstrAsm.__init__(self,'fbi'+cc+'_a1') | |
835 | self.cc = cc | |
836 | ||
837 | def idx_exe_s(self,file): | |
838 | pass | |
839 | ||
840 | def gen_exe_tbl(self,file,mode): | |
841 | pass | |
842 | ||
843 | def run_dec_c(self,file): | |
844 | self.c_code_dec_beg(file,'run_dec_') | |
845 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
846 | self.ill_ibe(file) | |
847 | file.write(' if (s->pstate.tct())\n') | |
848 | file.write(' idx = idx_tct_fbp%s_fcc0_a1;\n' % self.cc) | |
849 | file.write(' else\n') | |
850 | file.write(' idx = idx_exe_fbp%s_fcc0_a1;\n' % self.cc) | |
851 | file.write(' i->exe_tbl_idx = idx;\n') | |
852 | file.write(' i->exe = s->exe_table[idx];\n') | |
853 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n') | |
854 | self.c_code_dec_end(file) | |
855 | ||
856 | #============================================================================ | |
857 | # SS_call() | |
858 | #============================================================================ | |
859 | ||
860 | class SS_call(SS_InstrAsm): | |
861 | def __init__(self): | |
862 | SS_InstrAsm.__init__(self,'call') | |
863 | ||
864 | def run_exe_s(self,file): | |
865 | self.asm_function(file,'run_exe_'+self.name) | |
866 | self.ld_mask_pstate_am(file,'%g5') | |
867 | self.mov(file,self.PC,'%g4') | |
868 | self.mov(file,self.NPC,self.PC) | |
869 | self.ld_ea_rd(file,self.NPC) | |
870 | self.opr(file,'and','%g4','%g5','%g5') | |
871 | # ToDo do we need to sign extend the pc ... ironically that case should be a mem range trap | |
872 | if setup.va_bits != 64: | |
873 | self.opr(file,'sllx','%g5',str(64 - setup.va_bits),'%g5') | |
874 | self.opr(file,'srax','%g5',str(64 - setup.va_bits),'%g5') | |
875 | self.st_npc(file,self.NPC) | |
876 | self.retl(file) | |
877 | self.st_o7(file,'%g5') | |
878 | self.asm_codesize(file,'run_exe_'+self.name) | |
879 | ||
880 | def run_exe_c(self,file): | |
881 | file.write('#if defined(ARCH_X64)\n') | |
882 | self.c_code_beg(file,'run_exe_') | |
883 | file.write(' pc &= s->mask_pstate_am;\n') | |
884 | if setup.va_bits != 64: | |
885 | file.write(' pc = ((((int64_t)pc) << '+str(64-setup.va_bits)+') >> '+str(64-setup.va_bits)+');\n') | |
886 | file.write(' s->irf[15] = pc;\n') | |
887 | file.write(' s->npc = (SS_Vaddr&)i->rd;\n') | |
888 | file.write(' return npc;\n') | |
889 | self.c_code_end(file) | |
890 | file.write('#else\n') | |
891 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
892 | file.write('#endif\n\n') | |
893 | ||
894 | def run_dec_c(self,file): | |
895 | self.c_code_dec_beg(file,'run_dec_') | |
896 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
897 | self.ill_ibe(file) | |
898 | file.write(' if (s->pstate.tct())\n') | |
899 | file.write(' idx = idx_tct_bpa_icc_a0;\n') | |
900 | file.write(' else\n') | |
901 | file.write(' idx = idx_exe_%s;\n' % self.name) | |
902 | file.write(' i->exe_tbl_idx = idx;\n') | |
903 | file.write(' i->exe = s->exe_table[idx];\n') | |
904 | file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp30();\n') | |
905 | self.c_code_dec_end(file) | |
906 | ||
907 | def run_dec_p_count(self): | |
908 | return 64 | |
909 | ||
910 | def gen_exe_tbl(self,file,mode): | |
911 | if mode == 'v8_run': | |
912 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
913 | else: | |
914 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
915 | ||
916 | #============================================================================ | |
917 | # SS_illtrap() | |
918 | #=================================t=========================================== | |
919 | ||
920 | class SS_illtrap(SS_InstrCpp): | |
921 | def __init__(self): | |
922 | SS_InstrCpp.__init__(self,'illtrap') | |
923 | ||
924 | def run_exe_c(self,file): | |
925 | self.c_code_beg(file,'run_exe_') | |
926 | file.write(' assert(0);\n') | |
927 | file.write(' return -SS_Vaddr(1);\n') | |
928 | self.c_code_end(file) | |
929 | ||
930 | def run_dec_c(self,file): | |
931 | self.c_code_dec_beg(file,'run_dec_') | |
932 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
933 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
934 | self.c_code_dec_end(file) | |
935 | ||
936 | def run_dec_p_count(self): | |
937 | return 8 | |
938 | ||
939 | def gen_exe_tbl(self,file,mode): | |
940 | self.gen_exe_passthrough(file,mode) | |
941 | ||
942 | ||
943 | #============================================================================ | |
944 | # SS_jmpl(imm,out) | |
945 | # | |
946 | # ToDo: optimize common patters (retl) jmpl %o7+8,%g0, (call) jmpl %r,%o7 | |
947 | # and (tailcall) jmpl %r,%g0 | |
948 | #============================================================================ | |
949 | ||
950 | class SS_jmpl(SS_InstrAsm): | |
951 | def __init__(self): | |
952 | SS_InstrAsm.__init__(self,'jmpl') | |
953 | self.opc = 'jmpl' | |
954 | self.imm = ['i0' ,'i1'] | |
955 | self.out = ['rd' ,'g0'] | |
956 | ||
957 | def run_exe_c(self,file): | |
958 | for out in self.out: | |
959 | for imm in self.imm: | |
960 | file.write('#if defined(ARCH_X64)\n') | |
961 | self.c_code_beg_name(file,'run_exe_jmpl_'+imm+'_'+out) | |
962 | file.write(' uint64_t mask = s->mask_pstate_am;\n') | |
963 | if imm == 'i0': | |
964 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
965 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
966 | else: | |
967 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
968 | file.write(' int rs2 = i->rs2;\n'); | |
969 | ||
970 | # First check for aligned address | |
971 | ||
972 | file.write(' uint64_t target = rs1 + rs2;\n') | |
973 | file.write(' if (target & 0x3)\n') | |
974 | file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n') | |
975 | ||
976 | # Then check for address range if va_bits != 64 | |
977 | ||
978 | if setup.va_bits != 64: | |
979 | file.write(' uint64_t t1 = target & mask;\n') | |
980 | file.write(' uint64_t t = (((int64_t)t1) << '+str(64 - setup.va_bits)+') >> '+str(64 - setup.va_bits)+';\n') | |
981 | file.write(' if (t != t1)\n') | |
982 | file.write(' // Do not generate trap in HPRV or RED mode (IMMU bypass)\n') | |
983 | file.write(' if (s->sim_state.mode() < 2)\n') | |
984 | file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_RANGE);\n') | |
985 | ||
986 | if out == 'rd': | |
987 | file.write(' pc &= mask;\n') | |
988 | if setup.va_bits != 64: | |
989 | file.write(' pc = (((int64_t)pc) << '+str(64-setup.va_bits)+') >> '+str(64-setup.va_bits)+';\n') | |
990 | file.write(' s->get_irf(i->rd) = pc;\n') | |
991 | file.write(' s->npc = target;\n') | |
992 | file.write(' return npc;\n') | |
993 | self.c_code_end(file) | |
994 | file.write('#else\n') | |
995 | file.write('\nextern "C" SS_Vaddr run_exe_'+self.opc+'_'+imm+'_'+out+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n') | |
996 | file.write('#endif\n') | |
997 | for imm in self.imm: | |
998 | file.write('#if defined(ARCH_X64)\n') | |
999 | self.c_code_beg_name(file,'run_tct_jmpl_'+imm) | |
1000 | file.write(' uint64_t mask = s->mask_pstate_am;\n') | |
1001 | if imm == 'i0': | |
1002 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1003 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1004 | else: | |
1005 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1006 | file.write(' int rs2 = i->rs2;\n'); | |
1007 | ||
1008 | # First check for aligned address | |
1009 | ||
1010 | file.write(' uint64_t target = rs1 + rs2;\n') | |
1011 | file.write(' if (target & 0x3)\n') | |
1012 | file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n') | |
1013 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
1014 | self.c_code_end(file) | |
1015 | file.write('#else\n') | |
1016 | file.write('\nextern "C" SS_Vaddr run_tct_'+self.opc+'_'+imm+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n') | |
1017 | file.write('#endif\n') | |
1018 | ||
1019 | def run_exe_s(self,file): | |
1020 | for out in self.out: | |
1021 | for imm in self.imm: | |
1022 | self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
1023 | if imm == 'i0': | |
1024 | self.ld_rs1(file,'%g1') | |
1025 | self.ld_rs2(file,'%g2') | |
1026 | self.ld_mask_pstate_am(file,'%g4') | |
1027 | self.ld_irf(file,'%g1','%g1') | |
1028 | self.ld_irf(file,'%g2','%g2') | |
1029 | else: | |
1030 | self.ld_rs1(file,'%g1') | |
1031 | self.ld_imm(file,'%g2') | |
1032 | self.ld_mask_pstate_am(file,'%g4') | |
1033 | self.ld_irf(file,'%g1','%g1') | |
1034 | ||
1035 | if out == 'rd': | |
1036 | self.opr(file,'and',self.PC,'%g4','%g5') | |
1037 | self.ld_rd(file,'%g3') | |
1038 | if setup.va_bits != 64: | |
1039 | self.opr(file,'sllx','%g5',str(64 - setup.va_bits),'%g5') | |
1040 | self.opr(file,'srax','%g5',str(64 - setup.va_bits),'%g5') | |
1041 | ||
1042 | # First check for aligned address | |
1043 | # Then check for address range if va_bits != 64 | |
1044 | ||
1045 | self.add(file,'%g1','%g2','%g1') | |
1046 | self.opr(file,'andcc','%g1',3,'%g0') | |
1047 | ||
1048 | if setup.va_bits != 64: | |
1049 | self.opr(file,'and','%g1','%g4','%g4') | |
1050 | self.branch(file,'e','%icc','1f') | |
1051 | self.opr(file,'srax','%g4',str(setup.va_bits - 1),'%g4') | |
1052 | elif out == 'rd': | |
1053 | self.branch(file,'e,a','%icc','1f') | |
1054 | self.st_irf(file,'%g3','%g5') | |
1055 | else: | |
1056 | self.branch(file,'e,a','%icc','1f') | |
1057 | self.nop(file) | |
1058 | ||
1059 | self.ld_inst_trap(file,'%g2') | |
1060 | self.mov(file,'%g1','%o4') | |
1061 | self.jmpl(file,'%g2','%g0','%g0') | |
1062 | self.mov(file,'T_MEM_ADDRESS_NOT_ALIGNED','%o5') | |
1063 | ||
1064 | if setup.va_bits != 64: | |
1065 | file.write('1:\n') | |
1066 | self.add(file,'%g4','1','%g4') | |
1067 | self.ld_sim(file,'%g2') | |
1068 | self.opr(file,'subcc','%g4','1','%g0') | |
1069 | self.branch(file,'leu','%xcc','2f') | |
1070 | self.nop(file) | |
1071 | ||
1072 | # Don't generate the MEM_ADDRESS_RANGE trap in HPRV or RED mode (IMMU bypass) | |
1073 | ||
1074 | self.opr(file,'and','%g2','7','%g2') # priv() and red() -> sim_state.mode() | |
1075 | self.opr(file,'subcc','%g2','2','%g0') | |
1076 | self.branch(file,'ge,a','%xcc','2f') | |
1077 | self.nop(file) | |
1078 | ||
1079 | self.ld_inst_trap(file,'%g2') | |
1080 | self.mov(file,'%g1','%o4') | |
1081 | self.jmpl(file,'%g2','%g0','%g0') | |
1082 | self.mov(file,'T_MEM_ADDRESS_RANGE','%o5') | |
1083 | file.write('2:\n') | |
1084 | else: | |
1085 | file.write('1:\n') | |
1086 | ||
1087 | self.mov(file,self.NPC,self.PC) | |
1088 | if out == 'rd' and setup.va_bits != 64: | |
1089 | self.st_irf(file,'%g3','%g5') | |
1090 | self.mov(file,'%g1',self.NPC) | |
1091 | self.retl_st_npc(file,self.NPC) | |
1092 | ||
1093 | self.asm_codesize(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
1094 | ||
1095 | for imm in self.imm: | |
1096 | self.asm_function(file,'run_tct_'+self.opc+'_'+imm) | |
1097 | if imm == 'i0': | |
1098 | self.ld_rs1(file,'%g1') | |
1099 | self.ld_rs2(file,'%g2') | |
1100 | self.ld_irf(file,'%g1','%g1') | |
1101 | self.ld_irf(file,'%g2','%g2') | |
1102 | else: | |
1103 | self.ld_rs1(file,'%g1') | |
1104 | self.ld_imm(file,'%g2') | |
1105 | self.ld_irf(file,'%g1','%g1') | |
1106 | ||
1107 | self.add(file,'%g1','%g2','%g1') | |
1108 | self.opr(file,'andcc','%g1',3,'%g0') | |
1109 | self.branch(file,'e,a','%icc','1f') | |
1110 | self.ld_trap(file,'%g4') | |
1111 | ||
1112 | self.ld_inst_trap(file,'%g2') | |
1113 | self.mov(file,'%g1','%o4') | |
1114 | self.jmpl(file,'%g2','%g0','%g0') | |
1115 | self.mov(file,'T_MEM_ADDRESS_NOT_ALIGNED','%o5') | |
1116 | ||
1117 | file.write('1:\n') | |
1118 | ||
1119 | self.jmpl(file,'%g4','%g0','%g0') | |
1120 | self.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4') | |
1121 | ||
1122 | self.asm_codesize(file,'run_tct_'+self.opc+'_'+imm) | |
1123 | ||
1124 | ||
1125 | def run_dec_c(self,file): | |
1126 | self.c_code_dec_beg_name(file,'run_dec_jmpl') | |
1127 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1128 | file.write(' if (o.get_i())\n') | |
1129 | file.write(' {\n') | |
1130 | self.ill_ibe(file) | |
1131 | file.write(' if (s->pstate.tct())\n') | |
1132 | self.dec_0r13(file,' ','idx_tct_jmpl_i1') | |
1133 | file.write(' else\n') | |
1134 | file.write(' {\n') | |
1135 | file.write(' if (o.get_rd_irf())\n') | |
1136 | self.dec_rr13(file,' ','idx_exe_jmpl_i1_rd') | |
1137 | file.write(' else\n') | |
1138 | self.dec_0r13(file,' ','idx_exe_jmpl_i1_g0') | |
1139 | file.write(' }\n') | |
1140 | file.write(' }\n') | |
1141 | file.write(' else if (o.is_zero_12_5())\n') | |
1142 | file.write(' {\n') | |
1143 | self.ill_ibe(file) | |
1144 | file.write(' if (s->pstate.tct())\n') | |
1145 | self.dec_0rr(file,' ','idx_tct_jmpl_i0') | |
1146 | file.write(' else\n') | |
1147 | file.write(' {\n') | |
1148 | file.write(' if (o.get_rd_irf())\n') | |
1149 | self.dec_rrr(file,' ','idx_exe_jmpl_i0_rd') | |
1150 | file.write(' else\n') | |
1151 | self.dec_0rr(file,' ','idx_exe_jmpl_i0_g0') | |
1152 | file.write(' }\n') | |
1153 | file.write(' }\n') | |
1154 | file.write(' else\n') | |
1155 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1156 | self.c_code_end(file) | |
1157 | ||
1158 | def gen_exe_tbl(self,file,mode): | |
1159 | for out in self.out: | |
1160 | for imm in self.imm: | |
1161 | if mode == 'v8_run': | |
1162 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n') | |
1163 | else: | |
1164 | self.gen_exe_rrI(file,mode,imm,out) | |
1165 | for imm in self.imm: | |
1166 | if mode == 'trc': | |
1167 | self.gen_exe_rrI(file,mode,imm) | |
1168 | elif mode == 'v8_run': | |
1169 | file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self.name+'_'+imm+' */\n') | |
1170 | else: | |
1171 | file.write(' '+mode+'_tct_jmpl_'+imm+',\n') | |
1172 | ||
1173 | def idx_exe_s(self,file): | |
1174 | for out in self.out: | |
1175 | for imm in self.imm: | |
1176 | self.idx_exe_s_name(file,'exe_'+self.opc+'_'+imm+'_'+out) | |
1177 | for imm in self.imm: | |
1178 | self.idx_exe_s_name(file,'tct_'+self.opc+'_'+imm) | |
1179 | ||
1180 | def run_dec_p(self): | |
1181 | return 'run_dec_jmpl' | |
1182 | ||
1183 | ||
1184 | #============================================================================ | |
1185 | # SS_tcc(cc,imm) | |
1186 | # | |
1187 | # Note: tcc in usermode only allows for trapno: 0..127, checked in trap handle | |
1188 | # Note: control transfer traps for tcc behave the same as bpcc with no annul. | |
1189 | #============================================================================ | |
1190 | ||
1191 | class SS_tcc(SS_InstrAsm): | |
1192 | def __init__(self,cc,ccr,imm): | |
1193 | SS_InstrAsm.__init__(self,'t'+cc+'_'+ccr+'_'+imm) | |
1194 | self.opc = 't'+cc | |
1195 | self.cc = cc | |
1196 | self.ccr = ccr | |
1197 | self.imm = imm | |
1198 | ||
1199 | def run_exe_c(self,file): | |
1200 | file.write('#if defined(ARCH_X64)\n') | |
1201 | self.c_code_beg(file,'run_exe_') | |
1202 | self.test_icc(file,' ') | |
1203 | file.write(' {\n') | |
1204 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1205 | if (self.imm == 'i0'): | |
1206 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1207 | else: | |
1208 | file.write(' int rs2 = i->rs2;\n'); | |
1209 | file.write(' int trap = (rs1 + rs2) & 0xFF;\n') | |
1210 | file.write(' return (s->trap)(pc,npc,s,i,(SS_Trap::Type)(trap+0x100));\n') | |
1211 | file.write(' }\n') | |
1212 | file.write(' else {\n') | |
1213 | file.write(' pc = npc;\n') | |
1214 | file.write(' s->npc = npc + 4;\n') | |
1215 | file.write(' return pc;\n') | |
1216 | file.write(' }\n') | |
1217 | self.c_code_end(file) | |
1218 | file.write('#else\n') | |
1219 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1220 | file.write('#endif\n') | |
1221 | ||
1222 | def run_exe_s(self,file): | |
1223 | self.asm_function(file,'run_exe_'+self.name) | |
1224 | if (self.cc == 'n'): | |
1225 | self.mov(file,self.NPC,self.PC) | |
1226 | self.add(file,self.NPC,4,self.NPC) | |
1227 | self.retl_st_npc(file,self.NPC) | |
1228 | elif (self.cc == 'a'): | |
1229 | self.ld_rs1(file,'%g1') | |
1230 | self.ld_rs2(file,'%g2') | |
1231 | self.ld_irf(file,'%g1','%g1') | |
1232 | if (self.imm == 'i0'): | |
1233 | self.ld_irf(file,'%g2','%g2') | |
1234 | self.ld_trap(file,'%g5') | |
1235 | self.add(file,'%g1','%g2','%o4') | |
1236 | self.opr(file,'and','%o4',255,'%o4') | |
1237 | self.jmpl(file,'%g5','%g0','%g0') | |
1238 | self.add(file,'%o4',256,'%o4') | |
1239 | else: | |
1240 | self.ld_ccr(file,'%g3') | |
1241 | self.ld_rs1(file,'%g1') | |
1242 | self.ld_rs2(file,'%g2') | |
1243 | self.wr_ccr(file,'%g3') | |
1244 | self.ld_irf(file,'%g1','%g1') | |
1245 | if (self.imm == 'i0'): | |
1246 | self.ld_irf(file,'%g2','%g2') | |
1247 | self.ld_trap(file,'%g5') | |
1248 | self.branch(file,self.cc+',a','%'+self.ccr,'1f') | |
1249 | self.add(file,'%g1','%g2','%o4') | |
1250 | ||
1251 | self.mov(file,self.NPC,self.PC) | |
1252 | self.add(file,self.NPC,4,self.NPC) | |
1253 | self.retl_st_npc(file,self.NPC) | |
1254 | ||
1255 | file.write('1:\n') | |
1256 | ||
1257 | self.opr(file,'and','%o4',255,'%o4') | |
1258 | self.jmpl(file,'%g5','%g0','%g0') | |
1259 | self.add(file,'%o4',256,'%o4') | |
1260 | self.asm_codesize(file,'run_exe_'+self.name) | |
1261 | ||
1262 | def run_dec_c(self,file): | |
1263 | self.c_code_dec_beg(file,'run_dec_') | |
1264 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1265 | if self.imm == 'i1': | |
1266 | file.write(' if (o.is_zero_10_8())\n') | |
1267 | file.write(' {\n') | |
1268 | self.ill_ibe(file) | |
1269 | file.write(' if (s->pstate.tct())\n') | |
1270 | self.dec_0r8(file,' ','idx_tct_bp'+self.name[1:-2]+'a0') | |
1271 | file.write(' else\n') | |
1272 | self.dec_0r8(file,' ','idx_exe_'+self.name) | |
1273 | file.write(' }\n') | |
1274 | file.write(' else\n') | |
1275 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1276 | else: | |
1277 | file.write(' if (o.is_zero_10_5())\n') | |
1278 | file.write(' {\n') | |
1279 | self.ill_ibe(file) | |
1280 | file.write(' if (s->pstate.tct())\n') | |
1281 | self.dec_0rr(file,' ','idx_tct_bp'+self.name[1:-2]+'a0') | |
1282 | file.write(' else\n') | |
1283 | self.dec_0rr(file,' ','idx_exe_'+self.name) | |
1284 | file.write(' }\n') | |
1285 | file.write(' else\n') | |
1286 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1287 | self.c_code_end(file) | |
1288 | ||
1289 | def gen_exe_tbl(self,file,mode): | |
1290 | if mode == 'v8_run': | |
1291 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1292 | else: | |
1293 | self.gen_exe_0rI(file,mode) | |
1294 | ||
1295 | #============================================================================ | |
1296 | # SS_done() | |
1297 | #============================================================================ | |
1298 | ||
1299 | class SS_done(SS_InstrCpp): | |
1300 | def __init__(self): | |
1301 | SS_InstrCpp.__init__(self,'done') | |
1302 | ||
1303 | def run_exe_c(self,file): | |
1304 | self.c_code_beg(file,'run_exe_') | |
1305 | self.fail_chkpt(file) | |
1306 | file.write(' if (s->sim_state.priv() < SS_Strand::SS_PRIV)\n') | |
1307 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1308 | file.write(' else if (s->tl() == 0)\n') | |
1309 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1310 | file.write(' else if (s->pstate.tct())\n') | |
1311 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
1312 | file.write(' else\n') | |
1313 | file.write(' {\n') | |
1314 | file.write(' s->do_retry();\n') | |
1315 | file.write(' SS_Vaddr _npc = s->npc();\n') | |
1316 | file.write(' s->npc = _npc + 4;\n') | |
1317 | file.write(' return _npc;\n') | |
1318 | file.write(' }\n') | |
1319 | self.c_code_end(file) | |
1320 | ||
1321 | def run_dec_c(self,file): | |
1322 | self.c_code_dec_beg(file,'run_dec_') | |
1323 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1324 | file.write(' if (o.is_zero_18_0())\n') | |
1325 | file.write(' {\n') | |
1326 | self.ill_ibe(file) | |
1327 | self.dec_000(file,' ','idx_exe_'+self.name) | |
1328 | file.write(' }\n') | |
1329 | file.write(' else\n') | |
1330 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1331 | self.c_code_end(file) | |
1332 | ||
1333 | def gen_exe_tbl(self,file,mode): | |
1334 | self.gen_exe_passthrough(file,mode) | |
1335 | ||
1336 | ||
1337 | #============================================================================ | |
1338 | # SS_retry() | |
1339 | #============================================================================ | |
1340 | ||
1341 | class SS_retry(SS_InstrCpp): | |
1342 | def __init__(self): | |
1343 | SS_InstrCpp.__init__(self,'retry') | |
1344 | ||
1345 | def run_exe_c(self,file): | |
1346 | self.c_code_beg(file,'run_exe_') | |
1347 | self.fail_chkpt(file) | |
1348 | file.write(' if (s->sim_state.priv() < SS_Strand::SS_PRIV)\n') | |
1349 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1350 | file.write(' else if (s->tl() == 0)\n') | |
1351 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1352 | file.write(' else if (s->pstate.tct())\n') | |
1353 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
1354 | file.write(' else\n') | |
1355 | file.write(' {\n') | |
1356 | file.write(' s->do_retry();\n') | |
1357 | file.write(' return s->pc();\n') | |
1358 | file.write(' }\n') | |
1359 | self.c_code_end(file) | |
1360 | ||
1361 | def run_dec_c(self,file): | |
1362 | self.c_code_dec_beg(file,'run_dec_') | |
1363 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1364 | file.write(' if (o.is_zero_18_0())\n') | |
1365 | file.write(' {\n') | |
1366 | self.ill_ibe(file) | |
1367 | self.dec_000(file,' ','idx_exe_'+self.name) | |
1368 | file.write(' }\n') | |
1369 | file.write(' else\n') | |
1370 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1371 | self.c_code_end(file) | |
1372 | ||
1373 | def gen_exe_tbl(self,file,mode): | |
1374 | self.gen_exe_passthrough(file,mode) | |
1375 | ||
1376 | #============================================================================ | |
1377 | # SS_return() | |
1378 | #============================================================================ | |
1379 | ||
1380 | class SS_return(SS_InstrCpp): | |
1381 | def __init__(self): | |
1382 | SS_InstrCpp.__init__(self,'return') | |
1383 | self.opc = 'return' | |
1384 | self.imm = ['i0','i1'] | |
1385 | ||
1386 | def run_exe_c(self,file): | |
1387 | for imm in self.imm: | |
1388 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm) | |
1389 | self.fail_chkpt(file) | |
1390 | file.write('uint64_t r0,r1,r2,r3,r4,r5,r6,r7;') | |
1391 | file.write('uint64_t cwp = s->cwp();') | |
1392 | file.write('uint64_t canrestore = s->canrestore();') | |
1393 | file.write('r7 = s->irf[23];') | |
1394 | file.write('r6 = s->irf[22];') | |
1395 | file.write(' if (canrestore)\n') | |
1396 | file.write(' {\n') | |
1397 | if imm == 'i0': | |
1398 | file.write(' uint64_t ea = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n') | |
1399 | else: | |
1400 | file.write(' uint64_t ea = s->get_irf(i->rs1) + i->rs2;\n') | |
1401 | file.write(' if (ea & 3)\n') | |
1402 | file.write(' return (s->inst_trap)(pc,npc,s,i,ea,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n') | |
1403 | file.write(' else if (s->pstate.tct())\n') | |
1404 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n') | |
1405 | file.write(' s->cwp_save();\n') | |
1406 | file.write(' cwp = cwp ? (cwp - 1) : s->max_wp();\n') | |
1407 | file.write(' s->cansave = (s->cansave() < s->max_wp()) ? (s->cansave() + 1) : 0;\n') | |
1408 | file.write(' s->canrestore = canrestore ? (canrestore - 1) : s->max_wp();\n') | |
1409 | file.write(' s->cwp = cwp;\n') | |
1410 | file.write(' s->cwp_load();') | |
1411 | file.write(' s->npc = ea; return npc;\n') | |
1412 | file.write(' }\n') | |
1413 | file.write(' else if (s->otherwin())\n') | |
1414 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_other(s->wstate.other()));\n') | |
1415 | file.write(' else\n') | |
1416 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_normal(s->wstate.normal()));\n') | |
1417 | file.write('}\n\n') | |
1418 | ||
1419 | def run_dec_c(self,file): | |
1420 | self.c_code_dec_beg(file,'run_dec_') | |
1421 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1422 | file.write(' if (o.get_rd())\n') | |
1423 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1424 | file.write(' else if (o.get_i())\n') | |
1425 | file.write(' {\n') | |
1426 | self.ill_ibe(file) | |
1427 | self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1') | |
1428 | file.write(' }\n') | |
1429 | file.write(' else if (o.is_zero_12_5())\n') | |
1430 | file.write(' {\n') | |
1431 | self.ill_ibe(file) | |
1432 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0') | |
1433 | file.write(' }\n') | |
1434 | file.write(' else\n') | |
1435 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1436 | self.c_code_end(file) | |
1437 | ||
1438 | def gen_exe_tbl(self,file,mode): | |
1439 | if mode == 'v8_run': | |
1440 | mode = 'run' | |
1441 | for imm in self.imm: | |
1442 | self.gen_exe_0rI(file,mode,imm) | |
1443 | ||
1444 | ||
1445 | ||
1446 | #============================================================================ | |
1447 | #============================================================================ | |
1448 | ||
1449 | ss_bp_icc = SS_InstrGroup('00_00100x_bp_icc',25,0x1f,2) | |
1450 | ss_bp_c01 = SS_InstrGroup('00_001011',25,0x1f,2) | |
1451 | ss_bp_xcc = SS_InstrGroup('00_00110x_bp_xcc',25,0x1f,2) | |
1452 | ss_bp_c11 = SS_InstrGroup('00_00111x',25,0x1f,2) | |
1453 | ss_bi = SS_InstrGroup('00_010xxx_bi',25,0x1f,8) | |
1454 | ss_br = SS_InstrGroup('00_011xxx_br',25,0x1f,8) | |
1455 | ss_fbp_fcc0 = SS_InstrGroup('00_10100x_fbp_fcc0',25,0x1f,2) | |
1456 | ss_fbp_fcc1 = SS_InstrGroup('00_10101x_fbp_fcc1',25,0x1f,2) | |
1457 | ss_fbp_fcc2 = SS_InstrGroup('00_10110x_fbp_fcc2',25,0x1f,2) | |
1458 | ss_fbp_fcc3 = SS_InstrGroup('00_10111x_fbp_fcc3',25,0x1f,2) | |
1459 | ss_fbi = SS_InstrGroup('00_110xxx_fbi',25,0x1f,8) | |
1460 | ||
1461 | for cc,x in cond: | |
1462 | ss_bp_icc.append(SS_bp_a0(cc,'icc')) | |
1463 | ss_bp_c01.append(SS_ill()) | |
1464 | ss_bp_xcc.append(SS_bp_a0(cc,'xcc')) | |
1465 | ss_bp_c11.append(SS_ill()) | |
1466 | ss_bi.append(SS_bi_a0(cc)) | |
1467 | for cc,x in cond: | |
1468 | ss_bp_icc.append(SS_bp_a1(cc,'icc')) | |
1469 | if setup.product == 'N2': | |
1470 | ss_bp_c01.append(SS_ill()) | |
1471 | ss_bp_xcc.append(SS_bp_a1(cc,'xcc')) | |
1472 | ss_bp_c11.append(SS_ill()) | |
1473 | ss_bi.append(SS_bi_a1(cc)) | |
1474 | ||
1475 | for cc,x in rcond: | |
1476 | if (cc != ''): | |
1477 | ss_br.append(SS_br_a0(cc)) | |
1478 | else: | |
1479 | ss_br.append(SS_ill()) | |
1480 | for cc,x in rcond: | |
1481 | if (cc != ''): | |
1482 | ss_br.append(SS_br_a1(cc)) | |
1483 | else: | |
1484 | ss_br.append(SS_ill()) | |
1485 | ||
1486 | for cc,x in fcond: | |
1487 | ss_fbp_fcc0.append(SS_fbp_a0(cc,'fcc0')) | |
1488 | ss_fbp_fcc1.append(SS_fbp_a0(cc,'fcc1')) | |
1489 | ss_fbp_fcc2.append(SS_fbp_a0(cc,'fcc2')) | |
1490 | ss_fbp_fcc3.append(SS_fbp_a0(cc,'fcc3')) | |
1491 | ss_fbi.append(SS_fbi_a0(cc)) | |
1492 | for cc,x in fcond: | |
1493 | ss_fbp_fcc0.append(SS_fbp_a1(cc,'fcc0')) | |
1494 | ss_fbp_fcc1.append(SS_fbp_a1(cc,'fcc1')) | |
1495 | ss_fbp_fcc2.append(SS_fbp_a1(cc,'fcc2')) | |
1496 | ss_fbp_fcc3.append(SS_fbp_a1(cc,'fcc3')) | |
1497 | ss_fbi.append(SS_fbi_a1(cc)) | |
1498 | ||
1499 | # done/retry | |
1500 | ||
1501 | ss_done = SS_InstrGroup('10_111110_done',25,0x1f) | |
1502 | ss_done.append(SS_done()) | |
1503 | ss_done.append(SS_retry()) | |
1504 | for i in range(2,15): | |
1505 | ss_done.append(SS_ill()) | |
1506 | if setup.product == 'N2': | |
1507 | ss_done.append(SS_ill()) | |
1508 | for i in range(16,30): | |
1509 | ss_done.append(SS_ill()) | |
1510 | if setup.product == 'N2': | |
1511 | ss_done.append(SS_ill()) | |
1512 | ss_done.append(SS_ill()) | |
1513 | ||
1514 | # tcc | |
1515 | ||
1516 | ss_tcc = SS_InstrGroup('10_111010_tcc',25,0x1f) | |
1517 | for cc,x in cond: | |
1518 | ss_tcc_iccr = SS_InstrGroup('10_111010_tcc_'+cc,11,7) | |
1519 | ss_tcc_iccr.append(SS_tcc(cc,'icc','i0')) | |
1520 | ss_tcc_iccr.append(SS_ill()) | |
1521 | ss_tcc_iccr.append(SS_tcc(cc,'xcc','i0')) | |
1522 | ss_tcc_iccr.append(SS_ill()) | |
1523 | ss_tcc_iccr.append(SS_tcc(cc,'icc','i1')) | |
1524 | ss_tcc_iccr.append(SS_ill()) | |
1525 | ss_tcc_iccr.append(SS_tcc(cc,'xcc','i1')) | |
1526 | ss_tcc_iccr.append(SS_ill()) | |
1527 | ss_tcc.append(ss_tcc_iccr) | |
1528 | for cc,x in cond: | |
1529 | ss_tcc.append(SS_ill()) | |
1530 | ||
1531 |