Get rid of these files

This commit is contained in:
twinaphex 2018-02-21 23:25:49 +01:00
parent 6800cd5c96
commit f5bdb19385
4 changed files with 0 additions and 1023 deletions

View File

@ -1,156 +0,0 @@
#include <jit/jit.h>
#include <stdint.h>
// This is passed as an array of uint32_t
typedef struct state_s {
uint32_t reg[32];
uint32_t pc;
uint32_t hi, lo;
} state_t;
bool decompile(jit_function_t func, jit_value_t state, uint32_t pc, uint32_t inst, bool &branched);
jit_value_t _make_uint(jit_function_t func, uint32_t val) {
return jit_value_create_nint_constant(func, jit_type_uint, val);
}
#define make_uint(val) _make_uint(func, (val))
jit_type_t sig_1, sig_2, sig_3;
void store_memory(int size, uint32_t ptr, uint32_t val) {
}
void call_store_memory(jit_function_t func, int size, jit_value_t ptr, jit_value_t val) {
jit_value_t args[] = {make_uint(size), ptr, val};
jit_insn_call_native(func, 0, (void *) store_memory, sig_3, args, 3, 0);
}
uint32_t load_memory(int size, uint32_t ptr) {
return 0;
}
jit_value_t call_load_memory(jit_function_t func, int size, jit_value_t ptr) {
jit_value_t args[] = {make_uint(size), ptr};
return jit_insn_call_native(func, 0, (void *) load_memory, sig_2, args, 2, 0);
}
uint32_t read_copreg(int cop, int reg) {
return 0;
}
jit_value_t call_read_copreg(jit_function_t func, int cop, int reg) {
jit_value_t args[] = {make_uint(cop), make_uint(reg)};
return jit_insn_call_native(func, 0, (void *) read_copreg, sig_2, args, 2, 0);
}
uint32_t read_copcreg(int cop, int reg) {
return 0;
}
jit_value_t call_read_copcreg(jit_function_t func, int cop, int reg) {
jit_value_t args[] = {make_uint(cop), make_uint(reg)};
return jit_insn_call_native(func, 0, (void *) read_copcreg, sig_2, args, 2, 0);
}
void write_copreg(int cop, int reg, uint32_t val) {
}
void call_write_copreg(jit_function_t func, int cop, int reg, jit_value_t val) {
jit_value_t args[] = {make_uint(cop), make_uint(reg), val};
jit_insn_call_native(func, 0, (void *) write_copreg, sig_3, args, 3, 0);
}
void write_copcreg(int cop, int reg, uint32_t val) {
}
void call_write_copcreg(jit_function_t func, int cop, int reg, jit_value_t val) {
jit_value_t args[] = {make_uint(cop), make_uint(reg), val};
jit_insn_call_native(func, 0, (void *) write_copcreg, sig_3, args, 3, 0);
}
void copfun(int cop, int cofun) {
}
jit_value_t call_copfun(jit_function_t func, int cop, int cofun) {
jit_value_t args[] = {make_uint(cop), make_uint(cofun)};
return jit_insn_call_native(func, 0, (void *) copfun, sig_2, args, 2, 0);
}
int32_t signext(int size, uint32_t imm) {
if(size == 8)
return (int32_t) ((int8_t) ((uint8_t) imm));
else if(size == 16)
return (int32_t) ((int16_t) ((uint16_t) imm));
return (int32_t) imm;
}
jit_value_t call_signext(jit_function_t func, int size, jit_value_t val) {
jit_value_t args[] = {make_uint(size), val};
return jit_insn_call_native(func, 0, (void *) signext, sig_2, args, 2, 0);
}
void syscall(int code) {
}
void call_syscall(jit_function_t func, uint32_t code) {
jit_value_t args[] = {make_uint(code)};
jit_insn_call_native(func, 0, (void *) syscall, sig_1, args, 1, 0);
}
void break_(int code) {
}
void call_break(jit_function_t func, uint32_t code) {
jit_value_t args[] = {make_uint(code)};
jit_insn_call_native(func, 0, (void *) break_, sig_1, args, 1, 0);
}
void branch(uint32_t target) {
}
void call_branch(jit_function_t func, jit_value_t val) {
jit_value_t args[] = {val};
jit_insn_call_native(func, 0, (void *) branch, sig_1, args, 1, 0);
}
void overflow(uint32_t a, uint32_t b, int dir) {
}
void call_overflow(jit_function_t func, jit_value_t a, jit_value_t b, int dir) {
jit_value_t args[] = {a, b, make_uint(dir)};
jit_insn_call_native(func, 0, (void *) overflow, sig_3, args, 3, 0);
}
jit_context_t context;
jit_type_t block_sig;
void init_decompiler() {
context = jit_context_create();
jit_context_build_start(context);
jit_type_t s3params[3];
s3params[0] = jit_type_uint;
s3params[1] = jit_type_uint;
s3params[2] = jit_type_uint;
sig_3 = jit_type_create_signature(jit_abi_cdecl, jit_type_uint, s3params, 3, 1);
jit_type_t sparams[2];
sparams[0] = jit_type_uint;
sparams[1] = jit_type_uint;
sig_2 = jit_type_create_signature(jit_abi_cdecl, jit_type_uint, sparams, 2, 1);
jit_type_t lparams[2];
lparams[0] = jit_type_uint;
sig_1 = jit_type_create_signature(jit_abi_cdecl, jit_type_uint, lparams, 1, 1);
jit_type_t params[1];
params[0] = jit_type_create_pointer(jit_type_uint, 0);
block_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 1, 1);
}
jit_function_t create_function() {
auto func = jit_function_create(context, signature);
auto statevar = jit_value_get_param(func, 0);
decompile(func, statevar, 0xDEADBEE0, 0x0, branched);
return 0;
}

View File

@ -1,420 +0,0 @@
import json, re, struct
import os.path
from tblgen import interpret, Dag, TableGenBits
def dag2expr(dag):
def clean(value):
if isinstance(value, tuple) and len(value) == 2 and value[0] == 'defref':
return value[1]
return value
def sep((name, value)):
if name is None:
return clean(value)
return name
if isinstance(dag, Dag):
return [dag2expr(sep(elem)) for elem in dag.elements]
else:
return dag
if not os.path.exists('insts.td.cache') or os.path.getmtime('insts.td') > os.path.getmtime('insts.td.cache'):
insts = interpret('insts.td').deriving('BaseInst')
ops = []
for name, (bases, data) in insts:
ops.append((name, bases[1], data['Opcode'][1], data['Function'][1] if 'Function' in data else None, data['Disasm'][1], dag2expr(data['Eval'][1])))
with file('insts.td.cache', 'w') as fp:
json.dump(ops, fp)
else:
ops = json.load(file('insts.td.cache'))
toplevel = {}
for name, type, op, funct, dasm, dag in ops:
if funct is None:
assert op not in toplevel
toplevel[op] = name, type, dasm, dag
else:
if op not in toplevel:
toplevel[op] = [type, {}]
toplevel[op][1][funct] = name, type, dasm, dag
def generate(gfunc):
switch = []
for op, body in toplevel.items():
if isinstance(body, list):
type, body = body
subswitch = []
for funct, sub in body.items():
subswitch.append(('case', funct, gfunc(sub)))
if type == 'CFType':
when = ('&', ('>>', 'inst', 21), 0x1F)
elif type == 'RIType':
when = ('&', ('>>', 'inst', 16), 0x1F)
else:
when = ('&', 'inst', 0x3F)
switch.append(('case', op, ('switch', when, subswitch)))
else:
switch.append(('case', op, gfunc(body)))
return ('switch', ('>>', 'inst', 26), switch)
def indent(str, single=True):
if single and '\n' not in str:
return ' %s ' % str
else:
return '\n%s\n' % '\n'.join('\t' + x for x in str.split('\n'))
def output(expr, top=True):
if isinstance(expr, list):
return '\n'.join(output(x, top=top) for x in expr)
elif isinstance(expr, int) or isinstance(expr, long):
return '0x%x' % expr
elif isinstance(expr, str) or isinstance(expr, unicode):
expr = expr.replace('$', '')
return expr
op = expr[0]
if op == 'switch':
return 'switch(%s) {%s}' % (output(expr[1]), indent(output(expr[2])))
elif op == 'case':
return 'case %s: {%s\tbreak;\n}' % (output(expr[1]), indent(output(expr[2]), single=False))
elif op in ('+', '-', '*', '/', '%', '<<', '>>', '>>', '&', '|', '^', '==', '!=', '<', '<=', '>', '>='):
return '(%s) %s (%s)' % (output(expr[1], top=False), op, output(expr[2], top=False))
elif op == '!':
return '!(%s)' % output(expr[1], top=False)
elif op == '=':
lval = output(expr[1], top=False)
type = ''
if lval != 'branched':
type = 'uint32_t '
return '%s%s %s %s;' % (type, lval, op, output(expr[2], top=False))
elif op == 'if':
return 'if(%s) {%s} else {%s}' % (output(expr[1], top=False), indent(output(expr[2]), single=False), indent(output(expr[3]), single=False))
elif op == 'when':
return 'if(%s) {%s}' % (output(expr[1], top=False), indent(output(expr[2])))
elif op == 'comment':
return '/*%s*/' % indent(output(expr[1]))
elif op == 'str':
return `str(expr[1])`
elif op == 'index':
return '(%s)[%s]' % (output(expr[1], top=False), output(expr[2], top=False))
elif op == 'emit':
return '\n'.join(flatten(emitter(expr[1])))
elif op in gops:
return output(gops[op](*expr[1:]))
elif op == 'zeroext':
return output(expr[1])
else:
return '%s(%s)%s' % (op, ', '.join(output(x, top=False) for x in expr[1:]), ';' if top else '')
def flatten(x):
if isinstance(x, list) or isinstance(x, tuple):
return reduce(lambda a, b: a+b, map(flatten, x))
else:
return [x]
gops = {
'add' : lambda a, b: ('+', a, b),
'sub' : lambda a, b: ('-', a, b),
'and' : lambda a, b: ('&', a, b),
'or' : lambda a, b: ('|', a, b),
'nor' : lambda a, b: ('~', ('|', a, b)),
'xor' : lambda a, b: ('^', a, b),
'mul' : lambda a, b: ('*', a, b),
'div' : lambda a, b: ('/', a, b),
'mod' : lambda a, b: ('%', a, b),
'shl' : lambda a, b: ('<<', a, b),
'shra' : lambda a, b: ('>>', ('signed', a), ('signed', b)),
'shrl' : lambda a, b: ('>>', a, b),
'eq' : lambda a, b: ('==', a, b),
'ge' : lambda a, b: ('>=', a, b),
'gt' : lambda a, b: ('>', a, b),
'le' : lambda a, b: ('<=', a, b),
'lt' : lambda a, b: ('<', a, b),
'neq' : lambda a, b: ('!=', a, b),
}
eops = {
'add' : lambda a, b: ('jit_insn_add', a, b),
'sub' : lambda a, b: ('jit_insn_sub', a, b),
'and' : lambda a, b: ('jit_insn_and', a, b),
'or' : lambda a, b: ('jit_insn_or', a, b),
'nor' : lambda a, b: ('jit_insn_not', ('jit_insn_or', a, b)),
'xor' : lambda a, b: ('jit_insn_xor', a, b),
'mul' : lambda a, b: ('jit_insn_mul', a, b), # XXX: This needs to be a 64-bit mul!
'div' : lambda a, b: ('jit_insn_div', a, b),
'mod' : lambda a, b: ('jit_insn_rem', a, b),
'shl' : lambda a, b: ('jit_insn_shl', a, b),
'shra' : lambda a, b: ('jit_insn_sshr', a, b),
'shrl' : lambda a, b: ('jit_insn_ushr', a, b),
'eq' : lambda a, b: ('jit_insn_eq', a, b),
'ge' : lambda a, b: ('jit_insn_ge', a, b),
'gt' : lambda a, b: ('jit_insn_gt', a, b),
'le' : lambda a, b: ('jit_insn_le', a, b),
'lt' : lambda a, b: ('jit_insn_lt', a, b),
'neq' : lambda a, b: ('jit_insn_ne', a, b),
}
def cleansexp(sexp):
if isinstance(sexp, list):
return [cleansexp(x) for x in sexp if x != []]
elif isinstance(sexp, tuple):
return tuple([cleansexp(x) for x in sexp if x != []])
else:
return sexp
def find_deps(dag):
if isinstance(dag, str) or isinstance(dag, unicode):
return set([dag])
elif not isinstance(dag, list):
return set()
return reduce(lambda a, b: a|b, map(find_deps, dag[1:])) if len(dag) != 1 else set()
def decoder(code, vars, type, dag):
def decl(name, val):
if name in deps:
vars.append(name)
code.append(('=', name, val))
deps = find_deps(dag)
if type == 'IType' or type == 'RIType':
decl('$rs', ('&', ('>>', 'inst', 21), 0x1F))
decl('$rt', ('&', ('>>', 'inst', 16), 0x1F))
decl('$imm', ('&', 'inst', 0xFFFF))
elif type == 'JType':
decl('$imm', ('&', 'inst', 0x3FFFFFF))
elif type == 'RType':
decl('$rs', ('&', ('>>', 'inst', 21), 0x1F))
decl('$rt', ('&', ('>>', 'inst', 16), 0x1F))
decl('$rd', ('&', ('>>', 'inst', 11), 0x1F))
decl('$shamt', ('&', ('>>', 'inst', 6), 0x1F))
elif type == 'SType':
decl('$code', ('&', ('>>', 'inst', 6), 0x0FFFFF))
elif type == 'CFType':
decl('$cop', ('&', ('>>', 'inst', 26), 3))
decl('$rt', ('&', ('>>', 'inst', 16), 0x1F))
decl('$rd', ('&', ('>>', 'inst', 11), 0x1F))
decl('$cofun', ('&', 'inst', 0x01FFFFFF))
else:
print 'Unknown instruction type:', type
assert False
debug = False
def dlog(dag, code, pos):
if dag[0] == 'gpr':
name = ('regname', dag[1])
elif dag[0] == 'copreg':
name = '+', ('+', ('+', ('str', 'cop'), dag[1]), ('str', ' reg ')), dag[2]
elif dag[0] == 'copcreg':
name = '+', ('+', ('+', ('str', 'cop'), dag[1]), ('str', ' control reg ')), dag[2]
elif dag[0] in ('hi', 'lo', 'pc'):
name = dag[0]
elif dag[0] == 'store':
name = '>>', dag[1], 0
else:
print 'Unknown dag to dlog:', dag
return ('phex32', name, ('str', pos + ':'), code, ('str', 'uint:'), ('>>', code, 0))
temp_i = 0
def tempname():
global temp_i
temp_i += 1
return 'temp_%i' % temp_i
def to_val(val):
if val.startswith('jit_') or val.startswith('call_'):
return val
return 'jit_value_create_nint_constant(func, jit_type_uint, %s)' % val
def emitter(sexp, storing=False):
if isinstance(sexp, list):
if len(sexp) == 1:
sexp = sexp[0]
else:
return '/* Unhandled list */'
if isinstance(sexp, str) or isinstance(sexp, unicode):
return sexp.replace('$', '')
elif isinstance(sexp, int):
if sexp >= 0:
return '0x%x' % sexp
else:
return '-0x%x' % -sexp
op = sexp[0]
if op == '=':
lvalue = sexp[1]
if isinstance(lvalue, list) and len(lvalue) == 1:
lvalue = lvalue[0]
if lvalue[0] == 'reg':
return 'jit_insn_store_relative(func, jit_insn_add(func, state, jit_insn_mul(func, %s, %s)), 0, %s);' % (to_val(emitter(lvalue[1])), to_val('4'), to_val(emitter(sexp[2])))
elif lvalue[0] == 'pc':
return 'jit_insn_store_relative(func, state, 32*4, %s);' % to_val(emitter(sexp[2]))
elif lvalue[0] == 'hi':
return 'jit_insn_store_relative(func, state, 33*4, %s);' % to_val(emitter(sexp[2]))
elif lvalue[0] == 'lo':
return 'jit_insn_store_relative(func, state, 34*4, %s);' % to_val(emitter(sexp[2]))
elif lvalue[0] == 'copreg':
return 'call_write_copreg(func, %s, %s, %s);' % (emitter(lvalue[1]), emitter(lvalue[2]), to_val(emitter(sexp[2])))
elif lvalue[0] == 'copcreg':
return 'call_write_copcreg(func, %s, %s, %s);' % (emitter(lvalue[1]), emitter(lvalue[2]), to_val(emitter(sexp[2])))
else:
print 'Unknown lvalue', lvalue
raise False
elif op == 'reg':
return 'jit_insn_load_relative(func, jit_insn_add(func, state, jit_insn_mul(func, %s, %s)), 0, jit_type_uint)' % (to_val(emitter(sexp[1])), to_val('4'))
elif op == 'pc':
return 'jit_insn_load_relative(func, state, 32*4, jit_type_uint)'
elif op == 'hi':
return 'jit_insn_load_relative(func, state, 33*4, jit_type_uint)'
elif op == 'lo':
return 'jit_insn_load_relative(func, state, 34*4, jit_type_uint)'
elif op == 'copreg':
return 'call_read_copreg(func, %s, %s)' % (emitter(sexp[1]), emitter(sexp[2]))
elif op == 'copcreg':
return 'call_read_copcreg(func, %s, %s)' % (emitter(sexp[1]), emitter(sexp[2]))
elif op == 'branch':
return 'call_branch(func, %s);' % (to_val(emitter(sexp[1])))
elif op == 'syscall':
return 'call_syscall(func, %s);' % (emitter(sexp[1]))
elif op == 'break_':
return 'call_break(func, %s);' % (emitter(sexp[1]))
elif op == 'copfun':
return 'call_copfun(func, %s, %s);' % (emitter(sexp[1]), emitter(sexp[2]))
elif op == 'emit':
return emitter(sexp[1], storing=storing)
elif op == 'store':
return 'call_store_memory(func, %i, %s, %s);' % (sexp[1], to_val(emitter(sexp[2])), to_val(emitter(sexp[3])))
elif op == 'load':
return 'call_load_memory(func, %i, %s)' % (sexp[1], to_val(emitter(sexp[2])))
elif op == 'if':
temp = tempname()
end = tempname()
return [
'jit_label_t %s = jit_label_undefined, %s = jit_label_undefined;' % (temp, end),
'jit_insn_branch_if(func, %s, &%s);' % (to_val(emitter(sexp[1])), temp),
emitter(sexp[2]),
'jit_insn_branch(func, &%s);' % end,
'jit_insn_label(func, &%s);' % temp,
emitter(sexp[3]),
'jit_insn_label(func, &%s);' % end,
]
elif op == 'when':
temp = tempname()
return [
'jit_label_t %s = jit_label_undefined;' % temp,
'jit_insn_branch_if_not(func, %s, &%s);' % (to_val(emitter(sexp[1])), temp),
emitter(sexp[2]),
'jit_insn_label(func, &%s);' % temp
]
elif op == 'overflow':
if sexp[1][0] == 'add':
return 'call_overflow(func, %s, %s, 1);' % (to_val(emitter(sexp[1][1])), to_val(emitter(sexp[1][2])))
else:
return 'call_overflow(func, %s, %s, -1);' % (to_val(emitter(sexp[1][1])), to_val(emitter(sexp[1][2])))
elif op == 'zeroext':
return emitter(sexp[2], storing=storing)
elif op == 'signext':
return 'call_signext(func, %i, %s)' % (sexp[1], emitter(sexp[2], storing=storing))
elif op in eops:
return emitter(eops[op](*sexp[1:]), storing=storing)
elif op.startswith('jit_'):
return '%s(func, %s)' % (op, ', '.join([to_val(emitter(x, storing=storing)) for x in sexp[1:]]))
else:
print 'Unknown', sexp
return ''
def genDecomp((name, type, dasm, dag)):
code = [('comment', name), ('emit', ('=', ('pc', ), '$pc'))]
vars = []
decoder(code, vars, type, dag)
has_branch = [False]
def subgen(dag):
if isinstance(dag, str) or isinstance(dag, unicode):
return dag
elif isinstance(dag, int) or isinstance(dag, long):
return dag
elif not isinstance(dag, list):
print 'Fail', dag
assert False
op = dag[0]
if op in ('let', 'rlet'):
if dag[1] not in vars:
vars.append(dag[1])
ret = [('=', dag[1], subgen(dag[2]))] + subgen(['block'] + dag[3:])
if op == 'rlet':
return [('emit', ret)]
else:
return ret
elif op == 'set':
left = dag[1]
leftjs = subgen(left)
ret = [('emit', ('=', leftjs, subgen(dag[2])))]
if left[0] == 'gpr':
ret = [('when', ('neq', left[1], 0), ret)]
return ret
# XXX: Conditionals should detect if they can happen at decompile-time
elif op == 'if':
return [('emit', ('if', subgen(dag[1]), subgen(dag[2]), subgen(dag[3])))]
elif op == 'when':
return [('emit', ('when', subgen(dag[1]), subgen(dag[2])))]
elif op in gops:
return tuple(map(subgen, dag))
elif op in ('signext', 'zeroext'):
return (op, dag[1], subgen(dag[2]))
elif op == 'pc':
return ['$pc']
elif op in ('hi', 'lo'):
return [(op, )]
elif op == 'pcd':
return [('add', '$pc', 4)] # Return the delay slot position
elif op == 'gpr':
return ('reg', subgen(dag[1]))
elif op == 'copreg':
return ('copreg', subgen(dag[1]), subgen(dag[2]))
elif op == 'copcreg':
return ('copcreg', subgen(dag[1]), subgen(dag[2]))
elif op == 'block':
return list(map(subgen, dag[1:]))
elif op == 'unsigned':
return subgen(dag[1])
elif op == 'signed':
return subgen(dag[1])
elif op == 'check_overflow':
return [('emit', ('overflow', subgen(dag[1])))]
elif op == 'raise':
return [('emit', ('raise', dag[1]))]
elif op == 'break':
return [('emit', ('break_', dag[1]))]
elif op == 'syscall':
return [('emit', ('syscall', dag[1]))]
elif op == 'branch':
has_branch[0] = True
return [('emit', ('branch', subgen(dag[1]), 'true'))]
elif op == 'load':
return [('load', dag[1], subgen(dag[2]))]
elif op == 'store':
return [('emit', ('store', dag[1], subgen(dag[2]), subgen(dag[3])))]
elif op == 'copfun':
return [('emit', ('copfun', subgen(dag[1]), subgen(dag[2])))]
else:
print 'Unknown op:', op
return []
code += cleansexp(subgen(dag))
if has_branch[0]:
code.append(('=', 'branched', 'true'))
code.append(('return', 'true'))
return code
def build():
print 'Rebuilding from tables'
with file('mednafen/psx/decomp.cpp', 'w') as fp:
print >>fp, '/* Autogenerated from insts.td. DO NOT EDIT */'
print >>fp, file('decompstub.cpp', 'r').read()
print >>fp, 'bool decompile(jit_function_t func, jit_value_t state, uint32_t pc, uint32_t inst, bool &branched) {%s\treturn false;\n}' % indent(output(generate(genDecomp)))
if __name__=='__main__':
build()

446
insts.td
View File

@ -1,446 +0,0 @@
class DagOp;
def add : DagOp;
def sub : DagOp;
def and : DagOp;
def or : DagOp;
def nor : DagOp;
def xor : DagOp;
def mul : DagOp; // word * word -> dword
def div : DagOp; // word / word -> word
def mod : DagOp; // word % word -> word
def shl : DagOp;
def shra : DagOp;
def shrl : DagOp;
def signext : DagOp;
def zeroext : DagOp;
def eq : DagOp;
def ge : DagOp;
def gt : DagOp;
def le : DagOp;
def lt : DagOp;
def neq : DagOp;
def branch : DagOp;
def copreg : DagOp;
def copcreg : DagOp;
def gpr : DagOp;
def hi : DagOp;
def lo : DagOp;
def check_overflow : DagOp;
def pcd : DagOp;
def raise : DagOp;
def load : DagOp;
def store : DagOp;
def block : DagOp;
def if : DagOp;
def let : DagOp;
def rlet: DagOp;
def set : DagOp;
def when : DagOp;
def unsigned : DagOp;
def signed : DagOp;
// Special traps
def break : DagOp;
def syscall : DagOp;
def copfun : DagOp;
class Exception;
def ArithmeticOverflow : Exception;
class BaseInst<bits<6> op, string disasm, dag eval> {
bits<6> Opcode = op;
string Disasm = disasm;
dag Eval = eval;
}
class IType<bits<6> op, string disasm, dag eval> : BaseInst<op, disasm, eval> {
// 31-26: op
// 25-21: rs
// 20-16: rt
// 15-0: imm
}
class RIType<bits<6> op, bits<5> funct, string disasm, dag eval> : BaseInst<op, disasm, eval> {
// 31-26: op
// 25-21: rs
// 20-16: funct
// 15-0: imm
bits<5> Function = funct;
}
class JType<bits<6> op, string disasm, dag eval> : BaseInst<op, disasm, eval> {
// 31-26: op
// 25-0: imm
}
class RType<bits<6> funct, string disasm, dag eval> : BaseInst<0b000000, disasm, eval> {
// 31-26: op
// 25-21: rs
// 20-16: rt
// 15-11: rd
// 10-6: shamt
// 5-0: funct
bits<6> Function = funct;
}
class SType<bits<6> funct, string disasm, dag eval> : BaseInst<0b000000, disasm, eval> {
// 31-26: op
// 25-6: code
// 5-0: funct
bits<6> Function = funct;
}
class CFType<bits<6> op, bits<5> funct, string disasm, dag eval> : BaseInst<op, disasm, eval> {
// 31-26: op
// 27-26: cop
// 25-21: funct
// 20-16: rt
// 15-11: rd
// 24-0: cofun
bits<5> Function = funct;
}
multiclass CFDef<bits<6> op, bits<5> funct, string disasm, dag eval> {
def : CFType<!add(op, 0b000000), funct, disasm, eval>;
def : CFType<!add(op, 0b000001), funct, disasm, eval>;
def : CFType<!add(op, 0b000010), funct, disasm, eval>;
def : CFType<!add(op, 0b000011), funct, disasm, eval>;
}
def ADD : RType<0b100000, "add %$rd, %$rs, %$rt",
(block
(check_overflow (add (gpr $rs), (gpr $rt))),
(set (gpr $rd), (add (gpr $rs), (gpr $rt))))
>;
def ADDI : IType<0b001000, "addi %$rt, %$rs, $eimm",
(let $eimm, (signext 16, $imm),
(block
(check_overflow (add (gpr $rs), $eimm)),
(set (gpr $rt), (add (gpr $rs), $eimm))))
>;
def ADDIU : IType<0b001001, "addiu %$rt, %$rs, $eimm",
(let $eimm, (signext 16, $imm),
(set (gpr $rt), (add (gpr $rs), $eimm)))
>;
def ADDU : RType<0b100001, "addu %$rd, %$rs, %$rt",
(set (gpr $rd), (add (gpr $rs), (gpr $rt)))
>;
def AND : RType<0b100100, "and %$rd, %$rs, %$rt",
(set (gpr $rd), (and (gpr $rs), (gpr $rt)))
>;
def ANDI : IType<0b001100, "andi %$rt, %$rs, $eimm",
(let $eimm, (zeroext 16, $imm),
(set (gpr $rt), (and (gpr $rs), $eimm)))
>;
def BEQ : IType<0b000100, "beq %$rs, %$rt, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (eq (unsigned (gpr $rs)), (unsigned (gpr $rt))),
(branch $target)))
>;
def BGEZ : RIType<0b000001, 0b00001, "bgez %$rs, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (ge (signed (gpr $rs)), 0),
(branch $target)))
>;
def BGEZAL : RIType<0b000001, 0b10001, "bgezal %$rs, $target",
(block
(set (gpr 31), (pcd)),
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (ge (signed (gpr $rs)), 0),
(branch $target))))
>;
// This isn't really RIType, but that lets us constrain rt
def BGTZ : RIType<0b000111, 0b00000, "bgtz %$rs, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (gt (signed (gpr $rs)), 0),
(branch $target)))
>;
// This isn't really RIType, but that lets us constrain rt
def BLEZ : RIType<0b000110, 0b00000, "blez %$rs, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (le (signed (gpr $rs)), 0),
(branch $target)))
>;
def BLTZ : RIType<0b000001, 0b00000, "bltz %$rs, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (lt (signed (gpr $rs)), 0),
(branch $target)))
>;
def BLTZAL : RIType<0b000001, 0b10000, "bltzal %$rs, $target",
(block
(set (gpr 31), (pcd)),
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (lt (signed (gpr $rs)), 0),
(branch $target))))
>;
def BNE : IType<0b000101, "bne %$rs, %$rt, $target",
(let $target, (add (pcd), (signext 18, (shl $imm, 2))),
(when (neq (gpr $rs), (gpr $rt)),
(branch $target)))
>;
def BREAK : SType<0b001101, "break $code",
(break $code)
>;
defm CFCz : CFDef<0b010000, 0b00010, "cfc$cop %$rt, $rd",
(set (gpr $rt), (copcreg $cop, $rd))
>;
// HACK! This should be special cased.
multiclass COPzType<string disasm, dag eval> {
defm : CFDef<0b010000, 0b10000, disasm, eval>;
defm : CFDef<0b010000, 0b10001, disasm, eval>;
defm : CFDef<0b010000, 0b10010, disasm, eval>;
defm : CFDef<0b010000, 0b10011, disasm, eval>;
defm : CFDef<0b010000, 0b10100, disasm, eval>;
defm : CFDef<0b010000, 0b10101, disasm, eval>;
defm : CFDef<0b010000, 0b10110, disasm, eval>;
defm : CFDef<0b010000, 0b10111, disasm, eval>;
defm : CFDef<0b010000, 0b11000, disasm, eval>;
defm : CFDef<0b010000, 0b11001, disasm, eval>;
defm : CFDef<0b010000, 0b11010, disasm, eval>;
defm : CFDef<0b010000, 0b11011, disasm, eval>;
defm : CFDef<0b010000, 0b11100, disasm, eval>;
defm : CFDef<0b010000, 0b11101, disasm, eval>;
defm : CFDef<0b010000, 0b11110, disasm, eval>;
defm : CFDef<0b010000, 0b11111, disasm, eval>;
}
defm COPz : COPzType<"cop$cop $cofun",
(copfun $cop, $cofun)
>;
defm CTCz : CFDef<0b010000, 0b00110, "ctc$cop %$rt, $rd",
(set (copcreg $cop, $rd), (gpr $rt))
>;
def DIV : RType<0b011010, "div %$rs, %$rt",
(block
(set (lo), (div (gpr $rs), (gpr $rt))),
(set (hi), (mod (gpr $rs), (gpr $rt))))
>;
def DIVU : RType<0b011011, "divu %$rs, %$rt",
(block
(set (lo), (div (unsigned (gpr $rs)), (unsigned (gpr $rt)))),
(set (hi), (mod (unsigned (gpr $rs)), (unsigned (gpr $rt)))))
>;
def J : JType<0b000010, "j $target",
(let $target, (add (and (pcd), 0xF0000000), (zeroext 28, (shl $imm, 2))),
(branch $target))
>;
def JAL : JType<0b000011, "jal $target",
(block
(set (gpr 31), (add (pcd), 4)),
(let $target, (add (and (pcd), 0xF0000000), (zeroext 28, (shl $imm, 2))),
(branch $target)))
>;
def JALR : RType<0b001001, "jalr %$rd, %$rs",
(block
(set (gpr $rd), (add (pcd), 4)),
(branch (unsigned (gpr $rs))))
>;
def JR : RType<0b001000, "jr %$rs",
(branch (unsigned (gpr $rs)))
>;
def LB : IType<0b100000, "lb %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(set (gpr $rt), (signext 8, (load 8, (unsigned (add (gpr $rs), $offset))))))
>;
def LBU : IType<0b100100, "lbu %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(set (gpr $rt), (zeroext 8, (load 8, (unsigned (add (gpr $rs), $offset))))))
>;
def LH : IType<0b100001, "lh %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(set (gpr $rt), (signext 16, (load 16, (unsigned (add (gpr $rs), $offset))))))
>;
def LHU : IType<0b100101, "lhu %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(set (gpr $rt), (zeroext 16, (load 16, (add (gpr $rs), $offset)))))
>;
def LUI : IType<0b001111, "lui %$rt, $imm",
(set (gpr $rt), (shl $imm, 16))
>;
def LW : IType<0b100011, "lw %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(set (gpr $rt), (load 32, (unsigned (add (gpr $rs), $offset)))))
>;
// XXX: LWCz instruction
// XXX: LWL instruction
// XXX: LWR instruction
defm MFCz : CFDef<0b010000, 0b00000, "mfc$cop %$rt, $rd",
(set (gpr $rt), (copreg $cop, $rd))
>;
def MFHI : RType<0b010000, "mfhi %$rd",
(set (gpr $rd), (hi))
>;
def MFLO : RType<0b010010, "mflo %$rd",
(set (gpr $rd), (lo))
>;
defm MTCz : CFDef<0b010000, 0b00100, "mtc$cop %$rt, $rd",
(set (copreg $cop, $rd), (gpr $rt))
>;
def MTHI : RType<0b010001, "mthi %$rd",
(set (hi), (gpr $rd))
>;
def MTLO : RType<0b010011, "mtlo %$rd",
(set (lo), (gpr $rd))
>;
def MULT : RType<0b011000, "mult %$rs, %$rt",
(rlet $_t, (mul (gpr $rs), (gpr $rt)),
(set (lo), (and $_t, 0xFFFFFFFF)),
(set (hi), (shrl $_t, 32)))
>;
def MULTU : RType<0b011001, "multu %$rs, %$rt",
(rlet $_t, (mul (unsigned (gpr $rs)), (unsigned (gpr $rt))),
(set (lo), (and $_t, 0xFFFFFFFF)),
(set (hi), (shrl $_t, 32)))
>;
def NOR : RType<0b100111, "nor %$rd, %$rs, %$rt",
(set (gpr $rd), (nor (gpr $rs), (gpr $rt)))
>;
def OR : RType<0b100101, "or %$rd, %$rs, %$rt",
(set (gpr $rd), (or (gpr $rs), (gpr $rt)))
>;
def ORI : IType<0b001101, "ori %$rt, %$rs, $eimm",
(let $eimm, (zeroext 16, $imm),
(set (gpr $rt), (or (gpr $rs), $eimm)))
>;
def SB : IType<0b101000, "sb %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(store 8, (unsigned (add (gpr $rs), $offset)), (gpr $rt)))
>;
def SH : IType<0b101001, "sh %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(store 16, (unsigned (add (gpr $rs), $offset)), (gpr $rt)))
>;
def SLL : RType<0b000000, "sll %$rd, %$rt, $shamt",
(set (gpr $rd), (shl (gpr $rt), $shamt))
>;
def SLLV : RType<0b000100, "sllv %$rd, %$rt, %$rs",
(set (gpr $rd), (shl (gpr $rt), (gpr $rs)))
>;
def SLT : RType<0b101010, "slt %$rd, %$rs, %$rt",
(if (lt (signed (gpr $rs)), (signed (gpr $rt))),
(set (gpr $rd), 1),
(set (gpr $rd), 0))
>;
def SLTI : IType<0b001010, "slti %$rt, %$rs, $eimm",
(let $eimm, (signext 16, $imm),
(if (lt (signed (gpr $rs)), $eimm),
(set (gpr $rt), 1),
(set (gpr $rt), 0)))
>;
def SLTIU : IType<0b001011, "sltiu %$rt, %$rs, $eimm",
(let $eimm, (unsigned (signext 16, $imm)),
(if (lt (unsigned (gpr $rs)), $eimm),
(set (gpr $rt), 1),
(set (gpr $rt), 0)))
>;
def SLTU : RType<0b101011, "sltu %$rd, %$rs, %$rt",
(if (lt (unsigned (gpr $rs)), (unsigned (gpr $rt))),
(set (gpr $rd), 1),
(set (gpr $rd), 0))
>;
def SRA : RType<0b000011, "sra %$rd, %$rt, $shamt",
(set (gpr $rd), (shra (gpr $rt), $shamt))
>;
def SRAV : RType<0b000111, "srav %$rd, %$rt, $shamt",
(set (gpr $rd), (shra (gpr $rt), (gpr $rs)))
>;
def SRL : RType<0b000010, "srl %$rd, %$rt, $shamt",
(set (gpr $rd), (shrl (gpr $rt), $shamt))
>;
def SRLV : RType<0b000110, "srlv %$rd, %$rt, $shamt",
(set (gpr $rd), (shrl (gpr $rt), (gpr $rs)))
>;
def SUB : RType<0b100010, "sub %$rd, %$rs, %$rt",
(block
(check_overflow (sub (gpr $rs), (gpr $rt))),
(set (gpr $rd), (sub (gpr $rs), (gpr $rt))))
>;
def SUBU : RType<0b100011, "subu %$rd, %$rs, %$rt",
(set (gpr $rd), (sub (gpr $rs), (gpr $rt)))
>;
def SW : IType<0b101011, "sw %$rt, $offset(%$rs)",
(let $offset, (signext 16, $imm),
(store 32, (unsigned (add (gpr $rs), $offset)), (gpr $rt)))
>;
// XXX: SWCz instruction
// XXX: SWL instruction
// XXX: SWR instruction
def SYSCALL : SType<0b001100, "syscall $code",
(syscall $code)
>;
def XOR : RType<0b100110, "xor %$rd, %$rs, %$rt",
(set (gpr $rd), (xor (gpr $rs), (gpr $rt)))
>;
def XORI : IType<0b001110, "xori %$rt, %$rs, $eimm",
(let $eimm, (zeroext 16, $imm),
(set (gpr $rt), (xor (gpr $rs), $eimm)))
>;

File diff suppressed because one or more lines are too long