#!/usr/bin/python import math import sys import tokenize namelist = [] match = {} mask = {} pseudos = {} arguments = {} arglut = {} arglut['rd'] = (11,7) arglut['rs1'] = (19,15) arglut['rs2'] = (24,20) arglut['rs3'] = (31,27) arglut['aqrl'] = (26,25) arglut['pred'] = (27,24) arglut['succ'] = (23,20) arglut['rm'] = (14,12) arglut['imm20'] = (31,12) arglut['jimm20'] = (31,12) arglut['imm12'] = (31,20) arglut['imm12hi'] = (31,25) arglut['bimm12hi'] = (31,25) arglut['imm12lo'] = (11,7) arglut['bimm12lo'] = (11,7) arglut['zimm'] = (19,15) arglut['shamt'] = (25,20) arglut['shamtw'] = (24,20) arglut['vd'] = (11,7) arglut['vs1'] = (19,15) arglut['vs2'] = (24,20) arglut['vs3'] = (31,27) arglut['vop'] = (14,12) arglut['vm'] = (25,25) arglut['vwd'] = (26,26) arglut['vimm'] = (19,15) arglut['vmimm'] = (31,29) arglut['vcimmhi'] = (24,20) arglut['vcimmlo'] = (31,26) causes = [ (0x00, 'misaligned fetch'), (0x01, 'fetch access'), (0x02, 'illegal instruction'), (0x03, 'breakpoint'), (0x04, 'misaligned load'), (0x05, 'load access'), (0x06, 'misaligned store'), (0x07, 'store access'), (0x08, 'user_ecall'), (0x09, 'supervisor_ecall'), (0x0A, 'hypervisor_ecall'), (0x0B, 'machine_ecall'), (0x0C, 'fetch page fault'), (0x0D, 'load page fault'), (0x0F, 'store page fault'), ] csrs = [ # Standard User R/W (0x001, 'fflags'), (0x002, 'frm'), (0x003, 'fcsr'), (0x010, 'vtype'), (0x011, 'vl'), (0x012, 'vlmax'), # Standard User RO (0xC00, 'cycle'), (0xC01, 'time'), (0xC02, 'instret'), (0xC03, 'hpmcounter3'), (0xC04, 'hpmcounter4'), (0xC05, 'hpmcounter5'), (0xC06, 'hpmcounter6'), (0xC07, 'hpmcounter7'), (0xC08, 'hpmcounter8'), (0xC09, 'hpmcounter9'), (0xC0A, 'hpmcounter10'), (0xC0B, 'hpmcounter11'), (0xC0C, 'hpmcounter12'), (0xC0D, 'hpmcounter13'), (0xC0E, 'hpmcounter14'), (0xC0F, 'hpmcounter15'), (0xC10, 'hpmcounter16'), (0xC11, 'hpmcounter17'), (0xC12, 'hpmcounter18'), (0xC13, 'hpmcounter19'), (0xC14, 'hpmcounter20'), (0xC15, 'hpmcounter21'), (0xC16, 'hpmcounter22'), (0xC17, 'hpmcounter23'), (0xC18, 'hpmcounter24'), (0xC19, 'hpmcounter25'), (0xC1A, 'hpmcounter26'), (0xC1B, 'hpmcounter27'), (0xC1C, 'hpmcounter28'), (0xC1D, 'hpmcounter29'), (0xC1E, 'hpmcounter30'), (0xC1F, 'hpmcounter31'), # Standard Supervisor R/W (0x100, 'sstatus'), (0x104, 'sie'), (0x105, 'stvec'), (0x106, 'scounteren'), (0x140, 'sscratch'), (0x141, 'sepc'), (0x142, 'scause'), (0x143, 'stval'), (0x144, 'sip'), (0x180, 'satp'), # Standard Machine R/W (0x300, 'mstatus'), (0x301, 'misa'), (0x302, 'medeleg'), (0x303, 'mideleg'), (0x304, 'mie'), (0x305, 'mtvec'), (0x306, 'mcounteren'), (0x340, 'mscratch'), (0x341, 'mepc'), (0x342, 'mcause'), (0x343, 'mtval'), (0x344, 'mip'), (0x3a0, 'pmpcfg0'), (0x3a1, 'pmpcfg1'), (0x3a2, 'pmpcfg2'), (0x3a3, 'pmpcfg3'), (0x3b0, 'pmpaddr0'), (0x3b1, 'pmpaddr1'), (0x3b2, 'pmpaddr2'), (0x3b3, 'pmpaddr3'), (0x3b4, 'pmpaddr4'), (0x3b5, 'pmpaddr5'), (0x3b6, 'pmpaddr6'), (0x3b7, 'pmpaddr7'), (0x3b8, 'pmpaddr8'), (0x3b9, 'pmpaddr9'), (0x3ba, 'pmpaddr10'), (0x3bb, 'pmpaddr11'), (0x3bc, 'pmpaddr12'), (0x3bd, 'pmpaddr13'), (0x3be, 'pmpaddr14'), (0x3bf, 'pmpaddr15'), (0x7a0, 'tselect'), (0x7a1, 'tdata1'), (0x7a2, 'tdata2'), (0x7a3, 'tdata3'), (0x7b0, 'dcsr'), (0x7b1, 'dpc'), (0x7b2, 'dscratch'), (0xB00, 'mcycle'), (0xB02, 'minstret'), (0xB03, 'mhpmcounter3'), (0xB04, 'mhpmcounter4'), (0xB05, 'mhpmcounter5'), (0xB06, 'mhpmcounter6'), (0xB07, 'mhpmcounter7'), (0xB08, 'mhpmcounter8'), (0xB09, 'mhpmcounter9'), (0xB0A, 'mhpmcounter10'), (0xB0B, 'mhpmcounter11'), (0xB0C, 'mhpmcounter12'), (0xB0D, 'mhpmcounter13'), (0xB0E, 'mhpmcounter14'), (0xB0F, 'mhpmcounter15'), (0xB10, 'mhpmcounter16'), (0xB11, 'mhpmcounter17'), (0xB12, 'mhpmcounter18'), (0xB13, 'mhpmcounter19'), (0xB14, 'mhpmcounter20'), (0xB15, 'mhpmcounter21'), (0xB16, 'mhpmcounter22'), (0xB17, 'mhpmcounter23'), (0xB18, 'mhpmcounter24'), (0xB19, 'mhpmcounter25'), (0xB1A, 'mhpmcounter26'), (0xB1B, 'mhpmcounter27'), (0xB1C, 'mhpmcounter28'), (0xB1D, 'mhpmcounter29'), (0xB1E, 'mhpmcounter30'), (0xB1F, 'mhpmcounter31'), (0x323, 'mhpmevent3'), (0x324, 'mhpmevent4'), (0x325, 'mhpmevent5'), (0x326, 'mhpmevent6'), (0x327, 'mhpmevent7'), (0x328, 'mhpmevent8'), (0x329, 'mhpmevent9'), (0x32A, 'mhpmevent10'), (0x32B, 'mhpmevent11'), (0x32C, 'mhpmevent12'), (0x32D, 'mhpmevent13'), (0x32E, 'mhpmevent14'), (0x32F, 'mhpmevent15'), (0x330, 'mhpmevent16'), (0x331, 'mhpmevent17'), (0x332, 'mhpmevent18'), (0x333, 'mhpmevent19'), (0x334, 'mhpmevent20'), (0x335, 'mhpmevent21'), (0x336, 'mhpmevent22'), (0x337, 'mhpmevent23'), (0x338, 'mhpmevent24'), (0x339, 'mhpmevent25'), (0x33A, 'mhpmevent26'), (0x33B, 'mhpmevent27'), (0x33C, 'mhpmevent28'), (0x33D, 'mhpmevent29'), (0x33E, 'mhpmevent30'), (0x33F, 'mhpmevent31'), # Standard Machine RO (0xF11, 'mvendorid'), (0xF12, 'marchid'), (0xF13, 'mimpid'), (0xF14, 'mhartid'), ] csrs32 = [ # Standard User RO (0xC80, 'cycleh'), (0xC81, 'timeh'), (0xC82, 'instreth'), (0xC83, 'hpmcounter3h'), (0xC84, 'hpmcounter4h'), (0xC85, 'hpmcounter5h'), (0xC86, 'hpmcounter6h'), (0xC87, 'hpmcounter7h'), (0xC88, 'hpmcounter8h'), (0xC89, 'hpmcounter9h'), (0xC8A, 'hpmcounter10h'), (0xC8B, 'hpmcounter11h'), (0xC8C, 'hpmcounter12h'), (0xC8D, 'hpmcounter13h'), (0xC8E, 'hpmcounter14h'), (0xC8F, 'hpmcounter15h'), (0xC90, 'hpmcounter16h'), (0xC91, 'hpmcounter17h'), (0xC92, 'hpmcounter18h'), (0xC93, 'hpmcounter19h'), (0xC94, 'hpmcounter20h'), (0xC95, 'hpmcounter21h'), (0xC96, 'hpmcounter22h'), (0xC97, 'hpmcounter23h'), (0xC98, 'hpmcounter24h'), (0xC99, 'hpmcounter25h'), (0xC9A, 'hpmcounter26h'), (0xC9B, 'hpmcounter27h'), (0xC9C, 'hpmcounter28h'), (0xC9D, 'hpmcounter29h'), (0xC9E, 'hpmcounter30h'), (0xC9F, 'hpmcounter31h'), # Standard Machine RW (0xB80, 'mcycleh'), (0xB82, 'minstreth'), (0xB83, 'mhpmcounter3h'), (0xB84, 'mhpmcounter4h'), (0xB85, 'mhpmcounter5h'), (0xB86, 'mhpmcounter6h'), (0xB87, 'mhpmcounter7h'), (0xB88, 'mhpmcounter8h'), (0xB89, 'mhpmcounter9h'), (0xB8A, 'mhpmcounter10h'), (0xB8B, 'mhpmcounter11h'), (0xB8C, 'mhpmcounter12h'), (0xB8D, 'mhpmcounter13h'), (0xB8E, 'mhpmcounter14h'), (0xB8F, 'mhpmcounter15h'), (0xB90, 'mhpmcounter16h'), (0xB91, 'mhpmcounter17h'), (0xB92, 'mhpmcounter18h'), (0xB93, 'mhpmcounter19h'), (0xB94, 'mhpmcounter20h'), (0xB95, 'mhpmcounter21h'), (0xB96, 'mhpmcounter22h'), (0xB97, 'mhpmcounter23h'), (0xB98, 'mhpmcounter24h'), (0xB99, 'mhpmcounter25h'), (0xB9A, 'mhpmcounter26h'), (0xB9B, 'mhpmcounter27h'), (0xB9C, 'mhpmcounter28h'), (0xB9D, 'mhpmcounter29h'), (0xB9E, 'mhpmcounter30h'), (0xB9F, 'mhpmcounter31h'), ] opcode_base = 0 opcode_size = 7 funct_base = 12 funct_size = 3 def binary(n, digits=0): rep = bin(n)[2:] return rep if digits == 0 else ('0' * (digits - len(rep))) + rep def make_c(match,mask): print '/* Automatically generated by parse-opcodes. */' print '#ifndef RISCV_ENCODING_H' print '#define RISCV_ENCODING_H' for name in namelist: name2 = name.upper().replace('.','_') print '#define MATCH_%s %s' % (name2, hex(match[name])) print '#define MASK_%s %s' % (name2, hex(mask[name])) for num, name in csrs+csrs32: print '#define CSR_%s %s' % (name.upper(), hex(num)) for num, name in causes: print '#define CAUSE_%s %s' % (name.upper().replace(' ', '_'), hex(num)) print '#endif' print '#ifdef DECLARE_INSN' for name in namelist: name2 = name.replace('.','_') print 'DECLARE_INSN(%s, MATCH_%s, MASK_%s)' % (name2, name2.upper(), name2.upper()) print '#endif' print '#ifdef DECLARE_CSR' for num, name in csrs+csrs32: print 'DECLARE_CSR(%s, CSR_%s)' % (name, name.upper()) print '#endif' print '#ifdef DECLARE_CAUSE' for num, name in causes: print 'DECLARE_CAUSE("%s", CAUSE_%s)' % (name, name.upper().replace(' ', '_')) print '#endif' def yank(num,start,len): return (num >> start) & ((1 << len) - 1) def str_arg(arg0,name,match,arguments): if arg0 in arguments: return name or arg0 else: start = arglut[arg0][1] len = arglut[arg0][0] - arglut[arg0][1] + 1 return binary(yank(match,start,len),len) def str_inst(name,arguments): return name.replace('.rv32','').upper() def print_unimp_type(name,match,arguments): print """ & \\multicolumn{10}{|c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ '0'*32, \ 'UNIMP' \ ) def print_u_type(name,match,arguments): print """ & \\multicolumn{8}{|c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('imm20','imm[31:12]',match,arguments), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_uj_type(name,match,arguments): print """ & \\multicolumn{8}{|c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('jimm20','imm[20$\\vert$10:1$\\vert$11$\\vert$19:12]',match,arguments), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_s_type(name,match,arguments): print """ & \\multicolumn{4}{|c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('imm12hi','imm[11:5]',match,arguments), \ str_arg('rs2','',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('imm12lo','imm[4:0]',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_sb_type(name,match,arguments): print """ & \\multicolumn{4}{|c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('bimm12hi','imm[12$\\vert$10:5]',match,arguments), \ str_arg('rs2','',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('bimm12lo','imm[4:1$\\vert$11]',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_i_type(name,match,arguments): print """ & \\multicolumn{6}{|c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('imm12','imm[11:0]',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_csr_type(name,match,arguments): print """ & \\multicolumn{6}{|c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('imm12','csr',match,arguments), \ ('zimm' if name[-1] == 'i' else 'rs1'), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_ish_type(name,match,arguments): print """ & \\multicolumn{3}{|c|}{%s} & \\multicolumn{3}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ binary(yank(match,26,6),6), \ str_arg('shamt','shamt',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_ishw_type(name,match,arguments): print """ & \\multicolumn{4}{|c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ binary(yank(match,25,7),7), \ str_arg('shamtw','shamt',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_r_type(name,match,arguments): print """ & \\multicolumn{4}{|c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ binary(yank(match,25,7),7), \ str_arg('rs2','',match,arguments), \ 'zimm' in arguments and str_arg('zimm','imm[4:0]',match,arguments) or str_arg('rs1','',match,arguments), \ str_arg('rm','',match,arguments), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_r4_type(name,match,arguments): print """ & \\multicolumn{2}{|c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ str_arg('rs3','',match,arguments), \ binary(yank(match,25,2),2), \ str_arg('rs2','',match,arguments), \ str_arg('rs1','',match,arguments), \ str_arg('rm','',match,arguments), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_amo_type(name,match,arguments): print """ & \\multicolumn{2}{|c|}{%s} & \\multicolumn{1}{c|}{aq} & \\multicolumn{1}{c|}{rl} & \\multicolumn{2}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ binary(yank(match,27,5),5), \ str_arg('rs2','',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_fence_type(name,match,arguments): print """ & \\multicolumn{2}{|c|}{%s} & \\multicolumn{3}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & \\multicolumn{1}{c|}{%s} & %s \\\\ \\cline{2-11} """ % \ ( \ binary(yank(match,28,4),4), \ str_arg('pred','pred',match,arguments), \ str_arg('succ','',match,arguments), \ str_arg('rs1','',match,arguments), \ binary(yank(match,funct_base,funct_size),funct_size), \ str_arg('rd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_vi_type(name,match,arguments): #print """2+|%s|%s 2+|%s|%s|%s|%s 2+|%s|%s|%s""" % \ print """2+|%s|%s|%s|%s|%s 2+|%s|%s|%s""" % \ ( \ binary(yank(match,27,5),5), \ str_arg('vm','',match,arguments), \ str_arg('vimm','imm[4:0]',match,arguments), \ str_arg('vs1','',match,arguments), \ binary(yank(match,12,3),3), \ str_arg('vd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_vl_type(name,match,arguments): print """|%s|%s|%s|%s|%s|%s 2+|%s|%s|%s""" % \ ( \ 'vimm' in arguments and 'imm[6:5]' or 'imm[1:0]', \ binary(yank(match,27,3),3), \ str_arg('vm','m',match,arguments), \ 'vimm'in arguments and 'imm[4:0]' or str_arg('rs2' in arguments and 'rs2' or 'vs2','',match,arguments), \ str_arg('rs1' in arguments and 'rs1' or 'vs1','',match,arguments), \ binary(yank(match,12,3),3), \ str_arg('vd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_vs_type(name,match,arguments): print """2+|%s|%s|%s|%s|%s|%s|%s|%s|%s""" % \ ( \ str_arg('rs3' in arguments and 'rs3' or 'vs3','',match,arguments), \ str_arg('vm','m',match,arguments), \ 'vimm'in arguments and 'imm[4:0]' or str_arg('rs2' in arguments and 'rs2' or 'vs2','',match,arguments), \ str_arg('rs1' in arguments and 'rs1' or 'vs1','',match,arguments), \ binary(yank(match,12,3),3), \ 'vimm' in arguments and 'imm[6:5]' or 'imm[1:0]', \ binary(yank(match,7,3),3), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_vr4_type(name,match,arguments): print """2+|%s|%s|%s|%s|%s 2+|%s|%s|%s""" % \ ( \ str_arg('rs3' in arguments and 'rs3' or 'vs3','',match,arguments), \ str_arg('vm','',match,arguments), \ str_arg('rs2' in arguments and 'rs2' or 'vs2','',match,arguments), \ str_arg('rs1' in arguments and 'rs1' or 'vs1','',match,arguments), \ binary(yank(match,12,3),3), \ str_arg('rd' in arguments and 'rd' or 'vd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_vr_type(name,match,arguments): print """2+|%s|%s|%s|%s|%s 2+|%s|%s|%s""" % \ ( \ binary(yank(match,27,5),5), \ str_arg('vm','',match,arguments), \ str_arg('rs2' in arguments and 'rs2' or 'vs2','',match,arguments), \ str_arg('rs1' in arguments and 'rs1' or 'vs1','',match,arguments), \ binary(yank(match,12,3),3), \ str_arg('rd' in arguments and 'rd' or 'vd','',match,arguments), \ binary(yank(match,opcode_base,opcode_size),opcode_size), \ str_inst(name,arguments) \ ) def print_header(*types): print """ \\newpage \\begin{table}[p] \\begin{small} \\begin{center} \\begin{tabular}{p{0in}p{0.4in}p{0.05in}p{0.05in}p{0.05in}p{0.05in}p{0.4in}p{0.6in}p{0.4in}p{0.6in}p{0.7in}l} & & & & & & & & & & \\\\ & \\multicolumn{1}{l}{\\instbit{31}} & \\multicolumn{1}{r}{\\instbit{27}} & \\instbit{26} & \\instbit{25} & \\multicolumn{1}{l}{\\instbit{24}} & \\multicolumn{1}{r}{\\instbit{20}} & \\instbitrange{19}{15} & \\instbitrange{14}{12} & \\instbitrange{11}{7} & \\instbitrange{6}{0} \\\\ \\cline{2-11} """ if 'r' in types: print """ & \\multicolumn{4}{|c|}{funct7} & \\multicolumn{2}{c|}{rs2} & \\multicolumn{1}{c|}{rs1} & \\multicolumn{1}{c|}{funct3} & \\multicolumn{1}{c|}{rd} & \\multicolumn{1}{c|}{opcode} & R-type \\\\ \\cline{2-11} """ if 'r4' in types: print """ & \\multicolumn{2}{|c|}{rs3} & \\multicolumn{2}{c|}{funct2} & \\multicolumn{2}{c|}{rs2} & \\multicolumn{1}{c|}{rs1} & \\multicolumn{1}{c|}{funct3} & \\multicolumn{1}{c|}{rd} & \\multicolumn{1}{c|}{opcode} & R4-type \\\\ \\cline{2-11} """ if 'i' in types: print """ & \\multicolumn{6}{|c|}{imm[11:0]} & \\multicolumn{1}{c|}{rs1} & \\multicolumn{1}{c|}{funct3} & \\multicolumn{1}{c|}{rd} & \\multicolumn{1}{c|}{opcode} & I-type \\\\ \\cline{2-11} """ if 's' in types: print """ & \\multicolumn{4}{|c|}{imm[11:5]} & \\multicolumn{2}{c|}{rs2} & \\multicolumn{1}{c|}{rs1} & \\multicolumn{1}{c|}{funct3} & \\multicolumn{1}{c|}{imm[4:0]} & \\multicolumn{1}{c|}{opcode} & S-type \\\\ \\cline{2-11} """ if 'sb' in types: print """ & \\multicolumn{4}{|c|}{imm[12$\\vert$10:5]} & \\multicolumn{2}{c|}{rs2} & \\multicolumn{1}{c|}{rs1} & \\multicolumn{1}{c|}{funct3} & \\multicolumn{1}{c|}{imm[4:1$\\vert$11]} & \\multicolumn{1}{c|}{opcode} & B-type \\\\ \\cline{2-11} """ if 'u' in types: print """ & \\multicolumn{8}{|c|}{imm[31:12]} & \\multicolumn{1}{c|}{rd} & \\multicolumn{1}{c|}{opcode} & U-type \\\\ \\cline{2-11} """ if 'uj' in types: print """ & \\multicolumn{8}{|c|}{imm[20$\\vert$10:1$\\vert$11$\\vert$19:12]} & \\multicolumn{1}{c|}{rd} & \\multicolumn{1}{c|}{opcode} & J-type \\\\ \\cline{2-11} """ def print_subtitle(title, fields=10): print """ & \\multicolumn{%d}{c}{} & \\\\ & \\multicolumn{%d}{c}{\\bf %s} & \\\\ \\cline{2-%d} """ % (fields, fields, title, fields+1) def print_vec_subtitle(title): print "===%s===" % (title) def print_vec_header(): print """ .Vector Table [width="100%",cols="^3,^3,^3,^4,^4,^3,^3,^3,^7,<10"] |======================== |31 30 |29 27 |26 25 |24 20 |19 15 |14 12 |11 10 |9 7 |6 0 |Opcode """ def print_vec_footer(): print """ |======================== """ def print_vec_inst(n): if 'vlimm' in arguments[n]: print_vl_type(n, match[n], arguments[n]) elif 'vsimm' in arguments[n]: print_vs_type(n, match[n], arguments[n]) elif 'vimm' in arguments[n]: print_vi_type(n, match[n], arguments[n]) elif 'vs3' in arguments[n]: print_vr4_type(n, match[n], arguments[n]) elif 'vs1' in arguments[n] or 'vs2' in arguments[n] or 'vd' in arguments[n]: print_vr_type(n, match[n], arguments[n]) else: print_r_type(n, match[n], arguments[n]) def print_vec_insts(*names): for n in names: print_vec_inst(n) def print_footer(caption=''): print """ \\end{tabular} \\end{center} \\end{small} %s \\label{instr-table} \\end{table} """ % caption def print_inst(n): if n == 'fence' or n == 'fence.i': print_fence_type(n, match[n], arguments[n]) elif 'aqrl' in arguments[n]: print_amo_type(n, match[n], arguments[n]) elif 'shamt' in arguments[n]: print_ish_type(n, match[n], arguments[n]) elif 'shamtw' in arguments[n]: print_ishw_type(n, match[n], arguments[n]) elif 'imm20' in arguments[n]: print_u_type(n, match[n], arguments[n]) elif 'jimm20' in arguments[n]: print_uj_type(n, match[n], arguments[n]) elif n[:3] == 'csr': print_csr_type(n, match[n], arguments[n]) elif 'imm12' in arguments[n] or n == 'ecall' or n == 'ebreak': print_i_type(n, match[n], arguments[n]) elif 'imm12hi' in arguments[n]: print_s_type(n, match[n], arguments[n]) elif 'bimm12hi' in arguments[n]: print_sb_type(n, match[n], arguments[n]) elif 'rs3' in arguments[n]: print_r4_type(n, match[n], arguments[n]) elif 'vimm' in arguments[n]: print_vi_type(n, match[n], arguments[n]) elif 'vmimm' in arguments[n] or 'vs3' in arguments[n]: print_vm_type(n, match[n], arguments[n]) elif 'vs1' in arguments[n] or 'vs2' in arguments[n] or 'vd' in arguments[n]: print_vr_type(n, match[n], arguments[n]) else: print_r_type(n, match[n], arguments[n]) def print_insts(*names): for n in names: print_inst(n) def make_supervisor_latex_table(): print_header('i') print_subtitle('Environment Call and Breakpoint') print_insts('ecall', 'ebreak') print_subtitle('Trap-Return Instructions') print_insts('uret', 'sret', 'mret') print_subtitle('Interrupt-Management Instructions') print_insts('wfi') print_subtitle('Memory-Management Instructions') print_insts('sfence.vma') print_footer('\\caption{RISC-V Privileged Instructions}') def make_latex_table(): print_header('r','i','s','sb','u','uj') print_subtitle('RV32I Base Instruction Set') print_insts('lui', 'auipc') print_insts('jal', 'jalr', 'beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu') print_insts('lb', 'lh', 'lw', 'lbu', 'lhu', 'sb', 'sh', 'sw') print_insts('addi', 'slti', 'sltiu', 'xori', 'ori', 'andi', 'slli.rv32', 'srli.rv32', 'srai.rv32') print_insts('add', 'sub', 'sll', 'slt', 'sltu', 'xor', 'srl', 'sra', 'or', 'and') print_insts('fence', 'fence.i') print_insts('ecall', 'ebreak') print_insts('csrrw', 'csrrs', 'csrrc') print_insts('csrrwi', 'csrrsi', 'csrrci') print_footer() print_header('r','a','i','s') print_subtitle('RV64I Base Instruction Set (in addition to RV32I)') print_insts('lwu', 'ld', 'sd') print_insts('slli', 'srli', 'srai') print_insts('addiw', 'slliw', 'srliw', 'sraiw') print_insts('addw', 'subw', 'sllw', 'srlw', 'sraw') print_subtitle('RV32M Standard Extension') print_insts('mul', 'mulh', 'mulhsu', 'mulhu') print_insts('div', 'divu', 'rem', 'remu') print_subtitle('RV64M Standard Extension (in addition to RV32M)') print_insts('mulw', 'divw', 'divuw', 'remw', 'remuw') print_subtitle('RV32A Standard Extension') print_insts('lr.w', 'sc.w') print_insts('amoswap.w') print_insts('amoadd.w', 'amoxor.w', 'amoand.w', 'amoor.w') print_insts('amomin.w', 'amomax.w', 'amominu.w', 'amomaxu.w') print_footer() print_header('r','r4','i','s') print_subtitle('RV64A Standard Extension (in addition to RV32A)') print_insts('lr.d', 'sc.d') print_insts('amoswap.d') print_insts('amoadd.d', 'amoxor.d', 'amoand.d', 'amoor.d') print_insts('amomin.d', 'amomax.d', 'amominu.d', 'amomaxu.d') print_subtitle('RV32F Standard Extension') print_insts('flw', 'fsw') print_insts('fmadd.s', 'fmsub.s', 'fnmsub.s', 'fnmadd.s') print_insts('fadd.s', 'fsub.s', 'fmul.s', 'fdiv.s', 'fsqrt.s') print_insts('fsgnj.s', 'fsgnjn.s', 'fsgnjx.s', 'fmin.s', 'fmax.s') print_insts('fcvt.w.s', 'fcvt.wu.s', 'fmv.x.w') print_insts('feq.s', 'flt.s', 'fle.s', 'fclass.s') print_insts('fcvt.s.w', 'fcvt.s.wu', 'fmv.w.x') print_footer() print_header('r','r4','i','s') print_subtitle('RV64F Standard Extension (in addition to RV32F)') print_insts('fcvt.l.s', 'fcvt.lu.s') print_insts('fcvt.s.l', 'fcvt.s.lu') print_subtitle('RV32D Standard Extension') print_insts('fld', 'fsd') print_insts('fmadd.d', 'fmsub.d', 'fnmsub.d', 'fnmadd.d') print_insts('fadd.d', 'fsub.d', 'fmul.d', 'fdiv.d', 'fsqrt.d') print_insts('fsgnj.d', 'fsgnjn.d', 'fsgnjx.d', 'fmin.d', 'fmax.d') print_insts('fcvt.s.d', 'fcvt.d.s') print_insts('feq.d', 'flt.d', 'fle.d', 'fclass.d') print_insts('fcvt.w.d', 'fcvt.wu.d') print_insts('fcvt.d.w', 'fcvt.d.wu') print_subtitle('RV64D Standard Extension (in addition to RV32D)') print_insts('fcvt.l.d', 'fcvt.lu.d', 'fmv.x.d') print_insts('fcvt.d.l', 'fcvt.d.lu', 'fmv.d.x') print_footer() def make_vector_adoc_table(): #print_vec_subtitile('RV32V Standard Extension') print_vec_header() # Full op type field print_vec_insts('vadd.vv', 'vadd.vs', 'vadd.vi', 'vaddw.vv', 'vaddw.vs', 'vaddw.wv', 'vaddw.ws') print_vec_insts('vsub.vv', 'vsub.vs', 'vsub.vi', 'vsub.vv', 'vsub.vs', 'vsubw.wv', 'vsubw.ws') print_vec_insts('vmul.vv', 'vmul.vs', 'vmul.vi', 'vmul.vv', 'vmul.vs', 'vmulw.wv', 'vmulw.ws') print_vec_insts('vmulu.vv', 'vmulu.vs', 'vmulu.vi', 'vmulu.vv', 'vmulu.vs', 'vmuluw.wv', 'vmuluw.ws') print_vec_insts('vmulsu.vv', 'vmulsu.vs', 'vmulsu.vi', 'vmulsu.vv', 'vmulsu.vs', 'vmulsuw.wv', 'vmulsuw.ws') print_vec_footer() print_vec_header() # narrowing print_vec_insts('vsrln.vv', 'vsrln.vs', 'vsrln.vi', 'vsrln.wv', 'vsrln.ws', 'vsrln.wi', 'vsran.vv', 'vsran.vs', 'vsran.vi', 'vsran.wv', 'vsran.ws', 'vsran.wi') print_vec_insts('vclipn.vv', 'vclipn.vs', 'vclipn.vi', 'vclipn.wv', 'vclipn.ws', 'vclipn.wi', 'vclipun.vv', 'vclipun.vs', 'vclipun.vi', 'vclipun.wv', 'vclipun.ws', 'vclipun.wi') # not-widening print_vec_insts('vand.vv', 'vand.vs', 'vand.vi', 'vor.vv', 'vor.vs', 'vor.vi', 'vxor.vv', 'vxor.vs', 'vxor.vi', 'vsll.vv', 'vsll.vs', 'vsll.vi', 'vsrl.vv', 'vsrl.vs', 'vsrl.vi', 'vsra.vv', 'vsra.vs', 'vsra.vi') print_vec_insts('vseq.vv', 'vseq.vs', 'vseq.vi', 'vsne.vv', 'vsne.vs', 'vsne.vi', 'vslt.vv', 'vslt.vs', 'vslt.vi', 'vsltu.vv', 'vsltu.vs', 'vsltu.vi', 'vsle.vv', 'vsle.vs', 'vsle.vi', 'vsleu.vv', 'vsleu.vs', 'vsleu.vi') print_vec_insts('vmulh.vv', 'vmulh.vs', 'vmulh.vi', 'vdiv.vv', 'vdiv.vs', 'vdiv.vi', 'vdivu.vv', 'vdivu.vs', 'vdivu.vi', 'vrem.vv', 'vrem.vs', 'vrem.vi', 'vremu.vv', 'vremu.vs', 'vremu.vi') print_vec_insts('vsqrt.vv', 'vsqrt.vs', 'vsqrt.vi', 'vfclass.vv', 'vfclass.vs', 'vfclass.vi') print_vec_insts('vfsgnj.vv', 'vfsgnj.vs', 'vfsgnj.vi', 'vfsgnjn.vv', 'vfsgnjn.vs', 'vfsgnjn.vi', 'vfsgnjx.vv', 'vfsgnjx.vs', 'vfsgnjx.vi') print_vec_insts('vfmin.vv', 'vfmin.vs', 'vfmin.vi', 'vfmax.vv', 'vfmax.vs', 'vfmax.vi') print_vec_footer() print_vec_header() print_vec_insts('vmpopc', 'vmfirst', 'vmsbf.v', 'vmsif.v', 'vmsof.v', 'viota.v') print_vec_insts('vmerge.vv', 'vmerge.vs', 'vmerge.vi', 'vmv.x.v', 'vmv.v.x', 'vmv.s.v', 'vmv.v.s', 'vrgather.vv', 'vslideup.vs', 'vslideup.vi', 'vslidedown.vs', 'vslidedown.vi') print_vec_insts('vredsum.v', 'vredsumw.v', 'vredmax.v', 'vredmaxu.v', 'vredmin.v', 'vredminu.v', 'vredand.v', 'vredor.v', 'vredxor.v') print_vec_insts('vmadd.vvv', 'vmadd.vvs', 'vmsub.vvv', 'vmsub.vvs', 'vmaddw.vvv', 'vmaddw.vvs', 'vmsubw.vvv', 'vmsubw.vvs') print_vec_footer() print_vec_header() print_vec_insts('vlb.v', 'vlh.v', 'vlw.v', 'vle.v', 'vlbu.v', 'vlhu.v', 'vlwu.v', 'vleu.v') print_vec_insts('vlsb.v', 'vlsh.v', 'vlsw.v', 'vlse.v', 'vlsbu.v', 'vlshu.v', 'vlswu.v', 'vlseu.v') print_vec_insts('vlxb.v', 'vlxh.v', 'vlxw.v', 'vlxe.v', 'vlxbu.v', 'vlxhu.v', 'vlxwu.v', 'vlxeu.v') print_vec_insts('vlb.s', 'vlh.s', 'vlw.s', 'vle.s', 'vlbu.s', 'vlhu.s', 'vlwu.s', 'vleu.s') print_vec_insts('vlsb.s', 'vlsh.s', 'vlsw.s', 'vlse.s', 'vlsbu.s', 'vlshu.s', 'vlswu.s', 'vlseu.s') print_vec_insts('vlxb.s', 'vlxh.s', 'vlxw.s', 'vlxe.s', 'vlxbu.s', 'vlxhu.s', 'vlxwu.s', 'vlxeu.s') print_vec_insts('vsb.v', 'vsh.v', 'vsw.v', 'vse.v', 'vsub.v', 'vsuh.v', 'vsuw.v', 'vsue.v') print_vec_insts('vssb.v', 'vssh.v', 'vssw.v', 'vsse.v', 'vsusb.v', 'vsush.v', 'vsusw.v', 'vsuse.v') print_vec_insts('vsxb.v', 'vsxh.v', 'vsxw.v', 'vsxe.v', 'vsuxb.v', 'vsuxh.v', 'vsuxw.v', 'vsuxe.v') print_vec_insts('vsb.s', 'vsh.s', 'vsw.s', 'vse.s', 'vsub.s', 'vsuh.s', 'vsuw.s', 'vsue.s') print_vec_insts('vssb.s', 'vssh.s', 'vssw.s', 'vsse.s', 'vsusb.s', 'vsush.s', 'vsusw.s', 'vsuse.s') print_vec_insts('vsxb.s', 'vsxh.s', 'vsxw.s', 'vsxe.s', 'vsuxb.s', 'vsuxh.s', 'vsuxw.s', 'vsuxe.s') #print_vec_insts('vsetvl', 'vsetvli') print_vec_footer() def print_chisel_insn(name): s = " def %-18s = BitPat(\"b" % name.replace('.', '_').upper() for i in range(31, -1, -1): if yank(mask[name], i, 1): s = '%s%d' % (s, yank(match[name], i, 1)) else: s = s + '?' print s + "\")" def make_chisel(): print '/* Automatically generated by parse-opcodes */' print 'object Instructions {' for name in namelist: print_chisel_insn(name) print '}' print 'object Causes {' for num, name in causes: print ' val %s = %s' % (name.lower().replace(' ', '_'), hex(num)) print ' val all = {' print ' val res = collection.mutable.ArrayBuffer[Int]()' for num, name in causes: print ' res += %s' % (name.lower().replace(' ', '_')) print ' res.toArray' print ' }' print '}' print 'object CSRs {' for num, name in csrs+csrs32: print ' val %s = %s' % (name, hex(num)) print ' val all = {' print ' val res = collection.mutable.ArrayBuffer[Int]()' for num, name in csrs: print ' res += %s' % (name) print ' res.toArray' print ' }' print ' val all32 = {' print ' val res = collection.mutable.ArrayBuffer(all:_*)' for num, name in csrs32: print ' res += %s' % (name) print ' res.toArray' print ' }' print '}' def signed(value, width): if 0 <= value < (1<<(width-1)): return value else: return value - (1<= 2 name = tokens[0] pseudo = name[0] == '@' if pseudo: name = name[1:] mymatch = 0 mymask = 0 cover = 0 if not name in arguments.keys(): arguments[name] = [] for token in tokens[1:]: if len(token.split('=')) == 2: tokens = token.split('=') if len(tokens[0].split('..')) == 2: tmp = tokens[0].split('..') hi = int(tmp[0]) lo = int(tmp[1]) if hi <= lo: sys.exit("%s: bad range %d..%d" % (name,hi,lo)) else: hi = lo = int(tokens[0]) if tokens[1] != 'ignore': val = int(tokens[1], 0) if val >= (1 << (hi-lo+1)): sys.exit("%s: bad value %d for range %d..%d" % (name,val,hi,lo)) mymatch = mymatch | (val << lo) mymask = mymask | ((1<<(hi+1))-(1<