diff --git a/data/languages/xtensa.sinc b/data/languages/xtensa.sinc index 5989c96..6ebb0df 100644 --- a/data/languages/xtensa.sinc +++ b/data/languages/xtensa.sinc @@ -191,6 +191,12 @@ attach variables [ sr ] [ # 0x...0 0x...4 0x...8 0x...c ]; +define register offset=0x8400 size=4 contextreg; +define context contextreg + phase=(0,0) + loopEnd=(1,1) noflow +; + attach variables [ ar as at n_ar n_as n_at ] [ a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 ]; diff --git a/data/languages/xtensa.slaspec b/data/languages/xtensa.slaspec index 16a64f3..292e508 100644 --- a/data/languages/xtensa.slaspec +++ b/data/languages/xtensa.slaspec @@ -1,3 +1,23 @@ @include "xtensa.sinc" + +# NOTE: This is quite a big hack; a real processor will compare nextPC to LEND on every ifetch. +# As we only inject the branch-back check on addresses marked by loop insns, we may miss +# strange things like loop registers being written directly or loop registers being overwritten +# by a "nested" loop instruction. We also don't check CLOOPENABLE (PS.EXCM). +# For code that hasn't been intentially crafted for anti-analysis this should be fine. +:^instruction is phase=0 & loopEnd=1 & instruction [phase=1;] { + if (LCOUNT == 0) goto ; + LCOUNT = LCOUNT - 1; + goto [LBEG]; + + build instruction; +} + +:^instruction is phase=0 & loopEnd=0 & instruction [phase=1;] { + build instruction; +} + +with : phase=1 { @include "xtensaInstructions.sinc" @include "xtensaTodo.sinc" +} diff --git a/data/languages/xtensaTodo.sinc b/data/languages/xtensaTodo.sinc index b89eea5..c5f001e 100644 --- a/data/languages/xtensaTodo.sinc +++ b/data/languages/xtensaTodo.sinc @@ -56,11 +56,29 @@ ## Loop Option ## +macro loopSetup(as, end, doit) { + LCOUNT = as - 1; + LBEG = inst_next; + #LEND = end; + if (doit) goto ; + goto end; + +} + # LOOP - Loop, pg. 392. -:loop as, urel_16.23 is urel_16.23 & ar = 0b1000 & as & at = 0b0111 & op0 = 0b0110 unimpl +:loop as, urel_16.23 is urel_16.23 & ar=0b1000 & as & at=0b0111 & op0=0b0110 +[loopEnd=1; globalset(urel_16.23, loopEnd);] { + loopSetup(as, urel_16.23, 1:1); +} # LOOPGTZ - Loop if Greater Than Zero, pg. 394. -:loopgtz as, urel_16.23 is urel_16.23 & ar = 0b1010 & as & at = 0b0111 & op0 = 0b0110 unimpl +:loopgtz as, urel_16.23 is urel_16.23 & ar=0b1010 & as & at=0b0111 & op0=0b0110 +[loopEnd=1; globalset(urel_16.23, loopEnd);] { + loopSetup(as, urel_16.23, as s> 0); +} # LOOPNEZ - Loop if Not Equal Zero, pg. 396. -:loopnez as, urel_16.23 is urel_16.23 & ar = 0b1001 & as & at = 0b0111 & op0 = 0b0110 unimpl +:loopnez as, urel_16.23 is urel_16.23 & ar=0b1001 & as & at=0b0111 & op0=0b0110 +[loopEnd=1; globalset(urel_16.23, loopEnd);] { + loopSetup(as, urel_16.23, as != 0); +}