Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: SS_InstrAlu.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_Alu.py implements most of the op=2 instructions. | |
23 | #============================================================================ | |
24 | ||
25 | from SS_Instr import * | |
26 | from SS_Setup import * | |
27 | ||
28 | setup = setups[sys.argv[1]] | |
29 | ||
30 | #============================================================================ | |
31 | # sethi/nop | |
32 | #============================================================================ | |
33 | ||
34 | class SS_nop(SS_InstrAsm): | |
35 | def __init__(self): | |
36 | SS_InstrAsm.__init__(self,'nop') | |
37 | ||
38 | def run_exe_s(self,file): | |
39 | self.s_code(file,'run_exe_') | |
40 | self.mov(file,self.NPC,self.PC) | |
41 | self.add(file,self.NPC,4,self.NPC) | |
42 | self.retl_st_npc(file,self.NPC) | |
43 | ||
44 | def run_exe_c(self,file): | |
45 | file.write('#if defined(ARCH_X64)\n') | |
46 | self.c_code_beg(file,'run_exe_') | |
47 | file.write(' pc = npc;\n') | |
48 | file.write(' s->npc = npc + 4;\n') | |
49 | file.write(' return pc;\n') | |
50 | self.c_code_end(file) | |
51 | file.write('#else\n') | |
52 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
53 | file.write('#endif\n\n') | |
54 | ||
55 | def run_dec_p(self): | |
56 | return '' | |
57 | ||
58 | def gen_exe_tbl(self,file,mode): | |
59 | if mode == 'v8_run': | |
60 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
61 | else: | |
62 | self.gen_exe_passthrough(file,mode) | |
63 | ||
64 | class SS_sethi(SS_InstrAsm): | |
65 | def __init__(self): | |
66 | SS_InstrAsm.__init__(self,'sethi') | |
67 | ||
68 | def run_exe_s(self,file): | |
69 | self.s_code(file,'run_exe_') | |
70 | self.mov(file,self.NPC,self.PC) | |
71 | self.add(file,self.NPC,4,self.NPC) | |
72 | self.ld_rd(file,'%g1') | |
73 | self.ld_rs2_32(file,'%g2') | |
74 | self.st_npc(file,self.NPC) | |
75 | self.retl(file) | |
76 | self.st_irf(file,'%g1','%g2') | |
77 | ||
78 | def run_exe_c(self,file): | |
79 | file.write('#if defined(ARCH_X64)\n') | |
80 | self.c_code_beg(file,'run_exe_') | |
81 | file.write(' pc = npc;\n') | |
82 | file.write(' s->npc = npc + 4;\n') | |
83 | file.write(' s->get_irf(i->rd) = *(uint32_t *)(&i->rs2);\n') | |
84 | file.write(' return pc;\n') | |
85 | self.c_code_end(file) | |
86 | file.write('#else\n') | |
87 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
88 | file.write('#endif\n\n') | |
89 | ||
90 | def run_dec_c(self,file): | |
91 | self.c_code_dec_beg(file,'run_dec_') | |
92 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
93 | self.ill_ibe(file) | |
94 | file.write(' if (o.get_rd())\n') | |
95 | self.dec_r022(file,' ','idx_exe_sethi') | |
96 | file.write(' else\n') | |
97 | self.dec_000(file,' ','idx_exe_nop') | |
98 | self.c_code_end(file) | |
99 | ||
100 | def run_dec_p_count(self): | |
101 | return 8 | |
102 | ||
103 | def gen_exe_tbl(self,file,mode): | |
104 | if mode == 'trc': | |
105 | file.write(' trc_exe_r00, /* '+self.name+' */\n') | |
106 | elif mode == 'v8_run': | |
107 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
108 | else: | |
109 | SS_InstrAsm.gen_exe_tbl(self,file,mode) | |
110 | ||
111 | ||
112 | #============================================================================ | |
113 | # SS_alu(opc) | |
114 | #============================================================================ | |
115 | ||
116 | class SS_alu(SS_InstrAsm): | |
117 | def __init__(self,opc): | |
118 | SS_InstrAsm.__init__(self,opc) | |
119 | self.opc = opc | |
120 | self.imm = ['i0' ,'i1'] | |
121 | self.out = ['rd' ,'g0'] | |
122 | ||
123 | def run_exe_c(self,file): | |
124 | for out in self.out: | |
125 | for imm in self.imm: | |
126 | file.write('#if defined(ARCH_X64)\n') | |
127 | self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
128 | file.write(' int64_t rs1 = s->get_irf(i->rs1);\n') | |
129 | if (imm == 'i0'): | |
130 | file.write(' int64_t rs2 = s->get_irf(i->rs2);\n') | |
131 | else: | |
132 | file.write(' int64_t rs2 = i->rs2;\n'); | |
133 | if (self.opc == 'add'): | |
134 | file.write(' int64_t rd = rs1 + rs2;\n') | |
135 | elif (self.opc == 'and'): | |
136 | file.write(' int64_t rd = rs1 & rs2;\n') | |
137 | elif (self.opc == 'or'): | |
138 | file.write(' int64_t rd = rs1 | rs2;\n') | |
139 | elif (self.opc == 'xor'): | |
140 | file.write(' int64_t rd = rs1 ^ rs2;\n') | |
141 | elif (self.opc == 'sub'): | |
142 | file.write(' int64_t rd = rs1 - rs2;\n') | |
143 | elif (self.opc == 'andn'): | |
144 | file.write(' int64_t rd = rs1 & (~rs2);\n') | |
145 | elif (self.opc == 'orn'): | |
146 | file.write(' int64_t rd = rs1 | (~rs2);\n') | |
147 | elif (self.opc == 'xnor'): | |
148 | file.write(' int64_t rd = ~(rs1 ^ rs2);\n') | |
149 | elif (self.opc == 'addc'): | |
150 | file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n') | |
151 | elif (self.opc == 'mulx'): | |
152 | file.write(' int64_t rd = rs1 * rs2;\n') | |
153 | elif (self.opc == 'sdivx'): | |
154 | file.write(' if (rs2 == 0)\n') | |
155 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n') | |
156 | file.write(' int64_t rd = rs1 / rs2;\n') | |
157 | elif (self.opc in ['umul','umulcc','smul','smulcc']): | |
158 | if (self.opc in ['umul','umulcc']): | |
159 | file.write(' uint32_t t1 = rs1;\n') | |
160 | file.write(' uint32_t t2 = rs2;\n') | |
161 | file.write(' uint64_t rd = (uint64_t)t1 * (uint64_t)t2;\n') | |
162 | else: | |
163 | file.write(' int32_t t1 = rs1;\n') | |
164 | file.write(' int32_t t2 = rs2;\n') | |
165 | file.write(' int64_t rd = (int64_t)t1 * (int64_t)t2;\n') | |
166 | file.write(' s->y.set((uint32_t)(rd >> 32));\n') | |
167 | if (self.opc in ['umulcc','smulcc']): | |
168 | file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n') | |
169 | file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n') | |
170 | file.write(' if (rd == 0)\n') | |
171 | file.write(' xcc |= 0x4;\n') | |
172 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
173 | file.write(' icc |= 0x4;\n') | |
174 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
175 | elif (self.opc == 'subc'): | |
176 | file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n') | |
177 | elif (self.opc == 'udivx'): | |
178 | file.write(' uint64_t t1 = *(uint64_t *)&rs1;\n') | |
179 | file.write(' uint64_t t2 = *(uint64_t *)&rs2;\n') | |
180 | file.write(' if (t2 == 0)\n') | |
181 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n') | |
182 | file.write(' uint64_t rd = t1 / t2;\n') | |
183 | elif (self.opc in ['udiv','udivcc','sdiv','sdivcc']): | |
184 | if (self.opc in ['udiv','udivcc']): | |
185 | file.write(' uint32_t t1 = rs1;\n') | |
186 | file.write(' uint32_t t2 = rs2;\n') | |
187 | file.write(' uint64_t t3 = s->y();\n') | |
188 | file.write(' t3 = (t3 << 32) + t1;\n') | |
189 | file.write(' if (t2 == 0)\n') | |
190 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n') | |
191 | file.write(' uint64_t rd = t3 / t2;\n') | |
192 | file.write(' int overflow = 0;\n') | |
193 | file.write(' if (rd > 0xffffffffllu) {\n') | |
194 | file.write(' rd = 0xffffffffllu;\n') | |
195 | file.write(' overflow = 1;\n') | |
196 | file.write(' }\n') | |
197 | elif (self.opc in ['sdiv','sdivcc']): | |
198 | file.write(' uint32_t t1 = rs1;\n') | |
199 | file.write(' uint32_t t2 = rs2;\n') | |
200 | file.write(' int64_t t3 = ((uint64_t)s->y() << 32) + t1;\n') | |
201 | file.write(' int64_t rd;\n') | |
202 | file.write(' if (t2 == 0)\n') | |
203 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n') | |
204 | file.write(' int overflow = 0;\n') | |
205 | file.write(' if ((t3 == 0x8000000000000000ULL) && (t2 == 0xffffffffUL)) {\n') | |
206 | file.write(' rd = 0x7fffffffLL;\n') | |
207 | file.write(' overflow = 1;\n') | |
208 | file.write(' }\n') | |
209 | file.write(' else\n') | |
210 | file.write(' rd = t3 / (int32_t)t2;\n') | |
211 | file.write(' if ((rd > 0LL) && (rd > 0x7fffffffLL)) {\n') | |
212 | file.write(' rd = 0x7fffffffLL;\n') | |
213 | file.write(' overflow = 1;\n') | |
214 | file.write(' }\n') | |
215 | file.write(' else if ((rd < 0LL) && (rd < 0xffffffff80000000LL)) {\n') | |
216 | file.write(' rd = 0xffffffff80000000LL;\n') | |
217 | file.write(' overflow = 1;\n') | |
218 | file.write(' }\n') | |
219 | if (self.opc in ['udivcc','sdivcc']): | |
220 | file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n') | |
221 | file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n') | |
222 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
223 | file.write(' icc |= 0x4;\n') | |
224 | file.write(' if (rd == 0)\n') | |
225 | file.write(' xcc |= 0x4;\n') | |
226 | file.write(' if (overflow)\n') | |
227 | file.write(' icc |= 0x2;\n') | |
228 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
229 | elif (self.opc in ['addcc','addccc','subcc','subccc']): | |
230 | if (self.opc == 'addcc'): | |
231 | file.write(' int64_t rd = rs1 + rs2;\n') | |
232 | elif (self.opc == 'addccc'): | |
233 | file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n') | |
234 | elif (self.opc == 'subcc'): | |
235 | file.write(' int64_t rd = rs1 - rs2;\n') | |
236 | else: | |
237 | file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n') | |
238 | if (self.opc in ['addcc','addccc']): | |
239 | file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n') | |
240 | file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n') | |
241 | else: | |
242 | file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n') | |
243 | file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n') | |
244 | file.write(' uint32_t icc = ((v >> 31) & 0x1) << 1;\n') | |
245 | file.write(' uint32_t xcc = ((v >> 63) & 0x1) << 1;\n') | |
246 | file.write(' icc |= ((c >> 31) & 0x1);\n') | |
247 | file.write(' xcc |= ((c >> 63) & 0x1);\n') | |
248 | file.write(' icc |= ((rd >> 31) & 0x1) << 3;\n') | |
249 | file.write(' xcc |= ((rd >> 63) & 0x1) << 3;\n') | |
250 | file.write(' if (rd == 0)\n') | |
251 | file.write(' xcc |= 0x4;\n') | |
252 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
253 | file.write(' icc |= 0x4;\n') | |
254 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
255 | elif (self.opc in ['andcc','orcc','xorcc','andncc','orncc','xnorcc']): | |
256 | if (self.opc == 'andcc'): | |
257 | file.write(' int64_t rd = rs1 & rs2;\n') | |
258 | elif (self.opc == 'orcc'): | |
259 | file.write(' int64_t rd = rs1 | rs2;\n') | |
260 | elif (self.opc == 'xorcc'): | |
261 | file.write(' int64_t rd = rs1 ^ rs2;\n') | |
262 | elif (self.opc == 'andncc'): | |
263 | file.write(' int64_t rd = rs1 & (~rs2);\n') | |
264 | elif (self.opc == 'orncc'): | |
265 | file.write(' int64_t rd = rs1 | (~rs2);\n') | |
266 | elif (self.opc == 'xnorcc'): | |
267 | file.write(' int64_t rd = ~(rs1 ^ rs2);\n') | |
268 | file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n') | |
269 | file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n') | |
270 | file.write(' if (rd == 0)\n') | |
271 | file.write(' xcc |= 0x4;\n') | |
272 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
273 | file.write(' icc |= 0x4;\n') | |
274 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
275 | elif (self.opc == 'mulscc'): | |
276 | file.write(' /* step 1 */\n') | |
277 | file.write(' uint64_t t1 = rs2 & 0xFFFFFFFFLLU;\n') | |
278 | file.write(' /* step 2 */\n') | |
279 | file.write(' uint32_t icc = s->ccr.icc();\n') | |
280 | file.write(' uint32_t t0 = ((icc >> 3) ^ ((icc >> 1) & 1)) << 31;\n') | |
281 | file.write(' uint64_t t2 = rs1 & 0xFFFFFFFFLLU;\n') | |
282 | file.write(' t2 = (t2 >> 1) | t0;\n') | |
283 | file.write(' /* step 3 */\n') | |
284 | file.write(' uint32_t y = s->y();\n') | |
285 | file.write(' uint64_t t3a = (y & 1) ? t1 : 0;\n') | |
286 | file.write(' uint64_t rd = t2 + t3a;\n') | |
287 | file.write(' /* step 5 */\n') | |
288 | file.write(' s->y.set((y >> 1) | ((rs1 & 0x1) << 31));\n') | |
289 | file.write(' /* step 4 */\n') | |
290 | file.write(' uint32_t bit31_rs1 = (t2 >> 31) & 0x1;\n') | |
291 | file.write(' uint32_t bit31_rs2 = (t3a >> 31) & 0x1;\n') | |
292 | file.write(' uint32_t bit31_rd = (rd >> 31) & 0x1;\n') | |
293 | file.write(' icc = bit31_rd << 3;\n') | |
294 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
295 | file.write(' icc |= 0x4;\n') | |
296 | file.write(' if ((bit31_rs1 & bit31_rs2 & ~bit31_rd) ||\n') | |
297 | file.write(' (~bit31_rs1 & ~bit31_rs2 & bit31_rd))\n') | |
298 | file.write(' icc |= 0x2;\n') | |
299 | file.write(' if ((bit31_rs1 & bit31_rs2) ||\n') | |
300 | file.write(' (~bit31_rd & (bit31_rs1 | bit31_rs2)))\n') | |
301 | file.write(' icc |= 0x1;\n') | |
302 | file.write(' uint32_t xcc = (rd == 0) ? 0x4 : 0;\n') | |
303 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
304 | if (out == 'rd'): | |
305 | file.write(' s->get_irf(i->rd) = rd;\n') | |
306 | file.write(' pc = npc;\n') | |
307 | file.write(' s->npc = npc + 4;\n') | |
308 | file.write(' return pc;\n') | |
309 | self.c_code_end(file) | |
310 | file.write('#else\n') | |
311 | 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') | |
312 | file.write('#endif\n\n') | |
313 | ||
314 | def run_exe_s(self,file): | |
315 | for out in self.out: | |
316 | for imm in self.imm: | |
317 | self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
318 | if self.is_usdiv(): | |
319 | self.ld_y(file,'%g4') | |
320 | self.ld_rs1(file,'%g1') | |
321 | if imm == 'i0': | |
322 | self.ld_rs2(file,'%g2') | |
323 | else: | |
324 | self.ld_imm(file,'%g2') | |
325 | self.wr_y(file,'%g4') | |
326 | elif self.is_addci(): | |
327 | self.ld_ccr(file,'%g4') | |
328 | self.ld_rs1(file,'%g1') | |
329 | if imm == 'i0': | |
330 | self.ld_rs2(file,'%g2') | |
331 | else: | |
332 | self.ld_imm(file,'%g2') | |
333 | self.wr_ccr(file,'%g4') | |
334 | elif self.is_mulscc(): | |
335 | self.ld_y(file,'%g4') | |
336 | self.ld_rs1(file,'%g1') | |
337 | if imm == 'i0': | |
338 | self.ld_rs2(file,'%g2') | |
339 | else: | |
340 | self.ld_imm(file,'%g2') | |
341 | self.wr_y(file,'%g4') | |
342 | self.ld_ccr(file,'%g4') | |
343 | else: | |
344 | self.ld_rs1(file,'%g1') | |
345 | if imm == 'i0': | |
346 | self.ld_rs2(file,'%g2') | |
347 | else: | |
348 | self.ld_imm(file,'%g2') | |
349 | ||
350 | if not self.is_div(): | |
351 | self.mov(file,self.NPC,self.PC) | |
352 | self.add(file,self.NPC,4,self.NPC) | |
353 | ||
354 | self.ld_irf(file,'%g1','%g1') | |
355 | if imm == 'i0': | |
356 | self.ld_irf(file,'%g2','%g2') | |
357 | ||
358 | if self.is_mulscc(): | |
359 | self.wr_ccr(file,'%g4') | |
360 | ||
361 | if not self.is_div(): | |
362 | self.st_npc(file,self.NPC) | |
363 | ||
364 | if out == 'rd': | |
365 | self.ld_rd(file,'%g3') | |
366 | ||
367 | if self.is_div(): | |
368 | if self.is_usdiv(): | |
369 | self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32] | |
370 | self.branch(file,'rz','%g2','1f') | |
371 | self.nop(file) | |
372 | self.mov(file,self.NPC,self.PC) | |
373 | self.add(file,self.NPC,4,self.NPC) | |
374 | self.st_npc(file,self.NPC) | |
375 | ||
376 | self.opr(file,self.opc,'%g1','%g2','%g1') | |
377 | if self.is_cc(): | |
378 | self.rd_ccr(file,'%g4') | |
379 | ||
380 | if ((setup.product in ['N2']) and self.is_mulscc()): | |
381 | self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32] | |
382 | self.opr(file,'and','%g4','1','%g2') # get icc.c | |
383 | self.opr(file,'sllx','%g2','32','%g2') # | |
384 | self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c | |
385 | self.opr(file,'and','%g4','0xf','%g4') # get icc of rd | |
386 | self.rd_ccr(file,'%g2') | |
387 | self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd | |
388 | self.opr(file,'or','%g4','%g2','%g4') # the combined ccr | |
389 | ||
390 | self.st_irf(file,'%g3','%g1') | |
391 | if self.is_usmul() or self.is_mulscc(): | |
392 | self.rd_y(file,'%g5') | |
393 | self.st_y(file,'%g5') | |
394 | self.retl(file) | |
395 | self.st_ccr(file,'%g4') | |
396 | elif self.is_usmul(): | |
397 | self.rd_y(file,'%g5') | |
398 | self.st_irf(file,'%g3','%g1') | |
399 | self.retl(file) | |
400 | self.st_y(file,'%g5') | |
401 | else: | |
402 | self.retl(file) | |
403 | self.st_irf(file,'%g3','%g1') | |
404 | ||
405 | elif self.is_cc(): # rd == %g0 | |
406 | if self.is_div(): | |
407 | if self.is_usdiv(): | |
408 | self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32] | |
409 | self.branch(file,'rz','%g2','1f') | |
410 | self.nop(file) | |
411 | self.mov(file,self.NPC,self.PC) | |
412 | self.add(file,self.NPC,4,self.NPC) | |
413 | self.st_npc(file,self.NPC) | |
414 | ||
415 | self.opr(file,self.opc,'%g1','%g2','%g1') | |
416 | self.rd_ccr(file,'%g4') | |
417 | ||
418 | if ((setup.product in ['N2']) and self.is_mulscc()): | |
419 | self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32] | |
420 | self.opr(file,'and','%g4','1','%g2') # get icc.c | |
421 | self.opr(file,'sllx','%g2','32','%g2') # | |
422 | self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c | |
423 | self.opr(file,'and','%g4','0xf','%g4') # get icc of rd | |
424 | self.rd_ccr(file,'%g2') | |
425 | self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd | |
426 | self.opr(file,'or','%g4','%g2','%g4') # the combined ccr | |
427 | ||
428 | if self.is_usmul() or self.is_mulscc(): | |
429 | self.rd_y(file,'%g5') | |
430 | self.st_y(file,'%g5') | |
431 | self.retl(file) | |
432 | self.st_ccr(file,'%g4') | |
433 | ||
434 | elif self.is_usmul(): | |
435 | self.opr(file,self.opc,'%g1','%g2','%g0') | |
436 | self.rd_y(file,'%g5') | |
437 | self.retl(file) | |
438 | self.st_y(file,'%g5') | |
439 | ||
440 | else: | |
441 | if self.is_div(): | |
442 | if self.is_usdiv(): | |
443 | self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32] | |
444 | self.branch(file,'rz','%g2','1f') | |
445 | self.nop(file) | |
446 | self.mov(file,self.NPC,self.PC) | |
447 | self.add(file,self.NPC,4,self.NPC) | |
448 | self.st_npc(file,self.NPC) | |
449 | ||
450 | self.retl(file) | |
451 | self.opr(file,self.opc,'%g1','%g2','%g0') | |
452 | ||
453 | if self.is_div(): | |
454 | file.write('1:\n') | |
455 | self.ld_trap(file,'%o5') | |
456 | self.jmpl(file,'%o5','%g0','%g0') | |
457 | self.mov(file,'T_DIVISION_BY_ZERO','%o4') | |
458 | ||
459 | self.asm_codesize(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
460 | ||
461 | def run_dec_c(self,file): | |
462 | self.c_code_dec_beg_name(file,'run_dec_'+self.opc) | |
463 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
464 | file.write(' if (o.get_i())\n') | |
465 | file.write(' {\n') | |
466 | self.ill_ibe(file) | |
467 | file.write(' if (o.get_rd_irf())\n') | |
468 | self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i0_rd + 1') # i1_rd | |
469 | file.write(' else\n') | |
470 | self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i0_rd + 3') # i1_g0 | |
471 | file.write(' }\n') | |
472 | file.write(' else if (o.is_zero_12_5())\n') | |
473 | file.write(' {\n') | |
474 | self.ill_ibe(file) | |
475 | file.write(' if (o.get_rd_irf())\n') | |
476 | self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd') | |
477 | file.write(' else\n') | |
478 | self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_rd + 2') # i0_g0 | |
479 | file.write(' }\n') | |
480 | file.write(' else\n') | |
481 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
482 | self.c_code_end(file) | |
483 | ||
484 | def exe_idx_s(self,file): | |
485 | for out in self.out: | |
486 | for imm in self.imm: | |
487 | self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out) | |
488 | ||
489 | def gen_exe_tbl(self,file,mode): | |
490 | for out in self.out: | |
491 | for imm in self.imm: | |
492 | if mode == 'v8_run': | |
493 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n') | |
494 | else: | |
495 | self.gen_exe_rrI(file,mode,imm,out) | |
496 | ||
497 | def run_dec_p(self): | |
498 | return 'run_dec_%s' % self.opc | |
499 | ||
500 | def is_mulscc(self): | |
501 | return self.opc == 'mulscc' | |
502 | def is_usmul(self): | |
503 | return (self.opc == 'umul') or (self.opc == 'smul') or (self.opc == 'umulcc') or (self.opc == 'smulcc') | |
504 | def is_div(self): | |
505 | return self.is_usdiv() or (self.opc == 'udivx') or (self.opc == 'sdivx') | |
506 | def is_usdiv(self): | |
507 | return (self.opc == 'udiv') or (self.opc == 'sdiv') or (self.opc == 'udivcc') or (self.opc == 'sdivcc') | |
508 | def is_addci(self): | |
509 | return (self.opc == 'addc') or (self.opc == 'subc') or (self.opc == 'addccc') or (self.opc == 'subccc') | |
510 | def is_cc(self): | |
511 | return (self.opc[-2:] == 'cc') | |
512 | ||
513 | #============================================================================ | |
514 | # SS_sft(opc,imm,out) | |
515 | # | |
516 | # ToDo: opc to %g0 that don't set %ccr or %y are nop | |
517 | # ToDo: (mov) or %g0,src,dst is a frequent used instruction | |
518 | # ToDo: (cmp) subcc src,src,%g0 is a frequent used instruction | |
519 | # ToDo: These are excelent candidates for some dynamic translation (33% faster) | |
520 | #============================================================================ | |
521 | ||
522 | class SS_sft(SS_InstrAsm): | |
523 | def __init__(self,opc,imm): | |
524 | SS_InstrAsm.__init__(self,opc+'_'+imm) | |
525 | self.opc = opc | |
526 | self.imm = imm | |
527 | ||
528 | def gen_exe_tbl(self,file,mode): | |
529 | if mode == 'v8_run': | |
530 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
531 | else: | |
532 | self.gen_exe_rrI(file,mode) | |
533 | ||
534 | def run_exe_c(self,file): | |
535 | file.write('#if defined(ARCH_X64)') | |
536 | self.c_code_beg(file,'run_exe_') | |
537 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
538 | if (self.imm == 'i0'): | |
539 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
540 | else: | |
541 | file.write(' uint64_t rs2 = i->rs2;\n'); | |
542 | if (self.opc in ['sll','srl','sra']): | |
543 | file.write(' uint32_t shcnt = rs2 & 0x1f;\n') | |
544 | if (self.opc == 'sll'): | |
545 | file.write(' uint64_t rd = rs1 << shcnt;\n') | |
546 | elif (self.opc == 'srl'): | |
547 | file.write(' uint64_t rd = (rs1 & 0xffffffff) >> shcnt;\n') | |
548 | else: | |
549 | file.write(' int32_t t1 = rs1;\n') | |
550 | file.write(' uint64_t rd = t1 >> shcnt;\n') | |
551 | else: | |
552 | file.write(' uint32_t shcnt = rs2 & 0x3f;\n') | |
553 | if (self.opc == 'sllx'): | |
554 | file.write(' uint64_t rd = rs1 << shcnt;\n') | |
555 | elif (self.opc == 'srlx'): | |
556 | file.write(' uint64_t rd = rs1 >> shcnt;\n') | |
557 | else: | |
558 | file.write(' uint64_t rd = ((int64_t)rs1) >> shcnt;\n') | |
559 | file.write(' s->get_irf(i->rd) = rd;\n') | |
560 | file.write(' pc = npc;\n') | |
561 | file.write(' s->npc = npc + 4;\n') | |
562 | file.write(' return pc;\n') | |
563 | self.c_code_end(file) | |
564 | file.write('#else\n') | |
565 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
566 | file.write('#endif\n\n') | |
567 | ||
568 | def run_exe_s(self,file): | |
569 | self.s_code(file,'run_exe_') | |
570 | self.ld_rs1(file,'%g1') | |
571 | if (self.imm == 'i0'): | |
572 | self.ld_rs2(file,'%g2') | |
573 | else: | |
574 | self.ld_imm(file,'%g2') | |
575 | self.mov(file,self.NPC,self.PC) | |
576 | self.ld_irf(file,'%g1','%g1') | |
577 | if (self.imm == 'i0'): | |
578 | self.ld_irf(file,'%g2','%g2') | |
579 | self.ld_rd(file,'%g3') | |
580 | self.add(file,self.NPC,4,self.NPC) | |
581 | self.opr(file,self.opc,'%g1','%g2','%g1') | |
582 | self.st_npc(file,self.NPC) | |
583 | self.retl(file) | |
584 | self.st_irf(file,'%g3','%g1') | |
585 | ||
586 | def run_dec_c(self,file): | |
587 | self.c_code_dec_beg(file,'run_dec_') | |
588 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
589 | if self.imm == 'i0': | |
590 | file.write(' if (o.is_zero_11_5())\n') | |
591 | file.write(' {\n') | |
592 | self.ill_ibe(file) | |
593 | file.write(' if (o.get_rd_irf())\n') | |
594 | self.dec_rrr(file,' ','idx_exe_'+self.name) | |
595 | file.write(' else\n') | |
596 | self.dec_000(file,' ','idx_exe_nop') | |
597 | file.write(' }\n') | |
598 | file.write(' else\n') | |
599 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
600 | else: | |
601 | if self.is_x(): | |
602 | file.write(' if (o.is_zero_11_6())\n') | |
603 | else: | |
604 | file.write(' if (o.is_zero_11_5())\n') | |
605 | file.write(' {\n') | |
606 | self.ill_ibe(file) | |
607 | file.write(' if (o.get_rd_irf())\n') | |
608 | if self.is_x(): | |
609 | self.dec_rr6(file,' ','idx_exe_'+self.name) | |
610 | else: | |
611 | self.dec_rr5(file,' ','idx_exe_'+self.name) | |
612 | file.write(' else\n') | |
613 | self.dec_000(file,' ','idx_exe_nop') | |
614 | file.write(' }\n') | |
615 | file.write(' else\n') | |
616 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
617 | self.c_code_end(file) | |
618 | ||
619 | def is_x(self): | |
620 | return len(self.opc) == 4 and self.opc[3] == 'x' | |
621 | ||
622 | ||
623 | #============================================================================ | |
624 | # SS_tagged_alu(opc) | |
625 | #============================================================================ | |
626 | ||
627 | class SS_tagged_alu(SS_InstrAsm): | |
628 | def __init__(self,opc): | |
629 | SS_InstrAsm.__init__(self,opc) | |
630 | self.opc = opc | |
631 | self.imm = ['i0' ,'i1'] | |
632 | self.out = ['rd' ,'g0'] | |
633 | ||
634 | def run_exe_s(self,file): | |
635 | for imm in self.imm: | |
636 | for out in self.out: | |
637 | self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
638 | self.ld_rs1(file,'%g1') | |
639 | if imm == 'i0': | |
640 | self.ld_rs2(file,'%g2') | |
641 | else: | |
642 | self.ld_imm(file,'%g2') | |
643 | if out == 'rd': | |
644 | self.ld_rd(file,'%g3') | |
645 | self.ld_irf(file,'%g1','%g1') | |
646 | if imm == 'i0': | |
647 | self.ld_irf(file,'%g2','%g2') | |
648 | self.opr(file,'or','%g1','%g2','%g5') | |
649 | if self.opc[0:6] == 'taddcc': | |
650 | self.opr(file,'addcc','%g1','%g2','%g1') | |
651 | else: | |
652 | self.opr(file,'subcc','%g1','%g2','%g1') | |
653 | self.opr(file,'and','%g5','3','%g5') | |
654 | self.movr(file,'nz','%g5','2','%g5') | |
655 | self.rd_ccr(file,'%g4') | |
656 | self.opr(file,'or','%g4','%g5','%g4') | |
657 | if self.opc[-2:] == 'tv': | |
658 | self.opr(file,'and','%g4','2','%g2') | |
659 | file.write('\tbrz\t%g2,1f\n') | |
660 | file.write('\tnop\n') | |
661 | self.ld_trap(file,'%o5') | |
662 | self.jmpl(file,'%o5','%g0','%g0') | |
663 | self.mov(file,'T_TAG_OVERFLOW','%o4') | |
664 | file.write('1:\n') | |
665 | self.mov(file,self.NPC,self.PC) | |
666 | self.add(file,self.NPC,4,self.NPC) | |
667 | self.st_npc(file,self.NPC) | |
668 | if out == 'rd': | |
669 | self.st_irf(file,'%g3','%g1') | |
670 | self.retl(file) | |
671 | self.st_ccr(file,'%g4') | |
672 | ||
673 | def run_exe_c(self,file): | |
674 | for imm in self.imm: | |
675 | for out in self.out: | |
676 | file.write('#if defined(ARCH_X64)\n') | |
677 | self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out) | |
678 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
679 | if (imm == 'i0'): | |
680 | file.write(' int64_t rs2 = s->get_irf(i->rs2);\n') | |
681 | else: | |
682 | file.write(' int64_t rs2 = i->rs2;\n'); | |
683 | if (self.opc in ['taddcc','taddcctv']): | |
684 | file.write(' uint64_t rd = rs1 + rs2;\n') | |
685 | file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n') | |
686 | file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n') | |
687 | else: | |
688 | file.write(' uint64_t rd = rs1 - rs2;\n') | |
689 | file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n') | |
690 | file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n') | |
691 | file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n') | |
692 | file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n') | |
693 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
694 | file.write(' icc |= 0x4;\n') | |
695 | file.write(' if (rd == 0)\n') | |
696 | file.write(' xcc |= 0x4;\n') | |
697 | file.write(' icc |= ((v >> 31) & 0x1) << 1;\n') | |
698 | file.write(' if ((rs1 | rs2) & 0x3)\n') | |
699 | file.write(' icc |= 0x2;\n') | |
700 | file.write(' xcc |= ((v >> 63) & 0x1) << 1;\n') | |
701 | file.write(' icc |= (c >> 31) & 0x1;\n') | |
702 | file.write(' xcc |= (c >> 63) & 0x1;\n') | |
703 | if (self.opc in ['taddcctv','tsubcctv']): | |
704 | file.write(' if (icc & 0x2)\n') | |
705 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::TAG_OVERFLOW);\n') | |
706 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
707 | if (out == 'rd'): | |
708 | file.write(' s->get_irf(i->rd) = rd;\n') | |
709 | file.write(' pc = npc;\n') | |
710 | file.write(' s->npc = npc + 4;\n') | |
711 | file.write(' return pc;\n') | |
712 | self.c_code_end(file) | |
713 | file.write('#else\n') | |
714 | file.write('extern "C" SS_Vaddr run_exe_'+self.opc+'_'+imm+'_'+out+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n') | |
715 | file.write('#endif\n\n') | |
716 | ||
717 | def run_dec_c(self,file): | |
718 | self.c_code_dec_beg_name(file,'run_dec_'+self.opc) | |
719 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
720 | file.write(' if (o.get_i())\n') | |
721 | file.write(' {\n') | |
722 | self.ill_ibe(file) | |
723 | file.write(' if (o.get_rd_irf())\n') | |
724 | self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i1_rd') | |
725 | file.write(' else\n') | |
726 | self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i1_g0') | |
727 | file.write(' }\n') | |
728 | file.write(' else if (o.is_zero_12_5())\n') | |
729 | file.write(' {\n') | |
730 | self.ill_ibe(file) | |
731 | file.write(' if (o.get_rd_irf())\n') | |
732 | self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd') | |
733 | file.write(' else\n') | |
734 | self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_g0') | |
735 | file.write(' }\n') | |
736 | file.write(' else\n') | |
737 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
738 | self.c_code_end(file) | |
739 | ||
740 | def exe_idx_s(self,file): | |
741 | for imm in self.imm: | |
742 | for out in self.out: | |
743 | self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out) | |
744 | ||
745 | def gen_exe_tbl(self,file,mode): | |
746 | for out in self.out: | |
747 | for imm in self.imm: | |
748 | if mode == 'v8_run': | |
749 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n') | |
750 | else: | |
751 | self.gen_exe_rrI(file,mode,imm,out) | |
752 | ||
753 | def run_dec_p(self): | |
754 | return 'run_dec_%s' % self.opc | |
755 | ||
756 | ||
757 | #============================================================================ | |
758 | # SS_mov(cc,ccr,imm) | |
759 | # | |
760 | # ToDo: movn & mova can be optimised | |
761 | #============================================================================ | |
762 | ||
763 | class SS_movcc(SS_InstrAsm): | |
764 | def __init__(self,cc,ccr,imm): | |
765 | SS_InstrAsm.__init__(self,'mov'+cc+'_'+ccr+'_'+imm) | |
766 | self.opc = 'mov'+cc | |
767 | self.cc = cc | |
768 | self.ccr = ccr | |
769 | self.imm = imm | |
770 | ||
771 | def gen_exe_tbl(self,file,mode): | |
772 | if mode == 'v8_run': | |
773 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
774 | else: | |
775 | self.gen_exe_rrI(file,mode) | |
776 | ||
777 | def run_exe_c(self,file): | |
778 | file.write('#if defined(ARCH_X64)\n') | |
779 | self.c_code_beg(file,'run_exe_') | |
780 | if (self.ccr[:3] == 'fcc'): | |
781 | file.write(' if (s->sim_state.fp_disabled())\n') | |
782 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
783 | if (self.ccr[:3] == 'fcc'): | |
784 | self.test_fcc(file,' ') | |
785 | else: | |
786 | self.test_icc(file,' ') | |
787 | file.write(' {\n') | |
788 | if (self.imm == 'i0'): | |
789 | file.write(' int64_t rs2 = s->get_irf(i->rs2);\n') | |
790 | else: | |
791 | file.write(' int64_t rs2 = i->rs2;\n'); | |
792 | file.write(' s->get_irf(i->rd) = rs2;\n') | |
793 | file.write(' }\n') | |
794 | file.write(' pc = npc;\n') | |
795 | file.write(' s->npc = npc + 4;\n') | |
796 | file.write(' return pc;\n') | |
797 | self.c_code_end(file) | |
798 | file.write('#else\n') | |
799 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
800 | file.write('#endif\n\n') | |
801 | ||
802 | def run_exe_s(self,file): | |
803 | self.s_code(file,'run_exe_') | |
804 | if self.ccr[:3] == 'fcc': | |
805 | self.ld_sim(file,'%g5') | |
806 | self.st_fsr_cpu(file,'%fsr') | |
807 | if self.imm == 'i0': | |
808 | self.ld_rs2(file,'%g2') | |
809 | else: | |
810 | self.ld_imm(file,'%g2') | |
811 | self.ld_rd(file,'%g3') | |
812 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
813 | self.branch(file,'ne','%xcc','fpop_disabled_trap_fsr') | |
814 | self.ld_fsr_run(file,'%fsr') | |
815 | self.mov(file,self.NPC,self.PC) | |
816 | if self.imm == 'i0': | |
817 | self.ld_irf(file,'%g2','%g2') | |
818 | self.add(file,self.NPC,4,self.NPC) | |
819 | self.ld_irf(file,'%g3','%g4') | |
820 | self.st_npc(file,self.NPC) | |
821 | self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4') | |
822 | self.st_irf(file,'%g3','%g4') | |
823 | self.retl(file) | |
824 | self.ld_fsr_cpu(file,'%fsr') | |
825 | else: | |
826 | self.mov(file,self.NPC,self.PC) | |
827 | if self.imm == 'i0': | |
828 | self.ld_rs2(file,'%g2') | |
829 | else: | |
830 | self.ld_imm(file,'%g2') | |
831 | self.ld_rd(file,'%g3') | |
832 | self.add(file,self.NPC,4,self.NPC) | |
833 | self.st_npc(file,self.NPC) | |
834 | self.ld_ccr(file,'%g1') | |
835 | if self.imm == 'i0': | |
836 | self.ld_irf(file,'%g2','%g2') | |
837 | self.ld_irf(file,'%g3','%g4') | |
838 | self.wr_ccr(file,'%g1') | |
839 | self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4') | |
840 | self.retl(file) | |
841 | self.st_irf(file,'%g3','%g4') | |
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 | if self.imm == 'i1': | |
847 | self.ill_ibe(file) | |
848 | file.write(' if (o.get_rd_irf())\n') | |
849 | self.dec_rr11(file,' ','idx_exe_'+self.name) | |
850 | file.write(' else\n') | |
851 | self.dec_000(file,' ','idx_exe_nop') | |
852 | else: | |
853 | file.write(' if (o.is_zero_10_5())\n') | |
854 | file.write(' {\n') | |
855 | self.ill_ibe(file) | |
856 | file.write(' if (o.get_rd_irf())\n') | |
857 | self.dec_rrr(file,' ','idx_exe_'+self.name) | |
858 | file.write(' else\n') | |
859 | self.dec_000(file,' ','idx_exe_nop') | |
860 | file.write(' }\n') | |
861 | file.write(' else\n') | |
862 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
863 | self.c_code_end(file) | |
864 | ||
865 | ||
866 | #============================================================================ | |
867 | # SS_movr(cc,imm) | |
868 | #============================================================================ | |
869 | ||
870 | class SS_movr(SS_InstrAsm): | |
871 | def __init__(self,cc,imm): | |
872 | SS_InstrAsm.__init__(self,'movr'+cc+'_'+imm) | |
873 | self.opc = 'movr'+cc | |
874 | self.cc = cc | |
875 | self.imm = imm | |
876 | ||
877 | def run_exe_c(self,file): | |
878 | file.write('#if defined(ARCH_X64)\n') | |
879 | self.c_code_beg(file,'run_exe_') | |
880 | self.test_r(file,' ') | |
881 | file.write(' {\n') | |
882 | if (self.imm == 'i0'): | |
883 | file.write(' int64_t rs2 = s->get_irf(i->rs2);\n') | |
884 | else: | |
885 | file.write(' int64_t rs2 = i->rs2;\n'); | |
886 | file.write(' s->get_irf(i->rd) = rs2;\n') | |
887 | file.write(' }\n') | |
888 | file.write(' pc = npc;\n') | |
889 | file.write(' s->npc = npc + 4;\n') | |
890 | file.write(' return pc;\n') | |
891 | self.c_code_end(file) | |
892 | file.write('#else\n') | |
893 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
894 | file.write('#endif\n\n') | |
895 | ||
896 | def run_exe_s(self,file): | |
897 | self.s_code(file,'run_exe_') | |
898 | self.mov(file,self.NPC,self.PC) | |
899 | self.ld_rs1(file,'%g1') | |
900 | if self.imm == 'i0': | |
901 | self.ld_rs2(file,'%g2') | |
902 | else: | |
903 | self.ld_imm(file,'%g2') | |
904 | self.ld_rd(file,'%g3') | |
905 | self.add(file,self.NPC,4,self.NPC) | |
906 | self.st_npc(file,self.NPC) | |
907 | self.ld_irf(file,'%g1','%g1') | |
908 | if self.imm == 'i0': | |
909 | self.ld_irf(file,'%g2','%g2') | |
910 | self.ld_irf(file,'%g3','%g4') | |
911 | self.movr(file,self.cc,'%g1','%g2','%g4') | |
912 | self.retl(file) | |
913 | self.st_irf(file,'%g3','%g4') | |
914 | ||
915 | def run_dec_c(self,file): | |
916 | self.c_code_dec_beg(file,'run_dec_') | |
917 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
918 | if self.imm == 'i1': | |
919 | self.ill_ibe(file) | |
920 | file.write(' if (o.get_rd_irf())\n') | |
921 | self.dec_rr10(file,' ','idx_exe_'+self.name) | |
922 | file.write(' else\n') | |
923 | self.dec_000(file,' ','idx_exe_nop') | |
924 | else: | |
925 | file.write(' if (o.is_zero_9_5())\n') | |
926 | file.write(' {\n') | |
927 | self.ill_ibe(file) | |
928 | file.write(' if (o.get_rd_irf())\n') | |
929 | self.dec_rrr(file,' ','idx_exe_'+self.name) | |
930 | file.write(' else\n') | |
931 | self.dec_000(file,' ','idx_exe_nop') | |
932 | file.write(' }\n') | |
933 | file.write(' else\n') | |
934 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
935 | self.c_code_end(file) | |
936 | ||
937 | def gen_exe_tbl(self,file,mode): | |
938 | if mode == 'v8_run': | |
939 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
940 | else: | |
941 | self.gen_exe_rrI(file,mode) | |
942 | ||
943 | ||
944 | #============================================================================ | |
945 | # SS_save() | |
946 | #============================================================================ | |
947 | ||
948 | class SS_save(SS_InstrCpp): | |
949 | def __init__(self): | |
950 | SS_InstrCpp.__init__(self,'save') | |
951 | self.opc = 'save' | |
952 | self.imm = ['i0','i1'] | |
953 | self.out = ['rd','g0'] | |
954 | ||
955 | def run_exe_c(self,file): | |
956 | for imm in self.imm: | |
957 | for out in self.out: | |
958 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out) | |
959 | self.fail_chkpt(file) | |
960 | file.write('uint64_t cansave = s->cansave();') | |
961 | file.write('uint64_t cwp = s->cwp();') | |
962 | file.write(' if (cansave == 0)\n') | |
963 | file.write(' {\n') | |
964 | file.write(' if (s->otherwin())\n') | |
965 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n') | |
966 | file.write(' else\n') | |
967 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n') | |
968 | file.write(' }\n') | |
969 | file.write(' else if ((s->cleanwin() - s->canrestore()) == 0)\n') | |
970 | file.write(' {\n') | |
971 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CLEAN_WINDOW);\n') | |
972 | file.write(' }\n') | |
973 | file.write(' else\n') | |
974 | file.write(' {\n') | |
975 | if out == 'g0': | |
976 | file.write(' s->do_save_inst();\n') | |
977 | elif imm == 'i0': | |
978 | file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n') | |
979 | file.write(' s->do_save_inst();\n') | |
980 | file.write(' s->get_irf(i->rd) = val;\n') | |
981 | else: | |
982 | file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n') | |
983 | file.write(' s->do_save_inst();\n') | |
984 | file.write(' s->get_irf(i->rd) = val;\n') | |
985 | file.write(' s->npc = npc+4;\n') | |
986 | file.write(' return npc;\n') | |
987 | file.write(' }\n') | |
988 | file.write('}\n\n') | |
989 | ||
990 | def run_dec_c(self,file): | |
991 | self.c_code_dec_beg(file,'run_dec_') | |
992 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
993 | file.write(' if (o.get_i())\n') | |
994 | file.write(' {\n') | |
995 | self.ill_ibe(file) | |
996 | file.write(' if (o.get_rd_irf())\n') | |
997 | self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd') | |
998 | file.write(' else\n') | |
999 | self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0') | |
1000 | file.write(' }\n') | |
1001 | file.write(' else if (o.is_zero_12_5())\n') | |
1002 | file.write(' {\n') | |
1003 | self.ill_ibe(file) | |
1004 | file.write(' if (o.get_rd_irf())\n') | |
1005 | self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd') | |
1006 | file.write(' else\n') | |
1007 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0') | |
1008 | file.write(' }\n') | |
1009 | file.write(' else\n') | |
1010 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1011 | self.c_code_end(file) | |
1012 | ||
1013 | def exe_idx_s(self,file): | |
1014 | for imm in self.imm: | |
1015 | for out in self.out: | |
1016 | self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out) | |
1017 | ||
1018 | def gen_exe_tbl(self,file,mode): | |
1019 | if mode == 'v8_run': | |
1020 | mode = 'run' | |
1021 | for imm in self.imm: | |
1022 | for out in self.out: | |
1023 | self.gen_exe_rrI(file,mode,imm,out) | |
1024 | ||
1025 | ||
1026 | #============================================================================ | |
1027 | # SS_restore() | |
1028 | #============================================================================ | |
1029 | ||
1030 | class SS_restore(SS_InstrCpp): | |
1031 | def __init__(self): | |
1032 | SS_InstrCpp.__init__(self,'restore') | |
1033 | self.opc = 'restore' | |
1034 | self.imm = ['i0','i1'] | |
1035 | self.out = ['rd','g0'] | |
1036 | ||
1037 | def run_exe_c(self,file): | |
1038 | for imm in self.imm: | |
1039 | for out in self.out: | |
1040 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out) | |
1041 | self.fail_chkpt(file) | |
1042 | file.write(' if (s->canrestore())\n') | |
1043 | file.write(' {\n') | |
1044 | if out == 'g0': | |
1045 | file.write(' s->do_restore_inst();\n') | |
1046 | ||
1047 | elif imm == 'i0': | |
1048 | file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n') | |
1049 | file.write(' s->do_restore_inst();\n') | |
1050 | file.write(' s->get_irf(i->rd) = val;\n') | |
1051 | else: | |
1052 | file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n') | |
1053 | file.write(' s->do_restore_inst();\n') | |
1054 | file.write(' s->get_irf(i->rd) = val;\n') | |
1055 | ||
1056 | file.write(' s->npc = npc+4;\n') | |
1057 | file.write(' return npc;\n') | |
1058 | file.write(' }\n') | |
1059 | file.write(' else if (s->otherwin())\n') | |
1060 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_other(s->wstate.other()));\n') | |
1061 | file.write(' else\n') | |
1062 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_normal(s->wstate.normal()));\n') | |
1063 | file.write('}\n\n') | |
1064 | ||
1065 | def run_dec_c(self,file): | |
1066 | self.c_code_dec_beg(file,'run_dec_') | |
1067 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1068 | file.write(' if (o.get_i())\n') | |
1069 | file.write(' {\n') | |
1070 | self.ill_ibe(file) | |
1071 | file.write(' if (o.get_rd_irf())\n') | |
1072 | self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd') | |
1073 | file.write(' else\n') | |
1074 | self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0') | |
1075 | file.write(' }\n') | |
1076 | file.write(' else if (o.is_zero_12_5())\n') | |
1077 | file.write(' {\n') | |
1078 | self.ill_ibe(file) | |
1079 | file.write(' if (o.get_rd_irf())\n') | |
1080 | self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd') | |
1081 | file.write(' else\n') | |
1082 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0') | |
1083 | file.write(' }\n') | |
1084 | file.write(' else\n') | |
1085 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1086 | self.c_code_end(file) | |
1087 | ||
1088 | def exe_idx_s(self,file): | |
1089 | for imm in self.imm: | |
1090 | for out in self.out: | |
1091 | self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out) | |
1092 | ||
1093 | def gen_exe_tbl(self,file,mode): | |
1094 | if mode == 'v8_run': | |
1095 | mode = 'run' | |
1096 | for imm in self.imm: | |
1097 | for out in self.out: | |
1098 | self.gen_exe_rrI(file,mode,imm,out) | |
1099 | ||
1100 | #============================================================================ | |
1101 | # SS_110001() | |
1102 | #============================================================================ | |
1103 | ||
1104 | class SS_110001(SS_InstrCpp): | |
1105 | def __init__(self,name): | |
1106 | SS_InstrCpp.__init__(self,name) | |
1107 | ||
1108 | def run_dec_c(self,file): | |
1109 | self.c_code_dec_beg(file,'run_dec_') | |
1110 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1111 | file.write(' if (o.is_zero_18_0())\n') | |
1112 | file.write(' {\n') | |
1113 | self.ill_ibe(file) | |
1114 | self.dec_000(file,' ','idx_exe_'+self.name) | |
1115 | file.write(' }\n') | |
1116 | file.write(' else\n') | |
1117 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1118 | self.c_code_end(file) | |
1119 | ||
1120 | ||
1121 | #============================================================================ | |
1122 | # SS_saved() | |
1123 | #============================================================================ | |
1124 | ||
1125 | class SS_saved(SS_110001): | |
1126 | def __init__(self): | |
1127 | SS_110001.__init__(self,'saved') | |
1128 | ||
1129 | def run_exe_c(self,file): | |
1130 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1131 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1132 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1133 | file.write(' else\n') | |
1134 | file.write(' {\n') | |
1135 | file.write(' s->cansave = (s->cansave() < s->max_wp()) ? (s->cansave() + 1) : 0;\n') | |
1136 | file.write(' if (s->otherwin())\n') | |
1137 | file.write(' s->otherwin = s->otherwin() - 1;\n') | |
1138 | file.write(' else\n') | |
1139 | file.write(' s->canrestore = s->canrestore() ? (s->canrestore() - 1) : s->max_wp();\n') | |
1140 | file.write(' s->npc = npc+4; return npc;\n') | |
1141 | file.write(' }\n') | |
1142 | file.write('}\n\n') | |
1143 | ||
1144 | def gen_exe_tbl(self,file,mode): | |
1145 | self.gen_exe_passthrough(file,mode) | |
1146 | ||
1147 | #============================================================================ | |
1148 | # SS_restored() | |
1149 | #============================================================================ | |
1150 | ||
1151 | class SS_restored(SS_110001): | |
1152 | def __init__(self): | |
1153 | SS_110001.__init__(self,'restored') | |
1154 | ||
1155 | def run_exe_c(self,file): | |
1156 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1157 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1158 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1159 | file.write(' else\n') | |
1160 | file.write(' {\n') | |
1161 | file.write(' s->canrestore = (s->canrestore() < s->max_wp()) ? (s->canrestore() + 1) : 0;\n') | |
1162 | file.write(' if (s->otherwin())\n') | |
1163 | file.write(' s->otherwin = s->otherwin() - 1;\n') | |
1164 | file.write(' else\n') | |
1165 | file.write(' s->cansave = s->cansave() ? (s->cansave() - 1) : s->max_wp();\n') | |
1166 | file.write(' if (s->cleanwin() < s->max_wp())\n') | |
1167 | file.write(' s->cleanwin = s->cleanwin() + 1;\n') | |
1168 | file.write(' s->npc = npc+4; return npc;\n') | |
1169 | file.write(' }\n') | |
1170 | file.write('}\n\n') | |
1171 | ||
1172 | def gen_exe_tbl(self,file,mode): | |
1173 | self.gen_exe_passthrough(file,mode) | |
1174 | ||
1175 | #============================================================================ | |
1176 | # SS_allclean() | |
1177 | #============================================================================ | |
1178 | ||
1179 | class SS_allclean(SS_110001): | |
1180 | def __init__(self): | |
1181 | SS_110001.__init__(self,'allclean') | |
1182 | ||
1183 | def run_exe_c(self,file): | |
1184 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1185 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1186 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1187 | file.write(' else\n') | |
1188 | file.write(' {\n') | |
1189 | file.write(' s->cleanwin = s->max_wp();\n') | |
1190 | file.write(' s->npc = npc+4; return npc;\n') | |
1191 | file.write(' }\n') | |
1192 | file.write('}\n\n') | |
1193 | ||
1194 | def gen_exe_tbl(self,file,mode): | |
1195 | self.gen_exe_passthrough(file,mode) | |
1196 | ||
1197 | #============================================================================ | |
1198 | # SS_otherw() | |
1199 | #============================================================================ | |
1200 | ||
1201 | class SS_otherw(SS_110001): | |
1202 | def __init__(self): | |
1203 | SS_110001.__init__(self,'otherw') | |
1204 | ||
1205 | def run_exe_c(self,file): | |
1206 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1207 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1208 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1209 | file.write(' else\n') | |
1210 | file.write(' {\n') | |
1211 | file.write(' s->otherwin = s->canrestore();\n') | |
1212 | file.write(' s->canrestore = 0;\n') | |
1213 | file.write(' s->npc = npc+4; return npc;\n') | |
1214 | file.write(' }\n') | |
1215 | file.write('}\n\n') | |
1216 | ||
1217 | def gen_exe_tbl(self,file,mode): | |
1218 | self.gen_exe_passthrough(file,mode) | |
1219 | ||
1220 | ||
1221 | #============================================================================ | |
1222 | # SS_normalw() | |
1223 | #============================================================================ | |
1224 | ||
1225 | class SS_normalw(SS_110001): | |
1226 | def __init__(self): | |
1227 | SS_110001.__init__(self,'normalw') | |
1228 | ||
1229 | def run_exe_c(self,file): | |
1230 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1231 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1232 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1233 | file.write(' else\n') | |
1234 | file.write(' {\n') | |
1235 | file.write(' s->canrestore = s->otherwin();\n') | |
1236 | file.write(' s->otherwin = 0;\n') | |
1237 | file.write(' s->npc = npc+4; return npc;\n') | |
1238 | file.write(' }\n') | |
1239 | file.write('}\n\n') | |
1240 | ||
1241 | def gen_exe_tbl(self,file,mode): | |
1242 | self.gen_exe_passthrough(file,mode) | |
1243 | ||
1244 | #============================================================================ | |
1245 | # SS_invalw() | |
1246 | #============================================================================ | |
1247 | ||
1248 | class SS_invalw(SS_110001): | |
1249 | def __init__(self): | |
1250 | SS_110001.__init__(self,'invalw') | |
1251 | ||
1252 | def run_exe_c(self,file): | |
1253 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1254 | file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n') | |
1255 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n') | |
1256 | file.write(' else\n') | |
1257 | file.write(' {\n') | |
1258 | file.write(' s->cansave = s->max_wp() - 1;\n') | |
1259 | file.write(' s->canrestore = 0;\n') | |
1260 | file.write(' s->otherwin = 0;\n') | |
1261 | file.write(' s->npc = npc+4; return npc;\n') | |
1262 | file.write(' }\n') | |
1263 | file.write('}\n\n') | |
1264 | ||
1265 | def gen_exe_tbl(self,file,mode): | |
1266 | self.gen_exe_passthrough(file,mode) | |
1267 | ||
1268 | #============================================================================ | |
1269 | # SS_flushw() | |
1270 | #============================================================================ | |
1271 | ||
1272 | class SS_flushw(SS_InstrCpp): | |
1273 | def __init__(self): | |
1274 | SS_InstrCpp.__init__(self,'flushw') | |
1275 | ||
1276 | def run_exe_c(self,file): | |
1277 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1278 | file.write(' if (s->cansave() == (s->max_wp() - 1))\n') | |
1279 | file.write(' { s->npc = npc+4; return npc; }\n') | |
1280 | file.write(' else if (s->otherwin())\n') | |
1281 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n') | |
1282 | file.write(' else\n') | |
1283 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n') | |
1284 | file.write('}\n\n') | |
1285 | ||
1286 | def run_dec_c(self,file): | |
1287 | self.c_code_dec_beg(file,'run_dec_') | |
1288 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1289 | file.write(' if (o.is_zero_18_0() && o.get_rd() == 0)\n') | |
1290 | file.write(' {\n') | |
1291 | self.ill_ibe(file) | |
1292 | self.dec_000(file,' ','idx_exe_flushw') | |
1293 | file.write(' }\n') | |
1294 | file.write(' else\n') | |
1295 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1296 | self.c_code_end(file) | |
1297 | ||
1298 | def gen_exe_tbl(self,file,mode): | |
1299 | self.gen_exe_passthrough(file,mode) | |
1300 | ||
1301 | ||
1302 | #============================================================================ | |
1303 | # SS_popc | |
1304 | #============================================================================ | |
1305 | ||
1306 | class SS_popc(SS_InstrAsm): | |
1307 | def __init__(self): | |
1308 | SS_InstrAsm.__init__(self,'popc') | |
1309 | self.imm = ['i0' ,'i1'] | |
1310 | self.out = ['rd' ,'g0'] | |
1311 | ||
1312 | def run_exe_c(self,file): | |
1313 | for imm in self.imm: | |
1314 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm) | |
1315 | if imm == 'i0': | |
1316 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1317 | else: | |
1318 | file.write(' uint64_t rs2 = int64_t(i->rs2);\n') | |
1319 | file.write(' uint64_t n = 0;\n') | |
1320 | file.write(' for (int i=0; rs2 && i < 64; i++)\n') | |
1321 | file.write(' {\n') | |
1322 | file.write(' n += (rs2 & 1);\n') | |
1323 | file.write(' rs2 >>= 1;\n') | |
1324 | file.write(' }\n') | |
1325 | file.write(' s->get_irf(i->rd) = n;\n') | |
1326 | file.write(' s->npc = npc+4;\n') | |
1327 | file.write(' return npc;\n') | |
1328 | file.write('}\n\n') | |
1329 | ||
1330 | def run_dec_c(self,file): | |
1331 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1332 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1333 | file.write(' if (o.get_rs1())\n') | |
1334 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1335 | file.write(' else if (o.get_i())\n') | |
1336 | file.write(' {\n') | |
1337 | self.ill_ibe(file) | |
1338 | file.write(' if (o.get_rd_irf())\n') | |
1339 | self.dec_r013(file,' ','idx_exe_'+self.name+'_i1') # i1_rd | |
1340 | file.write(' else\n') | |
1341 | self.dec_000(file,' ','idx_exe_nop') # i1_g0 | |
1342 | file.write(' }\n') | |
1343 | file.write(' else if (o.is_zero_12_5())\n') | |
1344 | file.write(' {\n') | |
1345 | self.ill_ibe(file) | |
1346 | file.write(' if (o.get_rd_irf())\n') | |
1347 | self.dec_r0r(file,' ','idx_exe_'+self.name+'_i0') | |
1348 | file.write(' else\n') | |
1349 | self.dec_000(file,' ','idx_exe_nop') # i0_g0 | |
1350 | file.write(' }\n') | |
1351 | file.write(' else\n') | |
1352 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1353 | self.c_code_end(file) | |
1354 | ||
1355 | def exe_idx_s(self,file): | |
1356 | for imm in self.imm: | |
1357 | self.exe_idx_s_name(file,self.name+'_'+imm) | |
1358 | ||
1359 | def gen_exe_tbl(self,file,mode): | |
1360 | for imm in self.imm: | |
1361 | if mode == 'trc': | |
1362 | if self.imm == 'i0': | |
1363 | file.write(' trc_exe_r0r, /* '+self.name+'_'+imm+' */\n') | |
1364 | else: | |
1365 | file.write(' trc_exe_r00, /* '+self.name+'_'+imm+' */\n') | |
1366 | elif mode == 'v8_run': | |
1367 | file.write(' run_exe_'+self.name+'_'+imm+',\n') | |
1368 | else: | |
1369 | file.write(' '+mode+'_exe_'+self.name+'_'+imm+',\n') | |
1370 | ||
1371 | def run_dec_p(self): | |
1372 | return 'run_dec_%s' % self.name | |
1373 | ||
1374 | ||
1375 | #============================================================================ | |
1376 | #============================================================================ | |
1377 | # sll, srl, sra | |
1378 | ||
1379 | ss_sll = SS_InstrGroup('10_100101_sll',12,3) | |
1380 | ss_srl = SS_InstrGroup('10_100110_srl',12,3) | |
1381 | ss_sra = SS_InstrGroup('10_100111_sra',12,3) | |
1382 | ||
1383 | ss_sll.append(SS_sft('sll','i0')) | |
1384 | ss_sll.append(SS_sft('sllx','i0')) | |
1385 | ss_sll.append(SS_sft('sll','i1')) | |
1386 | ss_sll.append(SS_sft('sllx','i1')) | |
1387 | ||
1388 | ss_srl.append(SS_sft('srl','i0')) | |
1389 | ss_srl.append(SS_sft('srlx','i0')) | |
1390 | ss_srl.append(SS_sft('srl','i1')) | |
1391 | ss_srl.append(SS_sft('srlx','i1')) | |
1392 | ||
1393 | ss_sra.append(SS_sft('sra','i0')) | |
1394 | ss_sra.append(SS_sft('srax','i0')) | |
1395 | ss_sra.append(SS_sft('sra','i1')) | |
1396 | ss_sra.append(SS_sft('srax','i1')) | |
1397 | ||
1398 | # movcc | |
1399 | ||
1400 | ss_movcc = SS_InstrGroup('10_101100_movcc',11,0xff) | |
1401 | for cc,x in fcond: | |
1402 | ss_movcc.append(SS_movcc(cc,'fcc0','i0')) | |
1403 | ss_movcc.append(SS_movcc(cc,'fcc1','i0')) | |
1404 | ss_movcc.append(SS_movcc(cc,'fcc2','i0')) | |
1405 | ss_movcc.append(SS_movcc(cc,'fcc3','i0')) | |
1406 | ss_movcc.append(SS_movcc(cc,'fcc0','i1')) | |
1407 | ss_movcc.append(SS_movcc(cc,'fcc1','i1')) | |
1408 | ss_movcc.append(SS_movcc(cc,'fcc2','i1')) | |
1409 | ss_movcc.append(SS_movcc(cc,'fcc3','i1')) | |
1410 | for cc,x in cond: | |
1411 | ss_movcc.append(SS_movcc(cc,'icc','i0')) | |
1412 | ss_movcc.append(SS_ill()) | |
1413 | ss_movcc.append(SS_movcc(cc,'xcc','i0')) | |
1414 | ss_movcc.append(SS_ill()) | |
1415 | ss_movcc.append(SS_movcc(cc,'icc','i1')) | |
1416 | ss_movcc.append(SS_ill()) | |
1417 | ss_movcc.append(SS_movcc(cc,'xcc','i1')) | |
1418 | ss_movcc.append(SS_ill()) | |
1419 | ||
1420 | # movr | |
1421 | ||
1422 | ss_movr = SS_InstrGroup('10_101111_movr',10,0xf) | |
1423 | for cc,x in rcond8: | |
1424 | if (cc != ''): | |
1425 | ss_movr.append(SS_movr(cc,'i0')) | |
1426 | else: | |
1427 | ss_movr.append(SS_ill()) | |
1428 | for cc,x in rcond8: | |
1429 | if (cc != ''): | |
1430 | ss_movr.append(SS_movr(cc,'i1')) | |
1431 | else: | |
1432 | ss_movr.append(SS_ill()) | |
1433 | ||
1434 | # saved/restored | |
1435 | ||
1436 | ss_saved = SS_InstrGroup('10_110001_saved',25,0x1f) | |
1437 | ss_saved.append(SS_saved()) | |
1438 | ss_saved.append(SS_restored()) | |
1439 | ss_saved.append(SS_allclean()) | |
1440 | ss_saved.append(SS_otherw()) | |
1441 | ss_saved.append(SS_normalw()) | |
1442 | ss_saved.append(SS_invalw()) | |
1443 | for i in range(0,26): | |
1444 | ss_saved.append(SS_ill()) |