diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-07-28 19:08:04 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-07-28 19:08:04 -0700 |
commit | 056659263eaebb716eee839054e540cb83e3381b (patch) | |
tree | cc2784954954b5bf684077b1c2b405eb59f97acd | |
parent | 491e8f77c1e8fb1d2dce0df5e7f12000ce1da859 (diff) |
[sim,xcc] Changed instruction format to RISC-V
Massive changes to gcc, binutils to support new instruction encoding.
Simulator reflects these changes.
-rw-r--r-- | opcodes | 310 | ||||
-rwxr-xr-x | parse-opcodes | 226 | ||||
-rwxr-xr-x | update-opcodes | 2 |
3 files changed, 301 insertions, 237 deletions
@@ -1,148 +1,164 @@ -synci 001 -j 002 -jal 003 -beq 004 -bne 005 - -addi 010 -slti 012 -sltiu 013 -andi 014 -ori 015 -xori 016 -lui 017 - -blt 024 -bltu 025 -ble 026 -bleu 027 - -daddi 030 - -lb 040 -lh 041 -lw 043 -lbu 044 -lhu 045 -lwu 047 - -sb 050 -sh 051 -sw 053 - -l.s 061 -l.d 065 -ld 067 - -s.s 071 -s.d 075 -sd 077 - - - - - -unimp 000 000 -sll 000 001 -srl 000 002 -sra 000 003 -sllv 000 005 -srlv 000 006 -srav 000 007 - -jalr 000 011 -movz 000 012 -movn 000 013 -syscall 000 014 -break 000 015 -rdhwr 000 016 -sync 000 017 - -dsll 000 021 -dsrl 000 022 -dsra 000 023 -dsllv 000 025 -dsrlv 000 026 -dsrav 000 027 - -dsll32 000 031 -dsrl32 000 032 -dsra32 000 033 - -add 000 040 -sub 000 041 -slt 000 042 -sltu 000 043 -and 000 044 -or 000 045 -xor 000 046 -nor 000 047 - -mul 000 050 - -dadd 000 060 -dsub 000 061 - -dmul 000 070 - - - -ei 020 000 -di 020 001 -eret 020 002 - -mfc0 020 030 -dmfc0 020 031 -mtc0 020 034 -dmtc0 020 035 - -add.fmt 021 000 -sub.fmt 021 001 -mul.fmt 021 002 -div.fmt 021 003 -sqrt.fmt 021 004 -abs.fmt 021 005 -mov.fmt 021 006 -neg.fmt 021 007 - -round.l.fmt 021 010 -trunc.l.fmt 021 011 -ceil.l.fmt 021 012 -floor.l.fmt 021 013 -round.w.fmt 021 014 -trunc.w.fmt 021 015 -ceil.w.fmt 021 016 -floor.w.fmt 021 017 - -mfc1 021 030 -dmfc1 021 031 -cfc1 021 032 -mfhc1 021 033 -mtc1 021 034 -dmtc1 021 035 -ctc1 021 036 -mthc1 021 037 - -cvt.s.fmt 021 040 -cvt.d.fmt 021 041 -cvt.w.fmt 021 044 -cvt.l.fmt 021 045 - -c.f.fmt 021 060 -c.un.fmt 021 061 -c.eq.fmt 021 062 -c.ueq.fmt 021 063 -c.olt.fmt 021 064 -c.ult.fmt 021 065 -c.ole.fmt 021 066 -c.ule.fmt 021 067 - -c.sf.fmt 021 070 -c.ngle.fmt 021 071 -c.seq.fmt 021 072 -c.ngl.fmt 021 073 -c.lt.fmt 021 074 -c.nge.fmt 021 075 -c.le.fmt 021 076 -c.ngt.fmt 021 077 +# format of a line in this file: +# <instruction name> <opcode> <args> +# +# <opcode> is given by specifying one or more range/value pairs: +# highbit..lowbit=value (e.g. 31..25=0x45 14..12=0x0) +# +# <args> follows the conventions in xcc/src/opcodes/mips-opc.c + +unimp 31..0=0 + +j 31..27=0x18 imm27 # opcodes 0x60-0x64 +jal 31..27=0x19 imm27 # opcodes 0x64-0x68 + +lui 31..25=0x71 ra imm20 +slori 31..25=0x72 ra imm20 + +beq 31..25=0x73 14..12=0 ra rb imm +bne 31..25=0x73 14..12=1 ra rb imm +blt 31..25=0x73 14..12=2 ra rb imm +bltu 31..25=0x73 14..12=3 ra rb imm +ble 31..25=0x73 14..12=4 ra rb imm +bleu 31..25=0x73 14..12=5 ra rb imm + +addi 31..25=0x74 14..12=0 ra rb imm +daddi 31..25=0x74 14..12=1 ra rb imm +slti 31..25=0x74 14..12=2 ra rb imm +sltiu 31..25=0x74 14..12=3 ra rb imm +andi 31..25=0x74 14..12=4 ra rb imm +ori 31..25=0x74 14..12=5 ra rb imm +xori 31..25=0x74 14..12=6 ra rb imm + +add 31..25=0x75 14..12=0 11..5=0 rc rb ra +sub 31..25=0x75 14..12=0 11..5=1 rc rb ra +slt 31..25=0x75 14..12=0 11..5=2 rc rb ra +sltu 31..25=0x75 14..12=0 11..5=3 rc rb ra +and 31..25=0x75 14..12=0 11..5=4 rc rb ra +or 31..25=0x75 14..12=0 11..5=5 rc rb ra +xor 31..25=0x75 14..12=0 11..5=6 rc rb ra +nor 31..25=0x75 14..12=0 11..5=7 rc rb ra + +mul 31..25=0x75 14..12=1 11..5=0 rc rb ra +mulh 31..25=0x75 14..12=1 11..5=2 rc rb ra +mulhu 31..25=0x75 14..12=1 11..5=3 rc rb ra +div 31..25=0x75 14..12=1 11..5=4 rc rb ra +divu 31..25=0x75 14..12=1 11..5=5 rc rb ra +rem 31..25=0x75 14..12=1 11..5=6 rc rb ra +remu 31..25=0x75 14..12=1 11..5=7 rc rb ra + +sllv 31..25=0x75 14..12=4 11..5=1 rc rb ra +srlv 31..25=0x75 14..12=4 11..5=2 rc rb ra +srav 31..25=0x75 14..12=4 11..5=3 rc rb ra +sll 31..25=0x75 14..12=5 11..10=0 24..20=0 rc rb shamt +srl 31..25=0x75 14..12=6 11..10=0 24..20=0 rc rb shamt +sra 31..25=0x75 14..12=7 11..10=0 24..20=0 rc rb shamt + +dadd 31..25=0x76 14..12=0 11..5=0 rc rb ra +dsub 31..25=0x76 14..12=0 11..5=1 rc rb ra + +dmul 31..25=0x76 14..12=1 11..5=0 rc rb ra +dmulh 31..25=0x76 14..12=1 11..5=2 rc rb ra +dmulhu 31..25=0x76 14..12=1 11..5=3 rc rb ra +ddiv 31..25=0x76 14..12=1 11..5=4 rc rb ra +ddivu 31..25=0x76 14..12=1 11..5=5 rc rb ra +drem 31..25=0x76 14..12=1 11..5=6 rc rb ra +dremu 31..25=0x76 14..12=1 11..5=7 rc rb ra + +dsllv 31..25=0x76 14..12=4 11..5=1 rc rb ra +dsrlv 31..25=0x76 14..12=4 11..5=2 rc rb ra +dsrav 31..25=0x76 14..12=4 11..5=3 rc rb ra +dsll 31..25=0x76 14..12=5 11..10=0 24..20=0 rc rb shamt +dsll32 31..25=0x76 14..12=5 11..10=1 24..20=0 rc rb shamt +dsrl 31..25=0x76 14..12=6 11..10=0 24..20=0 rc rb shamt +dsrl32 31..25=0x76 14..12=6 11..10=1 24..20=0 rc rb shamt +dsra 31..25=0x76 14..12=7 11..10=0 24..20=0 rc rb shamt +dsra32 31..25=0x76 14..12=7 11..10=1 24..20=0 rc rb shamt + +lb 31..25=0x78 14..12=0 rb ra imm +lh 31..25=0x78 14..12=1 rb ra imm +lw 31..25=0x78 14..12=2 rb ra imm +ld 31..25=0x78 14..12=3 rb ra imm +lbu 31..25=0x78 14..12=4 rb ra imm +lhu 31..25=0x78 14..12=5 rb ra imm +lwu 31..25=0x78 14..12=6 rb ra imm +synci 31..25=0x78 14..12=7 24..20=0 rb imm + +sb 31..25=0x79 14..12=0 rb ra imm +sh 31..25=0x79 14..12=1 rb ra imm +sw 31..25=0x79 14..12=2 rb ra imm +sd 31..25=0x79 14..12=3 rb ra imm + +l.s 31..25=0x79 14..12=4 rb ra imm +l.d 31..25=0x79 14..12=5 rb ra imm +s.s 31..25=0x79 14..12=6 rb ra imm +s.d 31..25=0x79 14..12=7 rb ra imm + +jalr.c 31..25=0x7B 19..15=0 14..12=0 11..5=0 ra rc +jalr.r 31..25=0x7B 19..15=0 14..12=0 11..5=1 ra rc +jalr.j 31..25=0x7B 19..15=0 14..12=0 11..5=2 ra rc +rdpc 31..25=0x7B 24..15=0 14..12=1 11..5=0 rc +rdhwr 31..25=0x7B 19..15=0 14..12=2 11..5=0 rc ra +sync 31..25=0x7B 24..15=0 14..12=3 11..0=0 +syscall 31..25=0x7B 24..15=0 14..12=4 11..0=0 +break 31..25=0x7B 24..15=0 14..12=5 11..0=0 + +ei 31..25=0x7E 14..12=0 19..15=0 11..0=0 ra +di 31..25=0x7E 14..12=1 19..15=0 11..0=0 ra +eret 31..25=0x7E 14..12=2 24..15=0 11..0=0 +mfc0 31..25=0x7E 14..12=4 11..0=0 ra rb +dmfc0 31..25=0x7E 14..12=5 11..0=0 ra rb +mtc0 31..25=0x7E 14..12=6 11..0=0 ra rb +dmtc0 31..25=0x7E 14..12=7 11..0=0 ra rb + +# 0x7F is reserved for 64-bit-long instructions + +add.fmt 31..25=0x68 14..12=0 11..10=0 rc rb ra fmt +sub.fmt 31..25=0x68 14..12=1 11..10=0 rc rb ra fmt +mul.fmt 31..25=0x68 14..12=2 11..10=0 rc rb ra fmt +div.fmt 31..25=0x68 14..12=3 11..10=0 rc rb ra fmt +sqrt.fmt 31..25=0x68 14..12=4 19..15=0 11..10=0 rc ra fmt +abs.fmt 31..25=0x68 14..12=5 19..15=0 11..10=0 rc ra fmt +mov.fmt 31..25=0x68 14..12=6 19..15=0 11..10=0 rc ra fmt +neg.fmt 31..25=0x68 14..12=7 19..15=0 11..10=0 rc ra fmt + +round.l.fmt 31..25=0x69 14..12=0 19..15=0 11..10=0 rc ra fmt +trunc.l.fmt 31..25=0x69 14..12=1 19..15=0 11..10=0 rc ra fmt +ceil.l.fmt 31..25=0x69 14..12=2 19..15=0 11..10=0 rc ra fmt +floor.l.fmt 31..25=0x69 14..12=3 19..15=0 11..10=0 rc ra fmt +round.w.fmt 31..25=0x69 14..12=4 19..15=0 11..10=0 rc ra fmt +trunc.w.fmt 31..25=0x69 14..12=5 19..15=0 11..10=0 rc ra fmt +ceil.w.fmt 31..25=0x69 14..12=6 19..15=0 11..10=0 rc ra fmt +floor.w.fmt 31..25=0x69 14..12=7 19..15=0 11..10=0 rc ra fmt + +mfc1 31..25=0x6A 14..12=0 11..0=0 ra rb +dmfc1 31..25=0x6A 14..12=1 11..0=0 ra rb +cfc1 31..25=0x6A 14..12=2 11..0=0 ra rb +mfhc1 31..25=0x6A 14..12=3 11..0=0 ra rb +mtc1 31..25=0x6A 14..12=4 11..0=0 ra rb +dmtc1 31..25=0x6A 14..12=5 11..0=0 ra rb +ctc1 31..25=0x6A 14..12=6 11..0=0 ra rb +mthc1 31..25=0x6A 14..12=7 11..0=0 ra rb + +cvt.s.fmt 31..25=0x6B 14..12=0 19..15=0 11..10=0 rc ra fmt +cvt.d.fmt 31..25=0x6B 14..12=1 19..15=0 11..10=0 rc ra fmt +cvt.w.fmt 31..25=0x6B 14..12=4 19..15=0 11..10=0 rc ra fmt +cvt.l.fmt 31..25=0x6B 14..12=5 19..15=0 11..10=0 rc ra fmt + +c.f.fmt 31..25=0x6C 14..12=0 11..10=0 rc rb ra fmt +c.un.fmt 31..25=0x6C 14..12=1 11..10=0 rc rb ra fmt +c.eq.fmt 31..25=0x6C 14..12=2 11..10=0 rc rb ra fmt +c.ueq.fmt 31..25=0x6C 14..12=3 11..10=0 rc rb ra fmt +c.olt.fmt 31..25=0x6C 14..12=4 11..10=0 rc rb ra fmt +c.ult.fmt 31..25=0x6C 14..12=5 11..10=0 rc rb ra fmt +c.ole.fmt 31..25=0x6C 14..12=6 11..10=0 rc rb ra fmt +c.ule.fmt 31..25=0x6C 14..12=7 11..10=0 rc rb ra fmt + +c.sf.fmt 31..25=0x6D 14..12=0 11..10=0 rc rb ra fmt +c.ngle.fmt 31..25=0x6D 14..12=1 11..10=0 rc rb ra fmt +c.seq.fmt 31..25=0x6D 14..12=2 11..10=0 rc rb ra fmt +c.ngl.fmt 31..25=0x6D 14..12=3 11..10=0 rc rb ra fmt +c.lt.fmt 31..25=0x6D 14..12=4 11..10=0 rc rb ra fmt +c.nge.fmt 31..25=0x6D 14..12=5 11..10=0 rc rb ra fmt +c.le.fmt 31..25=0x6D 14..12=6 11..10=0 rc rb ra fmt +c.ngt.fmt 31..25=0x6D 14..12=7 11..10=0 rc rb ra fmt diff --git a/parse-opcodes b/parse-opcodes index 6c735d3..e9d0249 100755 --- a/parse-opcodes +++ b/parse-opcodes @@ -4,84 +4,105 @@ import math import sys import tokenize -opcode_base = 26 -opcode_size = 6 -funct_base = 0 -funct_size = 6 +match = {} +mask = {} -nopcode = 1 << opcode_size -nfunct = 1 << funct_size -opcodes = nopcode*[None] +args = {} +args['ra'] = (24,20) +args['rb'] = (19,15) +args['rc'] = (4,0) +args['imm27'] = (26,0) +args['imm20'] = (19,0) +args['imm'] = (11,0) +args['shamt'] = (9,5) +args['fmt'] = (9,5) def binary(n, digits=0): rep = bin(n)[2:] return rep if digits == 0 else ('0' * (digits - len(rep))) + rep -def make_latex_table(opcodes, captions, labels, upper_opcode=None): - if upper_opcode is None: print '% Automatically generated by parse-opcodes' - print '\\begin{table}[h]' - print '\\begin{center}' - print '\\begin{tabular}{r|c|c|c|c|c|c|c|c|}' - cols = 8 - print '\\multicolumn{1}{r}{}&', - for i in range(cols): - print '\\multicolumn{1}{c}{%s}' % binary(i,int(math.log(cols,2))),('&' if i < cols-1 else '\\\\\n'), - print '\\cline{2-%d}' % (cols+1) - for opcode, insn in enumerate(opcodes): - if not opcode % cols: print binary(opcode/cols,int(math.log(nopcode/cols,2))),'&', - if isinstance(insn, list): - print 'Table \\ref{table:%s}' % labels[1] % {'opcode':opcode}, - else: - print ' ' if insn is None else insn, - print '&' if (opcode+1) % cols else '\\\\\\cline{2-%d}\n' % (cols+1), - print '\\end{tabular}' - print '\\end{center}' - print '\\caption{%s}' % captions[0] % {'opcode':upper_opcode} - print '\\label{table:%s}' % labels[0] % {'opcode':upper_opcode} - print '\\end{table}' - - for opcode, insn in enumerate(opcodes): - if isinstance(insn, list): - make_latex_table(insn, captions[1:], labels[1:], opcode) - -def make_disasm_table(opcodes, upper_opcode=None): - if upper_opcode is None: print '/* Automatically generated by parse-opcodes */' - for opcode, insn in enumerate(opcodes): - if isinstance(insn, list): - make_disasm_table(insn, opcode) - elif isinstance(insn, basestring): - mask = ((1 << opcode_size)-1) << opcode_base - if upper_opcode is None: - match = opcode << opcode_base - else: - mask |= ((1 << funct_size)-1) << funct_base - match = (upper_opcode << opcode_base) | (opcode << funct_base) - insn = insn.upper().replace('.','_') - print '#define MATCH_%s %s' % (insn, hex(match)) - print '#define MASK_%s %s' % (insn, hex(mask)) - -def make_switch(opcodes, upper_opcode=None): - if upper_opcode is None: print '/* Automatically generated by parse-opcodes */' - pad = '' if upper_opcode is None else ' ' - print '%sswitch(%s)' % (pad,'opcode' if upper_opcode is None else 'funct') - print '%s{' % pad - for opcode, insn in enumerate(opcodes): - if insn is None: continue - print '%s case %d:' % (pad,opcode) - print '%s {' % pad - if isinstance(insn, list): - make_switch(insn, opcode) - else: - insn = insn.lower().replace('.','_') - print '%s #include "insns/%s.h"' % (pad,insn) - print '%s }' % pad - print '%s break;' % pad - print '%s default:' % pad - print '%s {' % pad - print '%s #include "insns/unimp.h"' % pad - print '%s }' % pad - print '%s break;' % pad - print '%s }' % pad +def make_disasm_table(match,mask): + print '/* Automatically generated by parse-opcodes */' + for name,match in match.iteritems(): + name2 = name.upper().replace('.','_') + print '#define MATCH_%s %s' % (name2, hex(match)) + print '#define MASK_%s %s' % (name2, hex(mask[name])) + +def make_switch(match,mask): + opcode_base = 25 + opcode_size = 7 + funct_base = 12 + funct_size = 3 + + opcode_mask = ((1<<(opcode_base+opcode_size))-(1<<opcode_base)) + funct_mask = ((1<<(funct_base+funct_size))-(1<<funct_base)) + + print '/* Automatically generated by parse-opcodes */' + print 'switch((insn.bits >> 0x%x) & 0x%x)' % (opcode_base,(1<<opcode_size)-1) + print '{' + + for opc in range(0,1<<opcode_size): + has_some_instruction = 0 + for name in match.iterkeys(): + if ((opc << opcode_base) & mask[name]) == (match[name] & mask[name] & opcode_mask): + has_some_instruction = 1 + if not has_some_instruction: continue + + print ' case 0x%x:' % opc + print ' {' + done = 0 + for name in match.iterkeys(): + name2 = name.replace('.','_') + # case 0: opcode fully describes insn + if ((opc << opcode_base) & mask[name]) == match[name] and (opcode_mask & mask[name]) == mask[name]: + print ' #include "insns/%s.h"' % name2 + done = 1 + break + + if not done: + print ' switch((insn.bits >> 0x%x) & 0x%x)' % (funct_base,(1<<funct_size)-1) + print ' {' + for funct in range(0,1<<funct_size): + has_some_instruction = 0 + for name in match.iterkeys(): + if (opc << opcode_base | funct << funct_base) == (match[name] & (opcode_mask | funct_mask)): + has_some_instruction = 1 + if not has_some_instruction: continue + print ' case 0x%x:' % funct + print ' {' + done = 0 + for name in match.iterkeys(): + name2 = name.replace('.','_') + # case 1: opcode + funct code completely describe insn + if ((opc << opcode_base | funct << funct_base) & mask[name]) == match[name] and ((opcode_mask | funct_mask) & mask[name]) == mask[name]: + print ' #include "insns/%s.h"' % name2 + print ' break;' + done = 1 + break + if not done: + for name in match.iterkeys(): + name2 = name.replace('.','_') + # case 2: general case: opcode + funct incompletely describe insn + if (opc << opcode_base | funct << funct_base) == (match[name] & (opcode_mask | funct_mask)): + print ' if((insn.bits & 0x%x) == 0x%x)' % (mask[name],match[name]) + print ' {' + print ' #include "insns/%s.h"' % name2 + print ' break;' + print ' }' + print ' #include "insns/unimp.h"' + print ' }' + print ' default:' + print ' {' + print ' #include "insns/unimp.h"' + print ' }' + print ' }' + print ' break;' + print ' }' + print ' default:' + print ' {' + print ' #include "insns/unimp.h"' + print ' }' + print '}' for line in sys.stdin: line = line.partition('#') @@ -89,27 +110,54 @@ for line in sys.stdin: if len(tokens) == 0: continue - assert len(tokens) in [2,3] - - opcode = int(tokens[1],0) - name = tokens[0].strip() - assert opcode < nopcode - assert not isinstance(opcodes[opcode], basestring) - - if len(tokens) == 3: - funct = int(tokens[2],0) - if opcodes[opcode] is None: - opcodes[opcode] = nfunct*[None] - assert not isinstance(opcodes[opcode][funct], basestring) - opcodes[opcode][funct] = name - else: - opcodes[opcode] = name + assert len(tokens) >= 2 + + name = tokens[0] + mymatch = 0 + mymask = 0 + cover = 0 + + for token in tokens[1:len(tokens)]: + if len(token.split('=')) == 2: + tmp = token.split('=') + val = int(tmp[1],0) + if len(tmp[0].split('..')) == 2: + tmp = tmp[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(tmp[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<<lo)) + if cover & ((1<<(hi+1))-(1<<lo)): + sys.exit("%s: overspecified" % name) + cover = cover | ((1<<(hi+1))-(1<<lo)) + elif token in args: + if cover & ((1<<(args[token][0]+1))-(1<<args[token][1])): + sys.exit("%s: overspecified" % name) + cover = cover | ((1<<(args[token][0]+1))-(1<<args[token][1])) + else: + sys.exit("%s: unknown token %s" % (name,token)); + + if cover != 0xFFFFFFFF: + sys.exit("%s: not all bits are covered" % name) + + for name2,match2 in match.iteritems(): + if (match2 & mymask) == mymatch: + sys.exit("%s and %s overlap" % (name,name2)); + + mask[name] = mymask; + match[name] = mymatch; if sys.argv[1] == '-tex': make_latex_table(opcodes, ['Instructions encoded by opcode field','Instructions encoded by funct field when opcode = %(opcode)d'], ['opcodes','opcode%(opcode)d']) elif sys.argv[1] == '-disasm': - make_disasm_table(opcodes) + make_disasm_table(match,mask) elif sys.argv[1] == '-switch': - make_switch(opcodes) + make_switch(match,mask) else: assert 0 diff --git a/update-opcodes b/update-opcodes index a546d05..da603b5 100755 --- a/update-opcodes +++ b/update-opcodes @@ -1,4 +1,4 @@ #!/bin/bash -./parse-opcodes -tex < opcodes > ../doc/opcodes.tex +#./parse-opcodes -tex < opcodes > ../doc/opcodes.tex ./parse-opcodes -disasm < opcodes > ../xcc/src/include/opcode/mips-riscv-opc.h ./parse-opcodes -switch < opcodes > ../sim/riscv/execute.h |