mirror of
https://github.com/libretro/beetle-psx-libretro.git
synced 2024-11-27 02:40:31 +00:00
Get rid of these files
This commit is contained in:
parent
6800cd5c96
commit
f5bdb19385
156
decompstub.cpp
156
decompstub.cpp
@ -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;
|
||||
}
|
420
generator.py
420
generator.py
@ -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
446
insts.td
@ -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
Loading…
Reference in New Issue
Block a user