Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_InstrAlu.py
# ========== Copyright Header Begin ==========================================
#
# OpenSPARC T2 Processor File: SS_InstrAlu.py
# Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
#
# The above named program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License version 2 as published by the Free Software Foundation.
#
# The above named program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this work; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ========== Copyright Header End ============================================
#============================================================================
# SS_Alu.py implements most of the op=2 instructions.
#============================================================================
from SS_Instr import *
from SS_Setup import *
setup = setups[sys.argv[1]]
#============================================================================
# sethi/nop
#============================================================================
class SS_nop(SS_InstrAsm):
def __init__(self):
SS_InstrAsm.__init__(self,'nop')
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.retl_st_npc(file,self.NPC)
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg(file,'run_exe_')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n\n')
def run_dec_p(self):
return ''
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
self.gen_exe_passthrough(file,mode)
class SS_sethi(SS_InstrAsm):
def __init__(self):
SS_InstrAsm.__init__(self,'sethi')
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.ld_rd(file,'%g1')
self.ld_rs2_32(file,'%g2')
self.st_npc(file,self.NPC)
self.retl(file)
self.st_irf(file,'%g1','%g2')
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg(file,'run_exe_')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' s->get_irf(i->rd) = *(uint32_t *)(&i->rs2);\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
file.write(' if (o.get_rd())\n')
self.dec_r022(file,' ','idx_exe_sethi')
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
self.c_code_end(file)
def run_dec_p_count(self):
return 8
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_r00, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
SS_InstrAsm.gen_exe_tbl(self,file,mode)
#============================================================================
# SS_alu(opc)
#============================================================================
class SS_alu(SS_InstrAsm):
def __init__(self,opc):
SS_InstrAsm.__init__(self,opc)
self.opc = opc
self.imm = ['i0' ,'i1']
self.out = ['rd' ,'g0']
def run_exe_c(self,file):
for out in self.out:
for imm in self.imm:
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
file.write(' int64_t rs1 = s->get_irf(i->rs1);\n')
if (imm == 'i0'):
file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n');
if (self.opc == 'add'):
file.write(' int64_t rd = rs1 + rs2;\n')
elif (self.opc == 'and'):
file.write(' int64_t rd = rs1 & rs2;\n')
elif (self.opc == 'or'):
file.write(' int64_t rd = rs1 | rs2;\n')
elif (self.opc == 'xor'):
file.write(' int64_t rd = rs1 ^ rs2;\n')
elif (self.opc == 'sub'):
file.write(' int64_t rd = rs1 - rs2;\n')
elif (self.opc == 'andn'):
file.write(' int64_t rd = rs1 & (~rs2);\n')
elif (self.opc == 'orn'):
file.write(' int64_t rd = rs1 | (~rs2);\n')
elif (self.opc == 'xnor'):
file.write(' int64_t rd = ~(rs1 ^ rs2);\n')
elif (self.opc == 'addc'):
file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n')
elif (self.opc == 'mulx'):
file.write(' int64_t rd = rs1 * rs2;\n')
elif (self.opc == 'sdivx'):
file.write(' if (rs2 == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
file.write(' int64_t rd = rs1 / rs2;\n')
elif (self.opc in ['umul','umulcc','smul','smulcc']):
if (self.opc in ['umul','umulcc']):
file.write(' uint32_t t1 = rs1;\n')
file.write(' uint32_t t2 = rs2;\n')
file.write(' uint64_t rd = (uint64_t)t1 * (uint64_t)t2;\n')
else:
file.write(' int32_t t1 = rs1;\n')
file.write(' int32_t t2 = rs2;\n')
file.write(' int64_t rd = (int64_t)t1 * (int64_t)t2;\n')
file.write(' s->y.set((uint32_t)(rd >> 32));\n')
if (self.opc in ['umulcc','smulcc']):
file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
elif (self.opc == 'subc'):
file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n')
elif (self.opc == 'udivx'):
file.write(' uint64_t t1 = *(uint64_t *)&rs1;\n')
file.write(' uint64_t t2 = *(uint64_t *)&rs2;\n')
file.write(' if (t2 == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
file.write(' uint64_t rd = t1 / t2;\n')
elif (self.opc in ['udiv','udivcc','sdiv','sdivcc']):
if (self.opc in ['udiv','udivcc']):
file.write(' uint32_t t1 = rs1;\n')
file.write(' uint32_t t2 = rs2;\n')
file.write(' uint64_t t3 = s->y();\n')
file.write(' t3 = (t3 << 32) + t1;\n')
file.write(' if (t2 == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
file.write(' uint64_t rd = t3 / t2;\n')
file.write(' int overflow = 0;\n')
file.write(' if (rd > 0xffffffffllu) {\n')
file.write(' rd = 0xffffffffllu;\n')
file.write(' overflow = 1;\n')
file.write(' }\n')
elif (self.opc in ['sdiv','sdivcc']):
file.write(' uint32_t t1 = rs1;\n')
file.write(' uint32_t t2 = rs2;\n')
file.write(' int64_t t3 = ((uint64_t)s->y() << 32) + t1;\n')
file.write(' int64_t rd;\n')
file.write(' if (t2 == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
file.write(' int overflow = 0;\n')
file.write(' if ((t3 == 0x8000000000000000ULL) && (t2 == 0xffffffffUL)) {\n')
file.write(' rd = 0x7fffffffLL;\n')
file.write(' overflow = 1;\n')
file.write(' }\n')
file.write(' else\n')
file.write(' rd = t3 / (int32_t)t2;\n')
file.write(' if ((rd > 0LL) && (rd > 0x7fffffffLL)) {\n')
file.write(' rd = 0x7fffffffLL;\n')
file.write(' overflow = 1;\n')
file.write(' }\n')
file.write(' else if ((rd < 0LL) && (rd < 0xffffffff80000000LL)) {\n')
file.write(' rd = 0xffffffff80000000LL;\n')
file.write(' overflow = 1;\n')
file.write(' }\n')
if (self.opc in ['udivcc','sdivcc']):
file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' if (overflow)\n')
file.write(' icc |= 0x2;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
elif (self.opc in ['addcc','addccc','subcc','subccc']):
if (self.opc == 'addcc'):
file.write(' int64_t rd = rs1 + rs2;\n')
elif (self.opc == 'addccc'):
file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n')
elif (self.opc == 'subcc'):
file.write(' int64_t rd = rs1 - rs2;\n')
else:
file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n')
if (self.opc in ['addcc','addccc']):
file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n')
file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n')
else:
file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n')
file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n')
file.write(' uint32_t icc = ((v >> 31) & 0x1) << 1;\n')
file.write(' uint32_t xcc = ((v >> 63) & 0x1) << 1;\n')
file.write(' icc |= ((c >> 31) & 0x1);\n')
file.write(' xcc |= ((c >> 63) & 0x1);\n')
file.write(' icc |= ((rd >> 31) & 0x1) << 3;\n')
file.write(' xcc |= ((rd >> 63) & 0x1) << 3;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
elif (self.opc in ['andcc','orcc','xorcc','andncc','orncc','xnorcc']):
if (self.opc == 'andcc'):
file.write(' int64_t rd = rs1 & rs2;\n')
elif (self.opc == 'orcc'):
file.write(' int64_t rd = rs1 | rs2;\n')
elif (self.opc == 'xorcc'):
file.write(' int64_t rd = rs1 ^ rs2;\n')
elif (self.opc == 'andncc'):
file.write(' int64_t rd = rs1 & (~rs2);\n')
elif (self.opc == 'orncc'):
file.write(' int64_t rd = rs1 | (~rs2);\n')
elif (self.opc == 'xnorcc'):
file.write(' int64_t rd = ~(rs1 ^ rs2);\n')
file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
elif (self.opc == 'mulscc'):
file.write(' /* step 1 */\n')
file.write(' uint64_t t1 = rs2 & 0xFFFFFFFFLLU;\n')
file.write(' /* step 2 */\n')
file.write(' uint32_t icc = s->ccr.icc();\n')
file.write(' uint32_t t0 = ((icc >> 3) ^ ((icc >> 1) & 1)) << 31;\n')
file.write(' uint64_t t2 = rs1 & 0xFFFFFFFFLLU;\n')
file.write(' t2 = (t2 >> 1) | t0;\n')
file.write(' /* step 3 */\n')
file.write(' uint32_t y = s->y();\n')
file.write(' uint64_t t3a = (y & 1) ? t1 : 0;\n')
file.write(' uint64_t rd = t2 + t3a;\n')
file.write(' /* step 5 */\n')
file.write(' s->y.set((y >> 1) | ((rs1 & 0x1) << 31));\n')
file.write(' /* step 4 */\n')
file.write(' uint32_t bit31_rs1 = (t2 >> 31) & 0x1;\n')
file.write(' uint32_t bit31_rs2 = (t3a >> 31) & 0x1;\n')
file.write(' uint32_t bit31_rd = (rd >> 31) & 0x1;\n')
file.write(' icc = bit31_rd << 3;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' if ((bit31_rs1 & bit31_rs2 & ~bit31_rd) ||\n')
file.write(' (~bit31_rs1 & ~bit31_rs2 & bit31_rd))\n')
file.write(' icc |= 0x2;\n')
file.write(' if ((bit31_rs1 & bit31_rs2) ||\n')
file.write(' (~bit31_rd & (bit31_rs1 | bit31_rs2)))\n')
file.write(' icc |= 0x1;\n')
file.write(' uint32_t xcc = (rd == 0) ? 0x4 : 0;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
if (out == 'rd'):
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
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')
file.write('#endif\n\n')
def run_exe_s(self,file):
for out in self.out:
for imm in self.imm:
self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
if self.is_usdiv():
self.ld_y(file,'%g4')
self.ld_rs1(file,'%g1')
if imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.wr_y(file,'%g4')
elif self.is_addci():
self.ld_ccr(file,'%g4')
self.ld_rs1(file,'%g1')
if imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.wr_ccr(file,'%g4')
elif self.is_mulscc():
self.ld_y(file,'%g4')
self.ld_rs1(file,'%g1')
if imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.wr_y(file,'%g4')
self.ld_ccr(file,'%g4')
else:
self.ld_rs1(file,'%g1')
if imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
if not self.is_div():
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.ld_irf(file,'%g1','%g1')
if imm == 'i0':
self.ld_irf(file,'%g2','%g2')
if self.is_mulscc():
self.wr_ccr(file,'%g4')
if not self.is_div():
self.st_npc(file,self.NPC)
if out == 'rd':
self.ld_rd(file,'%g3')
if self.is_div():
if self.is_usdiv():
self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
self.branch(file,'rz','%g2','1f')
self.nop(file)
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
self.opr(file,self.opc,'%g1','%g2','%g1')
if self.is_cc():
self.rd_ccr(file,'%g4')
if ((setup.product in ['N2']) and self.is_mulscc()):
self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32]
self.opr(file,'and','%g4','1','%g2') # get icc.c
self.opr(file,'sllx','%g2','32','%g2') #
self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c
self.opr(file,'and','%g4','0xf','%g4') # get icc of rd
self.rd_ccr(file,'%g2')
self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd
self.opr(file,'or','%g4','%g2','%g4') # the combined ccr
self.st_irf(file,'%g3','%g1')
if self.is_usmul() or self.is_mulscc():
self.rd_y(file,'%g5')
self.st_y(file,'%g5')
self.retl(file)
self.st_ccr(file,'%g4')
elif self.is_usmul():
self.rd_y(file,'%g5')
self.st_irf(file,'%g3','%g1')
self.retl(file)
self.st_y(file,'%g5')
else:
self.retl(file)
self.st_irf(file,'%g3','%g1')
elif self.is_cc(): # rd == %g0
if self.is_div():
if self.is_usdiv():
self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
self.branch(file,'rz','%g2','1f')
self.nop(file)
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
self.opr(file,self.opc,'%g1','%g2','%g1')
self.rd_ccr(file,'%g4')
if ((setup.product in ['N2']) and self.is_mulscc()):
self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32]
self.opr(file,'and','%g4','1','%g2') # get icc.c
self.opr(file,'sllx','%g2','32','%g2') #
self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c
self.opr(file,'and','%g4','0xf','%g4') # get icc of rd
self.rd_ccr(file,'%g2')
self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd
self.opr(file,'or','%g4','%g2','%g4') # the combined ccr
if self.is_usmul() or self.is_mulscc():
self.rd_y(file,'%g5')
self.st_y(file,'%g5')
self.retl(file)
self.st_ccr(file,'%g4')
elif self.is_usmul():
self.opr(file,self.opc,'%g1','%g2','%g0')
self.rd_y(file,'%g5')
self.retl(file)
self.st_y(file,'%g5')
else:
if self.is_div():
if self.is_usdiv():
self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
self.branch(file,'rz','%g2','1f')
self.nop(file)
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
self.retl(file)
self.opr(file,self.opc,'%g1','%g2','%g0')
if self.is_div():
file.write('1:\n')
self.ld_trap(file,'%o5')
self.jmpl(file,'%o5','%g0','%g0')
self.mov(file,'T_DIVISION_BY_ZERO','%o4')
self.asm_codesize(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.opc)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i0_rd + 1') # i1_rd
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i0_rd + 3') # i1_g0
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_rd + 2') # i0_g0
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def exe_idx_s(self,file):
for out in self.out:
for imm in self.imm:
self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
def gen_exe_tbl(self,file,mode):
for out in self.out:
for imm in self.imm:
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n')
else:
self.gen_exe_rrI(file,mode,imm,out)
def run_dec_p(self):
return 'run_dec_%s' % self.opc
def is_mulscc(self):
return self.opc == 'mulscc'
def is_usmul(self):
return (self.opc == 'umul') or (self.opc == 'smul') or (self.opc == 'umulcc') or (self.opc == 'smulcc')
def is_div(self):
return self.is_usdiv() or (self.opc == 'udivx') or (self.opc == 'sdivx')
def is_usdiv(self):
return (self.opc == 'udiv') or (self.opc == 'sdiv') or (self.opc == 'udivcc') or (self.opc == 'sdivcc')
def is_addci(self):
return (self.opc == 'addc') or (self.opc == 'subc') or (self.opc == 'addccc') or (self.opc == 'subccc')
def is_cc(self):
return (self.opc[-2:] == 'cc')
#============================================================================
# SS_sft(opc,imm,out)
#
# ToDo: opc to %g0 that don't set %ccr or %y are nop
# ToDo: (mov) or %g0,src,dst is a frequent used instruction
# ToDo: (cmp) subcc src,src,%g0 is a frequent used instruction
# ToDo: These are excelent candidates for some dynamic translation (33% faster)
#============================================================================
class SS_sft(SS_InstrAsm):
def __init__(self,opc,imm):
SS_InstrAsm.__init__(self,opc+'_'+imm)
self.opc = opc
self.imm = imm
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
self.gen_exe_rrI(file,mode)
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)')
self.c_code_beg(file,'run_exe_')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
if (self.imm == 'i0'):
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' uint64_t rs2 = i->rs2;\n');
if (self.opc in ['sll','srl','sra']):
file.write(' uint32_t shcnt = rs2 & 0x1f;\n')
if (self.opc == 'sll'):
file.write(' uint64_t rd = rs1 << shcnt;\n')
elif (self.opc == 'srl'):
file.write(' uint64_t rd = (rs1 & 0xffffffff) >> shcnt;\n')
else:
file.write(' int32_t t1 = rs1;\n')
file.write(' uint64_t rd = t1 >> shcnt;\n')
else:
file.write(' uint32_t shcnt = rs2 & 0x3f;\n')
if (self.opc == 'sllx'):
file.write(' uint64_t rd = rs1 << shcnt;\n')
elif (self.opc == 'srlx'):
file.write(' uint64_t rd = rs1 >> shcnt;\n')
else:
file.write(' uint64_t rd = ((int64_t)rs1) >> shcnt;\n')
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n\n')
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_rs1(file,'%g1')
if (self.imm == 'i0'):
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.mov(file,self.NPC,self.PC)
self.ld_irf(file,'%g1','%g1')
if (self.imm == 'i0'):
self.ld_irf(file,'%g2','%g2')
self.ld_rd(file,'%g3')
self.add(file,self.NPC,4,self.NPC)
self.opr(file,self.opc,'%g1','%g2','%g1')
self.st_npc(file,self.NPC)
self.retl(file)
self.st_irf(file,'%g3','%g1')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
if self.imm == 'i0':
file.write(' if (o.is_zero_11_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
else:
if self.is_x():
file.write(' if (o.is_zero_11_6())\n')
else:
file.write(' if (o.is_zero_11_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
if self.is_x():
self.dec_rr6(file,' ','idx_exe_'+self.name)
else:
self.dec_rr5(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def is_x(self):
return len(self.opc) == 4 and self.opc[3] == 'x'
#============================================================================
# SS_tagged_alu(opc)
#============================================================================
class SS_tagged_alu(SS_InstrAsm):
def __init__(self,opc):
SS_InstrAsm.__init__(self,opc)
self.opc = opc
self.imm = ['i0' ,'i1']
self.out = ['rd' ,'g0']
def run_exe_s(self,file):
for imm in self.imm:
for out in self.out:
self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
self.ld_rs1(file,'%g1')
if imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
if out == 'rd':
self.ld_rd(file,'%g3')
self.ld_irf(file,'%g1','%g1')
if imm == 'i0':
self.ld_irf(file,'%g2','%g2')
self.opr(file,'or','%g1','%g2','%g5')
if self.opc[0:6] == 'taddcc':
self.opr(file,'addcc','%g1','%g2','%g1')
else:
self.opr(file,'subcc','%g1','%g2','%g1')
self.opr(file,'and','%g5','3','%g5')
self.movr(file,'nz','%g5','2','%g5')
self.rd_ccr(file,'%g4')
self.opr(file,'or','%g4','%g5','%g4')
if self.opc[-2:] == 'tv':
self.opr(file,'and','%g4','2','%g2')
file.write('\tbrz\t%g2,1f\n')
file.write('\tnop\n')
self.ld_trap(file,'%o5')
self.jmpl(file,'%o5','%g0','%g0')
self.mov(file,'T_TAG_OVERFLOW','%o4')
file.write('1:\n')
self.mov(file,self.NPC,self.PC)
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
if out == 'rd':
self.st_irf(file,'%g3','%g1')
self.retl(file)
self.st_ccr(file,'%g4')
def run_exe_c(self,file):
for imm in self.imm:
for out in self.out:
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
if (imm == 'i0'):
file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n');
if (self.opc in ['taddcc','taddcctv']):
file.write(' uint64_t rd = rs1 + rs2;\n')
file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n')
file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n')
else:
file.write(' uint64_t rd = rs1 - rs2;\n')
file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n')
file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n')
file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' icc |= ((v >> 31) & 0x1) << 1;\n')
file.write(' if ((rs1 | rs2) & 0x3)\n')
file.write(' icc |= 0x2;\n')
file.write(' xcc |= ((v >> 63) & 0x1) << 1;\n')
file.write(' icc |= (c >> 31) & 0x1;\n')
file.write(' xcc |= (c >> 63) & 0x1;\n')
if (self.opc in ['taddcctv','tsubcctv']):
file.write(' if (icc & 0x2)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::TAG_OVERFLOW);\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
if (out == 'rd'):
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
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')
file.write('#endif\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.opc)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i1_g0')
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_g0')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def exe_idx_s(self,file):
for imm in self.imm:
for out in self.out:
self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
def gen_exe_tbl(self,file,mode):
for out in self.out:
for imm in self.imm:
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n')
else:
self.gen_exe_rrI(file,mode,imm,out)
def run_dec_p(self):
return 'run_dec_%s' % self.opc
#============================================================================
# SS_mov(cc,ccr,imm)
#
# ToDo: movn & mova can be optimised
#============================================================================
class SS_movcc(SS_InstrAsm):
def __init__(self,cc,ccr,imm):
SS_InstrAsm.__init__(self,'mov'+cc+'_'+ccr+'_'+imm)
self.opc = 'mov'+cc
self.cc = cc
self.ccr = ccr
self.imm = imm
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
self.gen_exe_rrI(file,mode)
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg(file,'run_exe_')
if (self.ccr[:3] == 'fcc'):
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if (self.ccr[:3] == 'fcc'):
self.test_fcc(file,' ')
else:
self.test_icc(file,' ')
file.write(' {\n')
if (self.imm == 'i0'):
file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n');
file.write(' s->get_irf(i->rd) = rs2;\n')
file.write(' }\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n\n')
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
if self.ccr[:3] == 'fcc':
self.ld_sim(file,'%g5')
self.st_fsr_cpu(file,'%fsr')
if self.imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap_fsr')
self.ld_fsr_run(file,'%fsr')
self.mov(file,self.NPC,self.PC)
if self.imm == 'i0':
self.ld_irf(file,'%g2','%g2')
self.add(file,self.NPC,4,self.NPC)
self.ld_irf(file,'%g3','%g4')
self.st_npc(file,self.NPC)
self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4')
self.st_irf(file,'%g3','%g4')
self.retl(file)
self.ld_fsr_cpu(file,'%fsr')
else:
self.mov(file,self.NPC,self.PC)
if self.imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.ld_rd(file,'%g3')
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
self.ld_ccr(file,'%g1')
if self.imm == 'i0':
self.ld_irf(file,'%g2','%g2')
self.ld_irf(file,'%g3','%g4')
self.wr_ccr(file,'%g1')
self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4')
self.retl(file)
self.st_irf(file,'%g3','%g4')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
if self.imm == 'i1':
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr11(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
else:
file.write(' if (o.is_zero_10_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
#============================================================================
# SS_movr(cc,imm)
#============================================================================
class SS_movr(SS_InstrAsm):
def __init__(self,cc,imm):
SS_InstrAsm.__init__(self,'movr'+cc+'_'+imm)
self.opc = 'movr'+cc
self.cc = cc
self.imm = imm
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg(file,'run_exe_')
self.test_r(file,' ')
file.write(' {\n')
if (self.imm == 'i0'):
file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n');
file.write(' s->get_irf(i->rd) = rs2;\n')
file.write(' }\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n\n')
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.mov(file,self.NPC,self.PC)
self.ld_rs1(file,'%g1')
if self.imm == 'i0':
self.ld_rs2(file,'%g2')
else:
self.ld_imm(file,'%g2')
self.ld_rd(file,'%g3')
self.add(file,self.NPC,4,self.NPC)
self.st_npc(file,self.NPC)
self.ld_irf(file,'%g1','%g1')
if self.imm == 'i0':
self.ld_irf(file,'%g2','%g2')
self.ld_irf(file,'%g3','%g4')
self.movr(file,self.cc,'%g1','%g2','%g4')
self.retl(file)
self.st_irf(file,'%g3','%g4')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
if self.imm == 'i1':
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr10(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
else:
file.write(' if (o.is_zero_9_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name)
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
self.gen_exe_rrI(file,mode)
#============================================================================
# SS_save()
#============================================================================
class SS_save(SS_InstrCpp):
def __init__(self):
SS_InstrCpp.__init__(self,'save')
self.opc = 'save'
self.imm = ['i0','i1']
self.out = ['rd','g0']
def run_exe_c(self,file):
for imm in self.imm:
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out)
self.fail_chkpt(file)
file.write('uint64_t cansave = s->cansave();')
file.write('uint64_t cwp = s->cwp();')
file.write(' if (cansave == 0)\n')
file.write(' {\n')
file.write(' if (s->otherwin())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n')
file.write(' }\n')
file.write(' else if ((s->cleanwin() - s->canrestore()) == 0)\n')
file.write(' {\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CLEAN_WINDOW);\n')
file.write(' }\n')
file.write(' else\n')
file.write(' {\n')
if out == 'g0':
file.write(' s->do_save_inst();\n')
elif imm == 'i0':
file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
file.write(' s->do_save_inst();\n')
file.write(' s->get_irf(i->rd) = val;\n')
else:
file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n')
file.write(' s->do_save_inst();\n')
file.write(' s->get_irf(i->rd) = val;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0')
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def exe_idx_s(self,file):
for imm in self.imm:
for out in self.out:
self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
for imm in self.imm:
for out in self.out:
self.gen_exe_rrI(file,mode,imm,out)
#============================================================================
# SS_restore()
#============================================================================
class SS_restore(SS_InstrCpp):
def __init__(self):
SS_InstrCpp.__init__(self,'restore')
self.opc = 'restore'
self.imm = ['i0','i1']
self.out = ['rd','g0']
def run_exe_c(self,file):
for imm in self.imm:
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out)
self.fail_chkpt(file)
file.write(' if (s->canrestore())\n')
file.write(' {\n')
if out == 'g0':
file.write(' s->do_restore_inst();\n')
elif imm == 'i0':
file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
file.write(' s->do_restore_inst();\n')
file.write(' s->get_irf(i->rd) = val;\n')
else:
file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n')
file.write(' s->do_restore_inst();\n')
file.write(' s->get_irf(i->rd) = val;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
file.write(' }\n')
file.write(' else if (s->otherwin())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_other(s->wstate.other()));\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_normal(s->wstate.normal()));\n')
file.write('}\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0')
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def exe_idx_s(self,file):
for imm in self.imm:
for out in self.out:
self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
for imm in self.imm:
for out in self.out:
self.gen_exe_rrI(file,mode,imm,out)
#============================================================================
# SS_110001()
#============================================================================
class SS_110001(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_0())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_000(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
#============================================================================
# SS_saved()
#============================================================================
class SS_saved(SS_110001):
def __init__(self):
SS_110001.__init__(self,'saved')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->cansave = (s->cansave() < s->max_wp()) ? (s->cansave() + 1) : 0;\n')
file.write(' if (s->otherwin())\n')
file.write(' s->otherwin = s->otherwin() - 1;\n')
file.write(' else\n')
file.write(' s->canrestore = s->canrestore() ? (s->canrestore() - 1) : s->max_wp();\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_restored()
#============================================================================
class SS_restored(SS_110001):
def __init__(self):
SS_110001.__init__(self,'restored')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->canrestore = (s->canrestore() < s->max_wp()) ? (s->canrestore() + 1) : 0;\n')
file.write(' if (s->otherwin())\n')
file.write(' s->otherwin = s->otherwin() - 1;\n')
file.write(' else\n')
file.write(' s->cansave = s->cansave() ? (s->cansave() - 1) : s->max_wp();\n')
file.write(' if (s->cleanwin() < s->max_wp())\n')
file.write(' s->cleanwin = s->cleanwin() + 1;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_allclean()
#============================================================================
class SS_allclean(SS_110001):
def __init__(self):
SS_110001.__init__(self,'allclean')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->cleanwin = s->max_wp();\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_otherw()
#============================================================================
class SS_otherw(SS_110001):
def __init__(self):
SS_110001.__init__(self,'otherw')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->otherwin = s->canrestore();\n')
file.write(' s->canrestore = 0;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_normalw()
#============================================================================
class SS_normalw(SS_110001):
def __init__(self):
SS_110001.__init__(self,'normalw')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->canrestore = s->otherwin();\n')
file.write(' s->otherwin = 0;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_invalw()
#============================================================================
class SS_invalw(SS_110001):
def __init__(self):
SS_110001.__init__(self,'invalw')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else\n')
file.write(' {\n')
file.write(' s->cansave = s->max_wp() - 1;\n')
file.write(' s->canrestore = 0;\n')
file.write(' s->otherwin = 0;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' }\n')
file.write('}\n\n')
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_flushw()
#============================================================================
class SS_flushw(SS_InstrCpp):
def __init__(self):
SS_InstrCpp.__init__(self,'flushw')
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->cansave() == (s->max_wp() - 1))\n')
file.write(' { s->npc = npc+4; return npc; }\n')
file.write(' else if (s->otherwin())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n')
file.write('}\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_0() && o.get_rd() == 0)\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_000(file,' ','idx_exe_flushw')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
self.gen_exe_passthrough(file,mode)
#============================================================================
# SS_popc
#============================================================================
class SS_popc(SS_InstrAsm):
def __init__(self):
SS_InstrAsm.__init__(self,'popc')
self.imm = ['i0' ,'i1']
self.out = ['rd' ,'g0']
def run_exe_c(self,file):
for imm in self.imm:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm)
if imm == 'i0':
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' uint64_t rs2 = int64_t(i->rs2);\n')
file.write(' uint64_t n = 0;\n')
file.write(' for (int i=0; rs2 && i < 64; i++)\n')
file.write(' {\n')
file.write(' n += (rs2 & 1);\n')
file.write(' rs2 >>= 1;\n')
file.write(' }\n')
file.write(' s->get_irf(i->rd) = n;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
file.write('}\n\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_rs1())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' else if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_r013(file,' ','idx_exe_'+self.name+'_i1') # i1_rd
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop') # i1_g0
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_r0r(file,' ','idx_exe_'+self.name+'_i0')
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop') # i0_g0
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def exe_idx_s(self,file):
for imm in self.imm:
self.exe_idx_s_name(file,self.name+'_'+imm)
def gen_exe_tbl(self,file,mode):
for imm in self.imm:
if mode == 'trc':
if self.imm == 'i0':
file.write(' trc_exe_r0r, /* '+self.name+'_'+imm+' */\n')
else:
file.write(' trc_exe_r00, /* '+self.name+'_'+imm+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_'+self.name+'_'+imm+',\n')
else:
file.write(' '+mode+'_exe_'+self.name+'_'+imm+',\n')
def run_dec_p(self):
return 'run_dec_%s' % self.name
#============================================================================
#============================================================================
# sll, srl, sra
ss_sll = SS_InstrGroup('10_100101_sll',12,3)
ss_srl = SS_InstrGroup('10_100110_srl',12,3)
ss_sra = SS_InstrGroup('10_100111_sra',12,3)
ss_sll.append(SS_sft('sll','i0'))
ss_sll.append(SS_sft('sllx','i0'))
ss_sll.append(SS_sft('sll','i1'))
ss_sll.append(SS_sft('sllx','i1'))
ss_srl.append(SS_sft('srl','i0'))
ss_srl.append(SS_sft('srlx','i0'))
ss_srl.append(SS_sft('srl','i1'))
ss_srl.append(SS_sft('srlx','i1'))
ss_sra.append(SS_sft('sra','i0'))
ss_sra.append(SS_sft('srax','i0'))
ss_sra.append(SS_sft('sra','i1'))
ss_sra.append(SS_sft('srax','i1'))
# movcc
ss_movcc = SS_InstrGroup('10_101100_movcc',11,0xff)
for cc,x in fcond:
ss_movcc.append(SS_movcc(cc,'fcc0','i0'))
ss_movcc.append(SS_movcc(cc,'fcc1','i0'))
ss_movcc.append(SS_movcc(cc,'fcc2','i0'))
ss_movcc.append(SS_movcc(cc,'fcc3','i0'))
ss_movcc.append(SS_movcc(cc,'fcc0','i1'))
ss_movcc.append(SS_movcc(cc,'fcc1','i1'))
ss_movcc.append(SS_movcc(cc,'fcc2','i1'))
ss_movcc.append(SS_movcc(cc,'fcc3','i1'))
for cc,x in cond:
ss_movcc.append(SS_movcc(cc,'icc','i0'))
ss_movcc.append(SS_ill())
ss_movcc.append(SS_movcc(cc,'xcc','i0'))
ss_movcc.append(SS_ill())
ss_movcc.append(SS_movcc(cc,'icc','i1'))
ss_movcc.append(SS_ill())
ss_movcc.append(SS_movcc(cc,'xcc','i1'))
ss_movcc.append(SS_ill())
# movr
ss_movr = SS_InstrGroup('10_101111_movr',10,0xf)
for cc,x in rcond8:
if (cc != ''):
ss_movr.append(SS_movr(cc,'i0'))
else:
ss_movr.append(SS_ill())
for cc,x in rcond8:
if (cc != ''):
ss_movr.append(SS_movr(cc,'i1'))
else:
ss_movr.append(SS_ill())
# saved/restored
ss_saved = SS_InstrGroup('10_110001_saved',25,0x1f)
ss_saved.append(SS_saved())
ss_saved.append(SS_restored())
ss_saved.append(SS_allclean())
ss_saved.append(SS_otherw())
ss_saved.append(SS_normalw())
ss_saved.append(SS_invalw())
for i in range(0,26):
ss_saved.append(SS_ill())