Skip to content

Instantly share code, notes, and snippets.

@eddyb
Created November 18, 2012 20:41
Show Gist options
  • Select an option

  • Save eddyb/4107305 to your computer and use it in GitHub Desktop.

Select an option

Save eddyb/4107305 to your computer and use it in GitHub Desktop.
macro _ {
case ( $def:lit ( $vars ... ) $ret ) => {
dis.op($def, function() {var $vars ...; return $ret;})
}
case ( $def:lit $ret ) => {
dis.op($def, function() {return $ret;})
}
}
var dis = require('./DAR4');
eval(dis.exportFn('dis'));
[
['And', 1], ['Xor', 1], ['Sub', 0], ['rsb', 0, function(a, b) {return Sub(b, a);}],
['Add', 0],
['adc', 0, function(a, b) {return Add(a, Add(b, R.C));}],
['sbc', 0, function(a, b) {return Sub(a, Add(Sub(b, R.C), 1));}],
['rsc', 0, function(a, b) {return Sub(b, Add(Sub(a, R.C), 1));}],
['tst', 1|2, And], ['teq', 1|2, Xor], ['cmp', 0|2, Sub], ['cmn', 0|2, Add],
['orr', 1, Or],
['mov', 1, function(a, b) {return b;}],
['bic', 1, function(a, b) {return And(a, Not(b));}],
['mvn', 1, function(a, b) {return Not(b);}]
].forEach(function(op, i) {
var name = op[0].toLowerCase(), fn = op[2] || eval(op[0]), code = i.toString(2);
var logical = op[1]&1, test = op[1]&2;
while(code.length < 4)
code = '0'+code;
dis.op('00I'+code+'SRn__Rd__Immrot$regsh', function(I, S, Rn, Rd, Immrot$regsh) {
if(test && !S)
return;
var v = fn(Rn, Immrot$regsh), r = [name];
if(!test)
r.push(Mov(Rd, v));
if(S) {
if(logical) {
// TODO C <- shifter carry.
} else {
// TODO V <- sign bit overflow (what exactly?).
// TODO C <- ALU carry.
}
r.push(Mov(R.Z, Eq(v, 0)), Mov(R.N, SignBit(v)));
}
return r;
});
// TODO Rd=15 S=1 - instead of changing flags, it does CPSR <- SPSR
});
// mul mla
_('000000ASRd__Rn__Rs__1001Rm__'(m = Mul(Rn, Rm))
[A?'mla':'mul', Mov(Rd, Add(A&&Rd, m)), S&&Mov(R.Z, Eq(m, 0)), S&&Mov(R.N, SignBit(m))])
// swp
// FIXME this is actually wrong, swp doesn't work that way.
// NOTE it's deprecated anyway in ARMv6 or so.
//_('00010B00Rn__Rd__00001001Rm__'
// ['swp'+(B?'b':''), Swap(Mem(Add(Rn, Rd), B&&1), Mem(Add(Rn, Rm), B&&1))])
// ldr str
_('01IPUBWLRn__Rd__Imm$regshift'(a = (U?Add:Sub)(Rn, Imm$regshift), m = Mem(P?a:Rn, B&&1))
((P||!W)&&[(L?'ldr':'str')+(B?'b':''), L?Mov(Rd, m):Mov(m, Rd), (W||!P)&&Mov(Rn, a)]))
// b bl
_('101LO_______________________'
[L?'bl':'b', L&&Mov(R.lr, R.pc), Mov(R.pc, Add(R.pc, SignExt(LSL(O, 2))))])
// swi
_('1111Comment_________________'
['swi', Interrupt(Comment)])
dis.out('arm.js', 'arm.out.js');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment