From b5d772d98d2fe886781c7c934824ce7cc3b5b6e3 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 1 Oct 2019 16:15:15 -0400 Subject: [PATCH 1/6] GT-3202: Added initial support for SparcV9 floating point instructions --- .../Sparc/data/languages/SparcV9.sinc | 298 +++++++++--------- .../Sparc/data/languages/SparcV9_32.cspec | 45 +++ .../Sparc/data/languages/SparcV9_64.cspec | 45 +++ 3 files changed, 240 insertions(+), 148 deletions(-) diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 6f6bb41bd9..e9fe9aca9a 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -28,7 +28,8 @@ define register offset=0x3000 size=1 [ x_nf x_zf x_vf x_cf i_nf i_zf i_vf i_cf ] define register offset=0x4000 size=1 [ ASI _ _ _ _ _ _ _ fprs _ _ _ _ _ _ _ ]; define register offset=0x4000 size=$(SIZE) [ ASIext fprsext ]; -define register offset=0x5000 size=1 [ fcc0 fcc1 fcc2 fcc3 ]; +define register offset=0x5000 size=2 [ fsr ]; +define register offset=0x5002 size=1 [ fcc0 fcc1 fcc2 fcc3 ]; define register offset=0x5010 size=1 [ didrestore ]; @@ -110,6 +111,21 @@ w720 w721 w722 w723 w724 w725 w726 w727 w730 w731 w732 w733 w734 w735 w736 w737 ]; +# Floating-point registers +define register offset=0x2000 size=4 [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 + fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 + fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 + fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 ]; + +define register offset=0x2000 size=8 [fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14 + fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30 + fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 + fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 ]; + +define register offset=0x2000 size=16 [fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 + fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 ]; + + define pcodeop segment; define pcodeop popc; define pcodeop sw_trap; @@ -1008,22 +1024,10 @@ define pcodeop IllegalInstructionTrap; :restored is op = 2 & fcn=1 & op3 = 0x31 {} :saved is op = 2 & fcn = 0 & op3 = 0x31 {} -#---- TO DO: floating point +# TODO: floating point -define register offset=0x2000 size=4 [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 - fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 - fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 - fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 ]; - -define register offset=0x2000 size=8 [fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14 - fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30 - fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 - fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 ]; - -define register offset=0x2000 size=16 [fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 - fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 ]; - + attach variables [fsrd fsrs1 fsrs2 ] [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 @@ -1036,52 +1040,6 @@ attach variables [fdrd fdrs1 fdrs2 ] [ fd0 fd32 fd2 fd34 fd4 fd36 fd6 fd38 attach variables [fqrd fqrs1 fqrs2 ] [ fq0 _ fq32 _ fq4 _ fq36 _ fq8 _ fq40 _ fq12 _ fq44 _ fq16 _ fq48 _ fq20 _ fq52 _ fq24 _ fq56 _ fq28 _ fq60 _]; -define pcodeop fabss; -define pcodeop fabsd; -define pcodeop fabsq; -define pcodeop fadds; -define pcodeop faddd; -define pcodeop faddq; -define pcodeop fdivs; -define pcodeop fdivd; -define pcodeop fdivq; -define pcodeop fdmulq; -define pcodeop fitos; -define pcodeop fitod; -define pcodeop fitoq; -define pcodeop fmovs; -define pcodeop fmovd; -define pcodeop fmovq; -define pcodeop fmuls; -define pcodeop fmuld; -define pcodeop fmulq; -define pcodeop fnegs; -define pcodeop fnegd; -define pcodeop fnegq; -define pcodeop fsmuld; -define pcodeop fsubs; -define pcodeop fsubd; -define pcodeop fsubq; -define pcodeop fxtos; -define pcodeop fxtod; -define pcodeop fxtoq; - -define pcodeop fstoi; -define pcodeop fdtoi; -define pcodeop fqtoi; -define pcodeop fstox; -define pcodeop fdtox; -define pcodeop fqtox; -define pcodeop fstod; -define pcodeop fstoq; -define pcodeop fdtos; -define pcodeop fdtoq; -define pcodeop fqtos; -define pcodeop fqtod; - -define pcodeop fsqrts; -define pcodeop fsqrtd; -define pcodeop fsqrtq; define pcodeop ld; define pcodeop ldd; @@ -1104,71 +1062,111 @@ define pcodeop sta; define pcodeop stda; define pcodeop stqa; -:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = fabss(fsrs2); } -:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = fabss(fdrs2); } -:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = fabss(fqrs2); } -:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fadds(fsrs1, fsrs2); } -:faddd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x42 & fdrs2 { fdrd = faddd(fsrs1, fdrs2); } -:faddq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x43 & fqrs2 { fqrd = faddq(fsrs1, fqrs2); } -:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fdivs(fsrs1, fsrs2); } -:fdivd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4e & fdrs2 { fdrd = fdivd(fsrs1, fdrs2); } -:fdivq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4f & fqrs2 { fqrd = fdivq(fsrs1, fqrs2); } -:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 { fqrd = fdmulq(fdrs1, fdrs2); } -:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = fitos(fsrs2); } -:fitod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fdrs2 { fdrd = fitod(fdrs2); } -:fitoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fqrs2 { fqrd = fitoq(fqrs2); } -:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fmovs(fsrs2); } -:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fmovd(fdrs2); } -:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fmovq(fqrs2); } -:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fmuls(fsrs1, fsrs2); } -:fmuld fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4a & fdrs2 { fdrd = fmuld(fsrs1, fdrs2); } -:fmulq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4b & fqrs2 { fqrd = fmulq(fsrs1, fqrs2); } -:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = fnegs(fsrs2); } -:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = fnegd(fdrs2); } -:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = fnegq(fqrs2); } -:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 { fdrd = fsmuld(fsrs1, fsrs2); } -:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsubs(fsrs1, fsrs2); } -:fsubd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x46 & fdrs2 { fdrd = fsubd(fsrs1, fdrs2); } -:fsubq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x47 & fqrs2 { fqrd = fsubq(fsrs1, fqrs2); } -:fxtos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fsrs2 { fsrd = fxtos(fsrs2); } -:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = fxtod(fdrs2); } -:fxtoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fqrs2 { fqrd = fxtoq(fqrs2); } +:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = abs(fsrs2); } +:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = abs(fdrs2); } +:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = abs(fqrs2); } -:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = fstoi(fsrs2); } -:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = fdtoi(fdrs2); } -:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = fqtoi(fqrs2); } -:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = fstox(fsrs2); } -:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = fdtox(fdrs2); } -:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = fqtox(fqrs2); } -:fstod fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc9 & fsrs2 { fsrd = fstod(fsrs2); } -:fstoq fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcd & fdrs2 { fdrd = fstoq(fdrs2); } -:fdtos fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xc6 & fqrs2 { fqrd = fdtos(fqrs2); } -:fdtoq fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xce & fsrs2 { fsrd = fdtoq(fsrs2); } -:fqtos fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc7 & fdrs2 { fdrd = fqtos(fdrs2); } -:fqtod fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcb & fqrs2 { fqrd = fqtod(fqrs2); } +:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fsrs1 f+ fsrs2; } +:faddd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x42 & fdrs2 +{ + tmp1:8 = float2float(fsrs1); + fdrd = tmp1 f+ fdrs2; +} +:faddq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x43 & fqrs2 +{ + tmp1:16 = float2float(fsrs1); + fqrd = tmp1 f+ fqrs2; +} -:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = fsqrts(fsrs2); } -:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = fsqrtd(fdrs2); } -:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = fsqrtq(fqrs2); } +:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fsrs1 f/ fsrs2; } +:fdivd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4e & fdrs2 +{ + tmp1:8 = float2float(fsrs1); + fdrd = tmp1 f/ fdrs2; +} +:fdivq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4f & fqrs2 +{ + tmp1:16 = float2float(fsrs1); + fqrd = tmp1 f/ fqrs2; +} -:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = ld(ea); } -:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = ldd(ea); } -:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = ldq(ea); } -:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { ld_fsr(ea); } -:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { ldx_fsr(ea); } -:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = lda(ea_alt); } -:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = ldda(ea_alt); } -:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = ldqa(ea_alt); } +:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 +{ + tmp1:16 = float2float(fdrs1); + tmp2:16 = float2float(fdrs2); + fqrd = tmp1 f* tmp2; +} +:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 +{ + tmp1:8 = float2float(fsrs1); + tmp2:8 = float2float(fsrs2); + fdrd = tmp1 f* tmp2; +} -:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { ea = st(fsrd); } -:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { ea = std(fdrd); } -:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { ea = stq(fqrd); } -:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { ea = st_fsr(); } -:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { ea = stx_fsr(); } +:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = int2float(fsrs2); } +:fitod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fdrs2 { fdrd = int2float(fdrs2); } +:fitoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fqrs2 { fqrd = int2float(fqrs2); } -:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { ea_alt = sta(fsrd); } -:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { ea_alt = stda(fdrd); } -:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { ea_alt = stqa(fqrd); } +:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fsrs2; } +:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fdrs2; } +:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fqrs2; } + +:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fsrs1 f* fsrs2; } +:fmuld fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4a & fdrs2 { fdrd = fdrs1 f* fdrs2; } +:fmulq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4b & fqrs2 { fqrd = fqrs1 f* fqrs2; } + +:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = f- fsrs2; } +:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = f- fdrs2; } +:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = f- fqrs2; } + +:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsrs1 f- fsrs2; } +:fsubd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x46 & fdrs2 { fdrd = fdrs1 f- fdrs2; } +:fsubq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x47 & fqrs2 { fqrd = fqrs1 f- fqrs2; } + +:fxtos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fsrs2 { fsrd = int2float(fsrs2); } +:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = int2float(fdrs2); } +:fxtoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fqrs2 { fqrd = int2float(fqrs2); } + +:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = trunc(fsrs2); } +:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = trunc(fdrs2); } +:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = trunc(fqrs2); } + +:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = trunc(fsrs2); } +:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = trunc(fdrs2); } +:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = trunc(fqrs2); } + +:fstod fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc9 & fsrs2 { fsrd = trunc(fsrs2); } +:fstoq fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcd & fdrs2 { fdrd = trunc(fdrs2); } + +:fdtos fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xc6 & fqrs2 { fqrd = trunc(fqrs2); } +:fdtoq fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xce & fsrs2 { fsrd = trunc(fsrs2); } + +:fqtos fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc7 & fdrs2 { fdrd = trunc(fdrs2); } +:fqtod fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcb & fqrs2 { fqrd = trunc(fqrs2); } + +:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = sqrt(fsrs2); } +:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = sqrt(fdrs2); } +:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = sqrt(fqrs2); } + +:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = *:4 ea; } +:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = *:8 ea; } +:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = *:16 ea; } +:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { fsr = *:2 ea; } +:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { fsr = *:2 ea; } + +:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = *:4 ea_alt; } +:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = *:8 ea_alt; } +:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = *:16 ea_alt; } + +:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { *ea = fsrd:4; } +:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { *ea = fdrd:8; } +:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { *ea = fqrd:16; } +:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { *ea = fsr; } +:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { *ea = fsr; } + +:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { *ea_alt = fsrd:4; } +:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { *ea_alt = fdrd:8; } +:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { *ea_alt = fqrd:16; } fcc0_or_fccn: is op2=6 { export fcc0; } fcc0_or_fccn: is op2=5 & fccn {export fccn; } @@ -1201,19 +1199,22 @@ fcc: "o" is cond=0xf & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn :fb^fcc^predict "%"fccn,reloff64 is op=0x0 & op2=0x5 & a=0x0 & fcc & reloff64 & predict & fccn { delayslot(1); if (fcc) goto reloff64; } :fb^fcc^",a"^predict "%"^fccn,reloff64 is op=0x0 & op2=0x5 & a=0x1 & fcc & reloff64 & predict & fccn { if (!fcc) goto inst_next; delayslot(1); goto reloff64; } -define pcodeop fcmps; -define pcodeop fcmpd; -define pcodeop fcmpq; -define pcodeop fcmpes; -define pcodeop fcmped; -define pcodeop fcmpeq; +macro fcmp(f1, f2, fccn) +{ + # fcc value | relation + # 0 | f1 = f2 + # 1 | f1 < f2 + # 2 | f1 > f2 + # 3 | f1 or f2 NaN + fccn = (1*(f1 s< f2)) + (2*(f1 s> f2)) + (3*(nan(f1) || nan(f2))); +} -:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmps(fsrs1, fsrs2); } -:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmpd(fdrs1, fdrs2); } -:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmpq(fqrs1, fqrs2); } -:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmpes(fsrs1, fsrs2); } -:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmped(fdrs1, fdrs2); } -:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmpeq(fqrs1, fqrs2); } +:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } +:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } +:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } +:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } +:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } +:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } Z: is opf_cc=4 { export i_zf; } @@ -1267,16 +1268,19 @@ fmfcc: "o" is cond4=0xf & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 fmfcc_or_fmicc: fmfcc is bit18=0 & fmfcc { export fmfcc; } fmfcc_or_fmicc: fmicc is bit18=1 & fmicc { export fmicc; } -fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 {} -fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 {} -fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 {} +fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 { } +fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 { } +fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 { } -:fmovs^fmfcc_or_fmicc fcc_icc_xcc,fsrs2,fsrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=1 & fsrs2 & fsrd { fsrd = fmovs(fcc_icc_xcc, fsrs2); } -:fmovd^fmfcc_or_fmicc fcc_icc_xcc,fdrs2,fdrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=2 & fdrs2 & fdrd { fdrd = fmovd(fcc_icc_xcc, fdrs2); } -:fmovq^fmfcc_or_fmicc fcc_icc_xcc,fqrs2,fqrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=3 & fqrs2 & fqrd { fqrd = fmovq(fcc_icc_xcc, fqrs2); } +:fmovs^fmfcc_or_fmicc fcc_icc_xcc,fsrs2,fsrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=1 & fsrs2 & fsrd + { if !(fmfcc_or_fmicc) goto inst_next; fsrd = fsrs2; } +:fmovd^fmfcc_or_fmicc fcc_icc_xcc,fdrs2,fdrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=2 & fdrs2 & fdrd + { if !(fmfcc_or_fmicc) goto inst_next; fdrd = fdrs2; } +:fmovq^fmfcc_or_fmicc fcc_icc_xcc,fqrs2,fqrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=3 & fqrs2 & fqrd + { if !(fmfcc_or_fmicc) goto inst_next; fqrd = fqrs2; } :movf^fmfcc_or_fmicc fcc_icc_xcc,regorimm11,rd is op=2 & rd & op3=0x2c & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & regorimm11 - { if (fmfcc_or_fmicc) goto inst_next; rd = regorimm11; } + { if !(fmfcc_or_fmicc) goto inst_next; rd = regorimm11; } fmovrcc: "z" is rcond3=0x1 & RS1 {tmp:1 = (RS1 f== 0); export tmp;} fmovrcc: "lez" is rcond3=0x2 & RS1 {tmp:1 = (RS1 f<= 0); export tmp;} @@ -1285,14 +1289,12 @@ fmovrcc: "nz" is rcond3=0x5 & RS1 {tmp:1 = (RS1 f!= 0); export tmp;} fmovrcc: "gz" is rcond3=0x6 & RS1 {tmp:1 = (RS1 f> 0); export tmp;} fmovrcc: "gez" is rcond3=0x7 & RS1 {tmp:1 = (RS1 f>= 0); export tmp;} - -define pcodeop fmovrs; -define pcodeop fmovrd; -define pcodeop fmovrq; - -:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 { fsrd = fmovrs(RS1, fsrs2); } -:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 { fdrd = fmovrd(RS1, fdrs2); } -:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 { fqrd = fmovrq(RS1, fqrs2); } +:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 + { if !(fmovrcc) goto inst_next; fsrd = fsrs2; } +:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 + { if !(fmovrcc) goto inst_next; fdrd = fdrs2; } +:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 + { if !(fmovrcc) goto inst_next; fqrd = fqrs2; } # Include support for the VIS1 vector instructions @include "SparcVIS.sinc" diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec index 64ae72dbb2..d3d608d0ef 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec @@ -8,6 +8,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -31,6 +67,15 @@ + + + + + + + + + diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec index be71efdf8a..4f67923d8b 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec @@ -8,6 +8,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -31,6 +67,15 @@ + + + + + + + + + From a61ea576cfe75a448c7960a477e5350ed6b93c2c Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Wed, 2 Oct 2019 14:34:18 -0400 Subject: [PATCH 2/6] GT-3202: SparcV9 sleigh corrections - Correctly implemented register windowing function for save/restore - Corrected floating point instructions which used the wrong operands - Corrected .cspec issues for 32- and 64-bit - Implemented pcodetests for 64-bit. --- .../Sparc/data/languages/SparcV9.sinc | 116 ++++++++---------- .../Sparc/data/languages/SparcV9_32.cspec | 36 ------ .../Sparc/data/languages/SparcV9_64.cspec | 20 +-- .../SparcV9_32_O0_EmulatorTest.java | 40 ++++++ .../SparcV9_32_O3_EmulatorTest.java | 40 ++++++ .../SparcV9_64_O0_EmulatorTest.java | 40 ++++++ .../SparcV9_64_O3_EmulatorTest.java | 40 ++++++ 7 files changed, 214 insertions(+), 118 deletions(-) create mode 100644 Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java create mode 100644 Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java create mode 100644 Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java create mode 100644 Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index e9fe9aca9a..1544c111e7 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -53,20 +53,20 @@ define register offset=0x6000 size=$(SIZE) [ HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4 HSTICK_CMPR1 HSTICK_CMPR2 HSTICK_CMPR3 HSTICK_CMPR4 ]; -# A window is 24 registers (96 or 192 bytes), must processors have 7 or 8. (g0->g7,o0->o7,l0->o7,i0->i7) +# A window is 24 registers (96 or 192 bytes), most processors have 7 or 8. (g0->g7,o0->o7,l0->o7,i0->i7) # When the window is overflowed the data must be purged to some backup memory, via user -# suppied function attached to a signal handler. +# supplied function attached to a signal handler. # When the window is underflowed the data must be read from some backup memory, via user -# suppied function attached to a signal handler. +# supplied function attached to a signal handler. # There are 2 basic strategies we figured for this. # One, create a bank of register space and read and write to it in a way that simulates -# how the sparc would really work, but the symboic names become indexes. +# how the sparc would really work, but the symbolic names become indexes. # Two, save and restore logic does all the work. # window index is ((CWP+1)%NWINDOWS) -# CWP is an index from 0 to N of the wondows. -# Size of CWP is implimination depedent (must be > 5 bits). +# CWP is an index from 0 to N of the windows. +# Size of CWP is implementation dependent (must be > 5 bits). # inputs i0 i1 i2 i3 i4 i5 fp i7 # locals l0 l1 l2 l3 l4 l5 l6 l7 @@ -245,26 +245,26 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _ # CWP++ macro save() { -@if SIZE=="4" -# # Save inputs -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+0)*$(SIZE)) = i0; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+1)*$(SIZE)) = i1; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+2)*$(SIZE)) = i2; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+3)*$(SIZE)) = i3; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+4)*$(SIZE)) = i4; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+5)*$(SIZE)) = i5; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+6)*$(SIZE)) = fp; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+7)*$(SIZE)) = i7; -# -# # Save local -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6; -# *[register]:$(SIZE) (&w010 + (CWP*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7; +@if SIZE=="4" || SIZE == "8" + # Save inputs + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0)*$(SIZE)) = i0; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1)*$(SIZE)) = i1; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2)*$(SIZE)) = i2; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3)*$(SIZE)) = i3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4)*$(SIZE)) = i4; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5)*$(SIZE)) = i5; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6)*$(SIZE)) = fp; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7)*$(SIZE)) = i7; + + # Save local + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7; # what was outputs become inputs i0 = o0; @@ -332,7 +332,7 @@ macro save() { macro restore() { CWP = CWP - 1; -@if SIZE=="4" +@if SIZE=="4" || SIZE == "8" # inputs once again become outputs o0 = i0; # API return value o1 = i1; @@ -343,25 +343,25 @@ macro restore() { sp = fp; o7 = i7; # address of CALLer address -# # restore original inputs -# i0 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+0)*$(SIZE))); -# i1 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+1)*$(SIZE))); -# i2 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+2)*$(SIZE))); -# i3 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+3)*$(SIZE))); -# i4 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+4)*$(SIZE))); -# i5 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+5)*$(SIZE))); -# fp = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6)*$(SIZE))); -# i7 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address -# -# # restore original locals -# l0 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE))); -# l1 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE))); -# l2 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE))); -# l3 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE))); -# l4 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE))); -# l5 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE))); -# l6 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); -# l7 = *[register]:$(SIZE) ((&:$(SIZE) w010) + ((CWP*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); + # restore original inputs + i0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0)*$(SIZE))); + i1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1)*$(SIZE))); + i2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2)*$(SIZE))); + i3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3)*$(SIZE))); + i4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4)*$(SIZE))); + i5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5)*$(SIZE))); + fp = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6)*$(SIZE))); + i7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address + + # restore original locals + l0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE))); + l1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE))); + l2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE))); + l3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE))); + l4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE))); + l5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE))); + l6 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); + l7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); @else o0 = i0; o1 = i1; @@ -1067,28 +1067,12 @@ define pcodeop stqa; :fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = abs(fqrs2); } :fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fsrs1 f+ fsrs2; } -:faddd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x42 & fdrs2 -{ - tmp1:8 = float2float(fsrs1); - fdrd = tmp1 f+ fdrs2; -} -:faddq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x43 & fqrs2 -{ - tmp1:16 = float2float(fsrs1); - fqrd = tmp1 f+ fqrs2; -} +:faddd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x42 & fdrs2 { fdrd = fdrs1 f+ fdrs2; } +:faddq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x43 & fqrs2 { fqrd = fqrs1 f+ fqrs2; } :fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fsrs1 f/ fsrs2; } -:fdivd fsrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x4e & fdrs2 -{ - tmp1:8 = float2float(fsrs1); - fdrd = tmp1 f/ fdrs2; -} -:fdivq fsrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fsrs1 & opf=0x4f & fqrs2 -{ - tmp1:16 = float2float(fsrs1); - fqrd = tmp1 f/ fqrs2; -} +:fdivd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4e & fdrs2 { fdrd = fdrs1 f/ fdrs2; } +:fdivq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4f & fqrs2 { fqrd = fqrs1 f/ fqrs2; } :fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 { diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec index d3d608d0ef..bc1aaa1967 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec @@ -8,42 +8,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec index 4f67923d8b..9eab4e95bc 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec @@ -20,30 +20,18 @@ - + - + - + - + - - - - - - - - - - - - diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java new file mode 100644 index 0000000000..b63beeb408 --- /dev/null +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class SparcV9_32_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "sparc:BE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public SparcV9_32_O0_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "sparcV9_32_GCC_O0"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O0_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java new file mode 100644 index 0000000000..7e225ba66a --- /dev/null +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class SparcV9_32_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "sparc:BE:32:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public SparcV9_32_O3_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "sparcV9_32_GCC_O3"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O3_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java new file mode 100644 index 0000000000..ba005c1d31 --- /dev/null +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class SparcV9_64_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "sparc:BE:64:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public SparcV9_64_O0_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "sparcV9_64_GCC_O0"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O0_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java new file mode 100644 index 0000000000..82c9417fca --- /dev/null +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class SparcV9_64_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "sparc:BE:64:default"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public SparcV9_64_O3_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "sparcV9_64_GCC_O3"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O3_EmulatorTest.class); + } +} From 9fb4dc4459b510e4944c9cffefc1c41ed74eed77 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Fri, 4 Oct 2019 13:13:25 -0400 Subject: [PATCH 3/6] GT-3202: Sparc sleigh changes - General sleigh formatting changes - Corrected floating point register ordering - Made decompiler happy with save/restore functions - Fixed decompiler issues with ldd (but not std yet) - Corrected issue with delay slot conditional goto inst_next instructions - Corrected register references in fito- and fxto- instructions. --- .../Sparc/data/languages/SparcV9.pspec | 1 + .../Sparc/data/languages/SparcV9.sinc | 1704 ++++++++--------- 2 files changed, 849 insertions(+), 856 deletions(-) diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.pspec b/Ghidra/Processors/Sparc/data/languages/SparcV9.pspec index 5005c26dc4..862d7adf1f 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.pspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.pspec @@ -9,6 +9,7 @@ + diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 1544c111e7..632a1def96 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -1,27 +1,33 @@ # SLA specification file for SPARC/64 define endian=big; + define alignment=4; define space ram type=ram_space size=$(SIZE) default; define space register type=register_space size=4; -define register offset=0 size=$(SIZE) [ g0 g1 g2 g3 g4 g5 g6 g7 - o0 o1 o2 o3 o4 o5 sp o7 - l0 l1 l2 l3 l4 l5 l6 l7 - i0 i1 i2 i3 i4 i5 fp i7 - ]; +define register offset=0 size=$(SIZE) [ + g0 g1 g2 g3 g4 g5 g6 g7 + o0 o1 o2 o3 o4 o5 sp o7 + l0 l1 l2 l3 l4 l5 l6 l7 + i0 i1 i2 i3 i4 i5 fp i7 +]; # these are save locations for implementing register windows # -define register offset=0x500 size=$(SIZE) [ s_l0 s_l1 s_l2 s_l3 s_l4 s_l5 s_l6 s_l7 - s_i0 s_i1 s_i2 s_i3 s_i4 s_i5 s_fp s_i7 ]; +define register offset=0x500 size=$(SIZE) [ + s_l0 s_l1 s_l2 s_l3 s_l4 s_l5 s_l6 s_l7 + s_i0 s_i1 s_i2 s_i3 s_i4 s_i5 s_fp s_i7 +]; define register offset=0x1000 size=$(SIZE) [ PC nPC ASR TICK Y CCR FPRS PCR PIC GSR SOFTINT_SET SOFTINT_CLR SOFTINT TICK_CMPR STICK STICK_CMPR ]; -define register offset=0x1100 size=$(SIZE) [ asr7 asr8 asr9 asr10 asr11 asr12 asr13 asr14 asr15 - asr16 asr17 asr18 asr19 asr20 asr21 asr22 asr23 - asr24 asr25 asr26 asr27 asr28 asr29 asr30 asr31 ]; +define register offset=0x1100 size=$(SIZE) [ + asr7 asr8 asr9 asr10 asr11 asr12 asr13 asr14 asr15 + asr16 asr17 asr18 asr19 asr20 asr21 asr22 asr23 + asr24 asr25 asr26 asr27 asr28 asr29 asr30 asr31 +]; define register offset=0x3000 size=1 [ x_nf x_zf x_vf x_cf i_nf i_zf i_vf i_cf ]; @@ -31,27 +37,31 @@ define register offset=0x4000 size=$(SIZE) [ ASIext fprsext ]; define register offset=0x5000 size=2 [ fsr ]; define register offset=0x5002 size=1 [ fcc0 fcc1 fcc2 fcc3 ]; define register offset=0x5010 size=1 [ didrestore ]; +define register offset=0x5020 size=1 [ DECOMPILE_MODE ]; # Fake register -define register offset=0x5000 size=$(SIZE) [ TPC1 TPC2 TPC3 TPC4 - TNPC1 TNPC2 TNPC3 TNPC4 - TSTATE1 TSTATE2 TSTATE3 TSTATE4 - TT1 TT2 TT3 TT4 - TCK TBA PSTATE TL - PIL CWP CANSAVE CANRESTORE CLEANWIN - OTHERWIN WSTATE FQ VER GL ]; +define register offset=0x5000 size=$(SIZE) [ + TPC1 TPC2 TPC3 TPC4 + TNPC1 TNPC2 TNPC3 TNPC4 + TSTATE1 TSTATE2 TSTATE3 TSTATE4 + TT1 TT2 TT3 TT4 + TCK TBA PSTATE TL + PIL CWP CANSAVE CANRESTORE CLEANWIN + OTHERWIN WSTATE FQ VER GL +]; -define register offset=0x6000 size=$(SIZE) [ HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4 - HTSTATE1 HTSTATE2 HTSTATE3 HTSTATE4 - RESV2_1 RESV2_2 RESV2_3 RESV2_4 - HINTP1 HINTP2 HINTP3 HINTP4 - RESV4_1 RESV4_2 RESV4_3 RESV4_4 - HTBA1 HTBA2 HTBA3 HTBA4 - HVER1 HVER2 HVER3 HVER4 +define register offset=0x6000 size=$(SIZE) [ + HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4 + HTSTATE1 HTSTATE2 HTSTATE3 HTSTATE4 + RESV2_1 RESV2_2 RESV2_3 RESV2_4 + HINTP1 HINTP2 HINTP3 HINTP4 + RESV4_1 RESV4_2 RESV4_3 RESV4_4 + HTBA1 HTBA2 HTBA3 HTBA4 + HVER1 HVER2 HVER3 HVER4 # TODO: actually RESV 6 - 29 registers... - RESV30_1 RESV30_2 RESV30_3 RESV30_4 - HSTICK_CMPR1 HSTICK_CMPR2 HSTICK_CMPR3 HSTICK_CMPR4 - ]; + RESV30_1 RESV30_2 RESV30_3 RESV30_4 + HSTICK_CMPR1 HSTICK_CMPR2 HSTICK_CMPR3 HSTICK_CMPR4 +]; # A window is 24 registers (96 or 192 bytes), most processors have 7 or 8. (g0->g7,o0->o7,l0->o7,i0->i7) # When the window is overflowed the data must be purged to some backup memory, via user @@ -77,54 +87,52 @@ define register offset=0x6000 size=$(SIZE) [ HPSTATE1 HPSTATE2 HPSTATE3 HPSTATE4 # i7 w017 w037 w127 w217 w237 w327 w417 # o7 w037 w127 w217 w237 w327 w417 -define register offset=0x7000 size=$(SIZE) [ -w010 w011 w012 w013 w014 w015 w016 w017 -w020 w021 w022 w023 w024 w025 w026 w027 -w030 w031 w032 w033 w034 w035 w036 w037 - -w110 w111 w112 w113 w114 w115 w116 w117 -w120 w121 w122 w123 w124 w125 w126 w127 -w130 w131 w132 w133 w134 w135 w136 w137 - -w210 w211 w212 w213 w214 w215 w216 w217 -w220 w221 w222 w223 w224 w225 w226 w227 -w230 w231 w232 w233 w234 w235 w236 w237 - -w310 w311 w312 w313 w314 w315 w316 w317 -w320 w321 w322 w323 w324 w325 w326 w327 -w330 w331 w332 w333 w334 w335 w336 w337 - -w410 w411 w412 w413 w414 w415 w416 w417 -w420 w421 w422 w423 w424 w425 w426 w427 -w430 w431 w432 w433 w434 w435 w436 w437 - -w510 w511 w512 w513 w514 w515 w516 w517 -w520 w521 w522 w523 w524 w525 w526 w527 -w530 w531 w532 w533 w534 w535 w536 w537 - -w610 w611 w612 w613 w614 w615 w616 w617 -w620 w621 w622 w623 w624 w625 w626 w627 -w630 w631 w632 w633 w634 w635 w636 w637 - -w710 w711 w712 w713 w714 w715 w716 w717 -w720 w721 w722 w723 w724 w725 w726 w727 -w730 w731 w732 w733 w734 w735 w736 w737 +define register offset=0x7000 size=$(SIZE) [ + w010 w011 w012 w013 w014 w015 w016 w017 + w020 w021 w022 w023 w024 w025 w026 w027 + w030 w031 w032 w033 w034 w035 w036 w037 + w110 w111 w112 w113 w114 w115 w116 w117 + w120 w121 w122 w123 w124 w125 w126 w127 + w130 w131 w132 w133 w134 w135 w136 w137 + w210 w211 w212 w213 w214 w215 w216 w217 + w220 w221 w222 w223 w224 w225 w226 w227 + w230 w231 w232 w233 w234 w235 w236 w237 + w310 w311 w312 w313 w314 w315 w316 w317 + w320 w321 w322 w323 w324 w325 w326 w327 + w330 w331 w332 w333 w334 w335 w336 w337 + w410 w411 w412 w413 w414 w415 w416 w417 + w420 w421 w422 w423 w424 w425 w426 w427 + w430 w431 w432 w433 w434 w435 w436 w437 + w510 w511 w512 w513 w514 w515 w516 w517 + w520 w521 w522 w523 w524 w525 w526 w527 + w530 w531 w532 w533 w534 w535 w536 w537 + w610 w611 w612 w613 w614 w615 w616 w617 + w620 w621 w622 w623 w624 w625 w626 w627 + w630 w631 w632 w633 w634 w635 w636 w637 + w710 w711 w712 w713 w714 w715 w716 w717 + w720 w721 w722 w723 w724 w725 w726 w727 + w730 w731 w732 w733 w734 w735 w736 w737 ]; # Floating-point registers -define register offset=0x2000 size=4 [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 - fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 - fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 - fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 ]; +define register offset=0x2000 size=4 [ + fs3 fs2 fs1 fs0 fs7 fs6 fs5 fs4 + fs11 fs10 fs9 fs8 fs15 fs14 fs13 fs12 + fs19 fs18 fs17 fs16 fs23 fs22 fs21 fs20 + fs27 fs26 fs25 fs24 fs31 fs30 fs29 fs28 +]; -define register offset=0x2000 size=8 [fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14 - fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30 - fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 - fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 ]; +define register offset=0x2000 size=8 [ + fd2 fd0 fd6 fd4 fd10 fd8 fd14 fd12 + fd18 fd16 fd22 fd20 fd26 fd24 fd30 fd28 + fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 + fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 +]; -define register offset=0x2000 size=16 [fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 - fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 ]; - +define register offset=0x2000 size=16 [ + fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 + fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 +]; define pcodeop segment; define pcodeop popc; @@ -132,87 +140,87 @@ define pcodeop sw_trap; define pcodeop reset; define token instr(32) - op = (30,31) - disp30 = (0,29) signed - udisp22 = (0,21) - disp22 = (0,21) signed - disp19 = (0,18) signed - d16lo = (0,13) - d16hi = (20,21) signed - op2 = (22,24) - a = (29,29) - fpc = (27,29) - cond = (25,28) - cond4 = (14,17) - rcond2 = (25,27) - cc0 = (20,20) - cc1 = (21,21) - fccn = (20,21) - fccn2 = (25,26) - cc0_3 = (25,25) - cc1_3 = (26,26) - cc0_4 = (11,11) - cc1_4 = (12,12) - fccn_4 = (11,12) - cc2_4 = (18,18) - p = (19,19) - rd = (25,29) - rd_d = (25,29) - rd_zero = (25,29) - fsrd = (25,29) - fdrd = (25,29) - fqrd = (25,29) - prd = (25,29) - op3 = (19,24) - rs1 = (14,18) - rs1_zero = (14,18) - rs1_3 = (14,18) - prs1 = (14,18) - fsrs1 = (14,18) - fdrs1 = (14,18) - fqrs1 = (14,18) - i = (13,13) - x = (12,12) - rcond3 = (10,12) - rs2 = (0,4) - rs2_zero = (0,4) - fsrs2 = (0,4) - fdrs2 = (0,4) - fqrs2 = (0,4) -shcnt32 = (0,4) -shcnt64 = (0,5) - simm13 = (0,12) signed - simm11 = (0,10) signed - simm10 = (0,9) signed -imm_asi = (5,12) - cmask = (4,6) - mmask = (0,3) - opf = (5,13) - opf5 = (5,9) - opf6 = (5,10) - opf_cc = (11,13) - opf_low= (5,10) - fcn = (25,29) - swtrap = (0,6) - bit28 = (28,28) -const22 = (0, 21) - bit13 = (13,13) - bit18 = (18,18) + op = (30,31) + disp30 = ( 0,29) signed + udisp22 = ( 0,21) + disp22 = ( 0,21) signed + disp19 = ( 0,18) signed + d16lo = ( 0,13) + d16hi = (20,21) signed + op2 = (22,24) + a = (29,29) + fpc = (27,29) + cond = (25,28) + cond4 = (14,17) + rcond2 = (25,27) + cc0 = (20,20) + cc1 = (21,21) + fccn = (20,21) + fccn2 = (25,26) + cc0_3 = (25,25) + cc1_3 = (26,26) + cc0_4 = (11,11) + cc1_4 = (12,12) + fccn_4 = (11,12) + cc2_4 = (18,18) + p = (19,19) + rd = (25,29) + rd_d = (25,29) + rd_zero = (25,29) + fsrd = (25,29) + fdrd = (25,29) + fqrd = (25,29) + prd = (25,29) + op3 = (19,24) + rs1 = (14,18) + rs1_zero = (14,18) + rs1_3 = (14,18) + prs1 = (14,18) + fsrs1 = (14,18) + fdrs1 = (14,18) + fqrs1 = (14,18) + i = (13,13) + x = (12,12) + rcond3 = (10,12) + rs2 = ( 0, 4) + rs2_zero = ( 0, 4) + fsrs2 = ( 0, 4) + fdrs2 = ( 0, 4) + fqrs2 = ( 0, 4) + shcnt32 = ( 0, 4) + shcnt64 = ( 0, 5) + simm13 = ( 0,12) signed + simm11 = ( 0,10) signed + simm10 = ( 0, 9) signed + imm_asi = ( 5,12) + cmask = ( 4, 6) + mmask = ( 0, 3) + opf = ( 5,13) + opf5 = ( 5, 9) + opf6 = ( 5,10) + opf_cc = (11,13) + opf_low = ( 5,10) + fcn = (25,29) + swtrap = ( 0, 6) + bit28 = (28,28) + const22 = ( 0,21) + bit13 = (13,13) + bit18 = (18,18) ; attach variables [ rd rs1 rs2 ] [ g0 g1 g2 g3 g4 g5 g6 g7 o0 o1 o2 o3 o4 o5 sp o7 l0 l1 l2 l3 l4 l5 l6 l7 i0 i1 i2 i3 i4 i5 fp i7 ]; - + @if SIZE=="4" # The ldd, ldda, std, and stda insns access a pair of regs define register offset=0 size=8 [ - g0_1 g2_3 g4_5 g6_7 - o0_1 o2_3 o4_5 sp_7 - l0_1 l2_3 l4_5 l6_7 - i0_1 i2_3 i4_5 fp_7 - ]; + g0_1 g2_3 g4_5 g6_7 + o0_1 o2_3 o4_5 sp_7 + l0_1 l2_3 l4_5 l6_7 + i0_1 i2_3 i4_5 fp_7 +]; attach variables [ rd_d ] [ g0_1 _ g2_3 _ g4_5 _ g6_7 _ @@ -220,6 +228,7 @@ attach variables [ rd_d ] [ l0_1 _ l2_3 _ l4_5 _ l6_7 _ i0_1 _ i2_3 _ i4_5 _ fp_7 _ ]; + @endif attach variables [ fccn fccn2 fccn_4 ] [ fcc0 fcc1 fcc2 fcc3 ]; @@ -233,9 +242,7 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _ # "%o0" "%o1" "%o2" "%o3" "%o4" "%o5" "%sp" "%o7" # "%l0" "%l1" "%l2" "%l3" "%l4" "%l5" "%l6" "%l7" # "%i0" "%i1" "%i2" "%i3" "%i4" "%i5" "%fp" "%i7" ]; - # Window register table accessors =================================== - @define NUMREGWINS 8 @define REGWINSZ 16 @define LOCALOFF 8 @@ -245,789 +252,778 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _ # CWP++ macro save() { -@if SIZE=="4" || SIZE == "8" - # Save inputs - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0)*$(SIZE)) = i0; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1)*$(SIZE)) = i1; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2)*$(SIZE)) = i2; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3)*$(SIZE)) = i3; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4)*$(SIZE)) = i4; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5)*$(SIZE)) = i5; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6)*$(SIZE)) = fp; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7)*$(SIZE)) = i7; - - # Save local - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6; - *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7; +if (!DECOMPILE_MODE) goto ; + # Save inputs + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0)*$(SIZE)) = i0; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1)*$(SIZE)) = i1; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2)*$(SIZE)) = i2; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3)*$(SIZE)) = i3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4)*$(SIZE)) = i4; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5)*$(SIZE)) = i5; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6)*$(SIZE)) = fp; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7)*$(SIZE)) = i7; - # what was outputs become inputs - i0 = o0; - i1 = o1; - i2 = o2; - i3 = o3; - i4 = o4; - i5 = o5; - fp = sp; - i7 = o7; - - # zero out locals - l0 = 0; - l1 = 0; - l2 = 0; - l3 = 0; - l4 = 0; - l5 = 0; - l6 = 0; - l7 = 0; + # Save local + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE)) = l0; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE)) = l1; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE)) = l3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE)) = l3; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE)) = l4; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE)) = l5; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE)) = l6; + *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+7+$(LOCALOFF))*$(SIZE)) = l7; -# # zero out outputs -# o0 = 0; -# o1 = 0; -# o2 = 0; -# o3 = 0; -# o4 = 0; -# o5 = 0; -# sp = 0; -# o7 = 0; -@else - i0 = o0; - i1 = o1; - i2 = o2; - i3 = o3; - i4 = o4; - i5 = o5; - fp = sp; - i7 = o7; - -# o0 = 0; -# o1 = 0; -# o2 = 0; -# o3 = 0; -# o4 = 0; -# o5 = 0; -# sp = 0; -# o7 = 0; + + # what was outputs become inputs + i0 = o0; + i1 = o1; + i2 = o2; + i3 = o3; + i4 = o4; + i5 = o5; + fp = sp; + i7 = o7; - l0 = 0; - l1 = 0; - l2 = 0; - l3 = 0; - l4 = 0; - l5 = 0; - l6 = 0; - l7 = 0; -@endif + # zero out locals + l0 = 0; + l1 = 0; + l2 = 0; + l3 = 0; + l4 = 0; + l5 = 0; + l6 = 0; + l7 = 0; - CWP = CWP + 1; + CWP = CWP + 1; } # copy iN ot oN # CWP-- macro restore() { - CWP = CWP - 1; + CWP = CWP - 1; -@if SIZE=="4" || SIZE == "8" - # inputs once again become outputs - o0 = i0; # API return value - o1 = i1; - o2 = i2; - o3 = i3; - o4 = i4; - o5 = i5; - sp = fp; - o7 = i7; # address of CALLer address + # inputs once again become outputs + o0 = i0; # API return value + o1 = i1; + o2 = i2; + o3 = i3; + o4 = i4; + o5 = i5; + sp = fp; + o7 = i7; # address of CALLer address - # restore original inputs - i0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0)*$(SIZE))); - i1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1)*$(SIZE))); - i2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2)*$(SIZE))); - i3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3)*$(SIZE))); - i4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4)*$(SIZE))); - i5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5)*$(SIZE))); - fp = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6)*$(SIZE))); - i7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address +if (!DECOMPILE_MODE) goto ; + # restore original inputs + i0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0)*$(SIZE))); + i1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1)*$(SIZE))); + i2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2)*$(SIZE))); + i3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3)*$(SIZE))); + i4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4)*$(SIZE))); + i5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5)*$(SIZE))); + fp = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6)*$(SIZE))); + i7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+7)*$(SIZE))); # address of CALLer address + # restore original locals + l0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE))); + l1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE))); + l2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE))); + l3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE))); + l4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE))); + l5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE))); + l6 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); + l7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); - # restore original locals - l0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0+$(LOCALOFF))*$(SIZE))); - l1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1+$(LOCALOFF))*$(SIZE))); - l2 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+2+$(LOCALOFF))*$(SIZE))); - l3 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+3+$(LOCALOFF))*$(SIZE))); - l4 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+4+$(LOCALOFF))*$(SIZE))); - l5 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+5+$(LOCALOFF))*$(SIZE))); - l6 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); - l7 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+6+$(LOCALOFF))*$(SIZE))); -@else - o0 = i0; - o1 = i1; - o2 = i2; - o3 = i3; - o4 = i4; - o5 = i5; - sp = fp; - o7 = i7; -@endif + } -RS1: rs1 is rs1 & rs1_zero=0 { export 0:$(SIZE); } -RS1: rs1 is rs1 { export rs1; } +RS1: rs1 is rs1 & rs1_zero=0 { export 0:$(SIZE); } +RS1: rs1 is rs1 { export rs1; } -RS2: rs2 is rs2 & rs2_zero=0 { export 0:$(SIZE); } -RS2: rs2 is rs2 { export rs2; } +RS2: rs2 is rs2 & rs2_zero=0 { export 0:$(SIZE); } +RS2: rs2 is rs2 { export rs2; } -RD: rd is rd & rd_zero=0 { export 0:$(SIZE); } -RD: rd is rd & rd_zero { export rd; } +RD: rd is rd & rd_zero=0 { export 0:$(SIZE); } +RD: rd is rd & rd_zero { export rd; } -regorimm: RS2 is i=0 & RS2 { export RS2; } -regorimm: simm13 is i=1 & simm13 { export *[const]:$(SIZE) simm13; } +regorimm: RS2 is i=0 & RS2 { export RS2; } +regorimm: simm13 is i=1 & simm13 { export *[const]:$(SIZE) simm13; } -regorimm10: RS2 is i=0 & RS2 { export RS2; } -regorimm10: simm10 is i=1 & simm10 { export *[const]:$(SIZE) simm10; } +regorimm10: RS2 is i=0 & RS2 { export RS2; } +regorimm10: simm10 is i=1 & simm10 { export *[const]:$(SIZE) simm10; } -regorimm11: RS2 is i=0 & RS2 { export RS2; } -regorimm11: simm11 is i=1 & simm11 { export *[const]:$(SIZE) simm11; } +regorimm11: RS2 is i=0 & RS2 { export RS2; } +regorimm11: simm11 is i=1 & simm11 { export *[const]:$(SIZE) simm11; } -reg_or_shcnt: RS2 is i=0 & RS2 & rs2=0 { export 0:1; } -reg_or_shcnt: RS2 is i=0 & x=0 & RS2 { tmp:1=RS2:1; tmp = tmp & 0x1f; export tmp; } -reg_or_shcnt: RS2 is i=0 & x=1 & RS2 { tmp:1=RS2:1; tmp = tmp & 0x3f; export tmp; } +reg_or_shcnt: RS2 is i=0 & RS2 & rs2=0 { export 0:1; } +reg_or_shcnt: RS2 is i=0 & x=0 & RS2 { tmp:1=RS2:1; tmp = tmp & 0x1f; export tmp; } +reg_or_shcnt: RS2 is i=0 & x=1 & RS2 { tmp:1=RS2:1; tmp = tmp & 0x3f; export tmp; } -reg_or_shcnt: shcnt32 is i=1 & x=0 & shcnt32 { export *[const]:1 shcnt32; } -reg_or_shcnt: shcnt64 is i=1 & x=1 & shcnt64 { export *[const]:1 shcnt64; } +reg_or_shcnt: shcnt32 is i=1 & x=0 & shcnt32 { export *[const]:1 shcnt32; } +reg_or_shcnt: shcnt64 is i=1 & x=1 & shcnt64 { export *[const]:1 shcnt64; } -ea: [regorimm] is rs1=0 & regorimm { export regorimm; } # special case g0=zero -ea: [RS1+regorimm] is RS1 & regorimm { local tmp = RS1+regorimm; export tmp; } -ea: [RS1] is RS1 & i=1 & simm13=0x0 { export RS1; } #special case when adding zero +ea: [regorimm] is rs1=0 & regorimm { export regorimm; } # special case g0=zero +ea: [RS1+regorimm] is RS1 & regorimm { local tmp = RS1+regorimm; export tmp; } +ea: [RS1] is RS1 & i=1 & simm13=0x0 { export RS1; } #special case when adding zero -retea: [regorimm] is rs1=0 & regorimm { export regorimm; } -retea: [RS1+regorimm] is RS1 & regorimm { local tmp = RS1+regorimm; export tmp; } -retea: [RS1] is RS1 & i=1 & simm13=0x0 { export RS1; } #special case when adding zero -retea: is rs1 & rs1_zero=31 & i=1 & simm13=0x8 { local tmp = rs1 + 0x8; export tmp; } # typical return from CALL instruction (suppress display) +retea: [regorimm] is rs1=0 & regorimm { export regorimm; } +retea: [RS1+regorimm] is RS1 & regorimm { local tmp = RS1+regorimm; export tmp; } +retea: [RS1] is RS1 & i=1 & simm13=0x0 { export RS1; } #special case when adding zero +retea: is rs1 & rs1_zero=31 & i=1 & simm13=0x8 { local tmp = rs1 + 0x8; export tmp; } # typical return from CALL instruction (suppress display) -ea_alt: [RS1+RS2] imm_asi is i=0 & RS1 & RS2 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+RS2+segment(tmp1); export tmp; } -ea_alt: [RS1+simm13] %ASI is i=1 & RS1 & simm13 & ASI { local tmp = RS1+simm13+segment(ASI); export tmp; } -ea_alt: [RS1] %ASI is i=1 & RS1 & simm13=0x0 & ASI { local tmp = RS1+segment(ASI); export tmp; } #special case when adding zero +ea_alt: [RS1+RS2] imm_asi is i=0 & RS1 & RS2 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+RS2+segment(tmp1); export tmp; } +ea_alt: [RS1+simm13] %ASI is i=1 & RS1 & simm13 & ASI { local tmp = RS1+simm13+segment(ASI); export tmp; } +ea_alt: [RS1] %ASI is i=1 & RS1 & simm13=0x0 & ASI { local tmp = RS1+segment(ASI); export tmp; } #special case when adding zero macro addflags(op1,op2) { - x_cf = carry(op1,op2); - x_vf = scarry(op1,op2); + x_cf = carry(op1,op2); + x_vf = scarry(op1,op2); - local tmp1 = op1:4; - local tmp2 = op2:4; + local tmp1 = op1:4; + local tmp2 = op2:4; - i_cf = carry(tmp1,tmp2); - i_vf = scarry(tmp1,tmp2); + i_cf = carry(tmp1,tmp2); + i_vf = scarry(tmp1,tmp2); } macro taddflags(op1,op2) { - addflags(op1,op2); - i_vf = i_vf || ((op1 & 0x3) != 0) || ((op2 & 0x3) != 0); + addflags(op1,op2); + i_vf = i_vf || ((op1 & 0x3) != 0) || ((op2 & 0x3) != 0); } macro addflags32(op1,op2) { - i_cf = carry(op1,op2); - i_vf = scarry(op1,op2); + i_cf = carry(op1,op2); + i_vf = scarry(op1,op2); } macro logicflags() { - x_cf = 0; - x_vf = 0; + x_cf = 0; + x_vf = 0; - i_cf = 0; - i_vf = 0; + i_cf = 0; + i_vf = 0; } macro subflags(op1,op2) { - x_cf = op1 < op2; - x_vf = sborrow(op1,op2); + x_cf = op1 < op2; + x_vf = sborrow(op1,op2); - local tmp1 = op1:4; - local tmp2 = op2:4; + local tmp1 = op1:4; + local tmp2 = op2:4; - i_cf = tmp1 < tmp2; - i_vf = sborrow(tmp1,tmp2); + i_cf = tmp1 < tmp2; + i_vf = sborrow(tmp1,tmp2); } macro zeroflags(op1) { - x_zf = (op1 == 0); - x_nf = (op1 s< 0); + x_zf = (op1 == 0); + x_nf = (op1 s< 0); - local tmp1 = op1:4; + local tmp1 = op1:4; - i_zf = (tmp1 == 0); - i_nf = (tmp1 s< 0); + i_zf = (tmp1 == 0); + i_nf = (tmp1 s< 0); } macro packflags(ccr) { - ccr = zext((x_nf << 7) | (x_zf << 6) | (x_vf << 5) | (x_cf << 4) | (i_nf << 3) | (i_zf << 2) | (i_vf << 1) | (i_cf << 0)); + ccr = zext((x_nf << 7) | (x_zf << 6) | (x_vf << 5) | (x_cf << 4) | (i_nf << 3) | (i_zf << 2) | (i_vf << 1) | (i_cf << 0)); } macro unpackflags(ccr) { - x_nf = (ccr & 0x80)!=0; - x_zf = (ccr & 0x40)!=0; - x_vf = (ccr & 0x20)!=0; - x_cf = (ccr & 0x10)!=0; - i_nf = (ccr & 0x8)!=0; - i_zf = (ccr & 0x4)!=0; - i_vf = (ccr & 0x2)!=0; - i_cf = (ccr & 0x1)!=0; + x_nf = (ccr & 0x80)!=0; + x_zf = (ccr & 0x40)!=0; + x_vf = (ccr & 0x20)!=0; + x_cf = (ccr & 0x10)!=0; + i_nf = (ccr & 0x8)!=0; + i_zf = (ccr & 0x4)!=0; + i_vf = (ccr & 0x2)!=0; + i_cf = (ccr & 0x1)!=0; } - - # --------------- +:add RS1,regorimm,rd is op=2 & rd & op3=0x0 & RS1 & regorimm {rd = RS1 + regorimm;} -:add RS1,regorimm,rd is op=2 & rd & op3=0x0 & RS1 & regorimm {rd = RS1 + regorimm;} +:addcc RS1,regorimm,rd is op=2 & rd & op3=0x10 & RS1 & regorimm {addflags(RS1,regorimm); + rd = RS1 + regorimm; + zeroflags(rd); +} -:addcc RS1,regorimm,rd is op=2 & rd & op3=0x10 & RS1 & regorimm {addflags(RS1,regorimm); - rd = RS1 + regorimm; - zeroflags(rd); } - -:addc RS1,regorimm,rd is op=2 & rd & op3=0x8 & RS1 & regorimm {rd = RS1 + regorimm + zext(i_cf);} +:addc RS1,regorimm,rd is op=2 & rd & op3=0x8 & RS1 & regorimm {rd = RS1 + regorimm + zext(i_cf);} -:addccc RS1,regorimm,rd is op=2 & rd & op3=0x18 & RS1 & regorimm {addflags(RS1,regorimm); - rd = RS1 + regorimm + zext(i_cf); - zeroflags(rd); } +:addccc RS1,regorimm,rd is op=2 & rd & op3=0x18 & RS1 & regorimm {addflags(RS1,regorimm); + rd = RS1 + regorimm + zext(i_cf); + zeroflags(rd); +} #----------------------- -:and RS1,regorimm,rd is op=2 & rd & op3=0x1 & RS1 & regorimm {rd = RS1 & regorimm;} +:and RS1,regorimm,rd is op=2 & rd & op3=0x1 & RS1 & regorimm {rd = RS1 & regorimm;} -:andcc RS1,regorimm,rd is op=2 & rd & op3=0x11 & RS1 & regorimm {logicflags(); - rd = RS1 & regorimm; - zeroflags(rd); } -:andn RS1,regorimm,rd is op=2 & rd & op3=0x5 & RS1 & regorimm {rd = RS1 & ~regorimm;} +:andcc RS1,regorimm,rd is op=2 & rd & op3=0x11 & RS1 & regorimm {logicflags(); + rd = RS1 & regorimm; + zeroflags(rd); +} +:andn RS1,regorimm,rd is op=2 & rd & op3=0x5 & RS1 & regorimm {rd = RS1 & ~regorimm;} -:andncc RS1,regorimm,rd is op=2 & rd & op3=0x15 & RS1 & regorimm {logicflags(); - rd = RS1 & ~regorimm; - zeroflags(rd); } +:andncc RS1,regorimm,rd is op=2 & rd & op3=0x15 & RS1 & regorimm {logicflags(); + rd = RS1 & ~regorimm; + zeroflags(rd); +} -:or RS1,regorimm,rd is op=2 & rd & op3=0x2 & RS1 & regorimm {rd = RS1 | regorimm;} +:or RS1,regorimm,rd is op=2 & rd & op3=0x2 & RS1 & regorimm {rd = RS1 | regorimm;} -:orcc RS1,regorimm,rd is op=2 & rd & op3=0x12 & RS1 & regorimm {logicflags(); - rd = RS1 | regorimm; - zeroflags(rd); } -:orn RS1,regorimm,rd is op=2 & rd & op3=0x6 & RS1 & regorimm {rd = RS1 | ~regorimm;} +:orcc RS1,regorimm,rd is op=2 & rd & op3=0x12 & RS1 & regorimm {logicflags(); + rd = RS1 | regorimm; + zeroflags(rd); +} +:orn RS1,regorimm,rd is op=2 & rd & op3=0x6 & RS1 & regorimm {rd = RS1 | ~regorimm;} -:orncc RS1,regorimm,rd is op=2 & rd & op3=0x16 & RS1 & regorimm {logicflags(); - rd = RS1 | ~regorimm; - zeroflags(rd); } -:xor RS1,regorimm,rd is op=2 & rd & op3=0x3 & RS1 & regorimm {rd = RS1 ^ regorimm;} +:orncc RS1,regorimm,rd is op=2 & rd & op3=0x16 & RS1 & regorimm {logicflags(); + rd = RS1 | ~regorimm; + zeroflags(rd); +} +:xor RS1,regorimm,rd is op=2 & rd & op3=0x3 & RS1 & regorimm {rd = RS1 ^ regorimm;} -:xorcc RS1,regorimm,rd is op=2 & rd & op3=0x13 & RS1 & regorimm {logicflags(); - rd = RS1 ^ regorimm; - zeroflags(rd); } -:xnor RS1,regorimm,rd is op=2 & rd & op3=0x7 & RS1 & regorimm {rd = RS1 ^ ~regorimm;} +:xorcc RS1,regorimm,rd is op=2 & rd & op3=0x13 & RS1 & regorimm {logicflags(); + rd = RS1 ^ regorimm; + zeroflags(rd); +} +:xnor RS1,regorimm,rd is op=2 & rd & op3=0x7 & RS1 & regorimm {rd = RS1 ^ ~regorimm;} -:xnorcc RS1,regorimm,rd is op=2 & rd & op3=0x17 & RS1 & regorimm {logicflags(); - rd = RS1 ^ ~regorimm; - zeroflags(rd); } +:xnorcc RS1,regorimm,rd is op=2 & rd & op3=0x17 & RS1 & regorimm {logicflags(); + rd = RS1 ^ ~regorimm; + zeroflags(rd); +} # --------------- -:ldsb ea,rd is op=3 & rd & op3=0x09 & ea { rd = sext(*:1 ea); } -:ldsh ea,rd is op=3 & rd & op3=0x0A & ea { rd = sext(*:2 ea); } -:ldsw ea,rd is op=3 & rd & op3=0x08 & ea { rd = sext(*:4 ea); } -:ldub ea,rd is op=3 & rd & op3=0x01 & ea { rd = zext(*:1 ea); } -:lduh ea,rd is op=3 & rd & op3=0x02 & ea { rd = zext(*:2 ea); } -:lduw ea,rd is op=3 & rd & op3=0x00 & ea { rd = zext(*:4 ea); } -:ldx ea,rd is op=3 & rd & op3=0x0b & ea { rd = *:$(SIZE) ea; } +:ldsb ea,rd is op=3 & rd & op3=0x09 & ea { rd = sext(*:1 ea); } +:ldsh ea,rd is op=3 & rd & op3=0x0A & ea { rd = sext(*:2 ea); } +:ldsw ea,rd is op=3 & rd & op3=0x08 & ea { rd = sext(*:4 ea); } +:ldub ea,rd is op=3 & rd & op3=0x01 & ea { rd = zext(*:1 ea); } +:lduh ea,rd is op=3 & rd & op3=0x02 & ea { rd = zext(*:2 ea); } +:lduw ea,rd is op=3 & rd & op3=0x00 & ea { rd = zext(*:4 ea); } +:ldx ea,rd is op=3 & rd & op3=0x0b & ea { rd = *:$(SIZE) ea; } @if SIZE=="8" -:ldd ea,rd is op=3 & rd & op3=0x03 & ea { rd = *:$(SIZE) ea; } +:ldd ea,rd is op=3 & rd & op3=0x03 & ea { rd = *:$(SIZE) ea; } + @else -:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea { tmp:8 = *:8 ea; rd_d = tmp; } +:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea +{ + tmp:8 = *:8 ea; + rd_d[32,32] = tmp(4); + rd_d[0,32] = tmp(0); +} + @endif -:ldsba ea_alt,rd is op=3 & rd & op3=0x19 & ea_alt { rd = sext(*:1 ea_alt); } -:ldsha ea_alt,rd is op=3 & rd & op3=0x1a & ea_alt { rd = sext(*:2 ea_alt); } -:ldswa ea_alt,rd is op=3 & rd & op3=0x18 & ea_alt { rd = sext(*:4 ea_alt); } -:lduba ea_alt,rd is op=3 & rd & op3=0x11 & ea_alt { rd = zext(*:1 ea_alt); } -:lduha ea_alt,rd is op=3 & rd & op3=0x12 & ea_alt { rd = zext(*:2 ea_alt); } -:lduwa ea_alt,rd is op=3 & rd & op3=0x10 & ea_alt { rd = zext(*:4 ea_alt); } +:ldsba ea_alt,rd is op=3 & rd & op3=0x19 & ea_alt { rd = sext(*:1 ea_alt); } +:ldsha ea_alt,rd is op=3 & rd & op3=0x1a & ea_alt { rd = sext(*:2 ea_alt); } +:ldswa ea_alt,rd is op=3 & rd & op3=0x18 & ea_alt { rd = sext(*:4 ea_alt); } +:lduba ea_alt,rd is op=3 & rd & op3=0x11 & ea_alt { rd = zext(*:1 ea_alt); } +:lduha ea_alt,rd is op=3 & rd & op3=0x12 & ea_alt { rd = zext(*:2 ea_alt); } +:lduwa ea_alt,rd is op=3 & rd & op3=0x10 & ea_alt { rd = zext(*:4 ea_alt); } -:ldxa ea_alt,rd is op=3 & rd & op3=0x1b & ea_alt { rd = *:$(SIZE) ea_alt; } -:ldda ea_alt,rd is op=3 & rd & op3=0x13 & ea_alt { rd = *:$(SIZE) ea_alt; } +:ldxa ea_alt,rd is op=3 & rd & op3=0x1b & ea_alt { rd = *:$(SIZE) ea_alt; } +:ldda ea_alt,rd is op=3 & rd & op3=0x13 & ea_alt { rd = *:$(SIZE) ea_alt; } #----------------- -:stb RD,ea is op=3 & RD & op3=0x05 & ea { *ea = RD:1; } -:sth RD,ea is op=3 & RD & op3=0x06 & ea { *ea = RD:2; } -:stw RD,ea is op=3 & RD & op3=0x04 & ea { *ea = RD:4; } +:stb RD,ea is op=3 & RD & op3=0x05 & ea { *ea = RD:1; } +:sth RD,ea is op=3 & RD & op3=0x06 & ea { *ea = RD:2; } +:stw RD,ea is op=3 & RD & op3=0x04 & ea { *ea = RD:4; } @if SIZE=="8" -:stx RD,ea is op=3 & RD & op3=0x0e & ea { *ea = RD; } -:std RD,ea is op=3 & RD & op3=0x07 & ea { *ea = RD; } +:stx RD,ea is op=3 & RD & op3=0x0e & ea { *ea = RD; } +:std RD,ea is op=3 & RD & op3=0x07 & ea { *ea = RD; } + @else # size = 4, but this extended store insn needs to write 8 bytes -:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea { *ea = rd_d:8; } -:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; } +:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea +{ + # There is a bug in the sleigh compiler that implements the tmp_hi:4 = rd_d[32,32] instruction incorrectly + #tmp_lo:4 = rd_d[0,32]; + #tmp_hi:4 = rd_d[32,32]; + #tmp:8 = zext(tmp_lo) + zext(tmp_hi << 32); + *ea = rd_d;#tmp; +} +:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; } + +:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea +{ + #tmp_lo:4 = rd_d[0,32]; + #tmp_hi:4 = rd_d[32,32]; + #tmp:8 = zext(tmp_lo) + zext(tmp_hi << 32); + *ea = rd_d;#tmp; +} +:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; } -:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea { *ea = rd_d:8; } -:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; } @endif -:stba RD,ea_alt is op=3 & RD & op3=0x15 & ea_alt { *ea_alt = RD:1; } -:stha RD,ea_alt is op=3 & RD & op3=0x16 & ea_alt { *ea_alt = RD:2; } -:stwa RD,ea_alt is op=3 & RD & op3=0x14 & ea_alt { *ea_alt = RD:4; } -:stxa RD,ea_alt is op=3 & RD & op3=0x1e & ea_alt { *ea_alt = RD; } -:stda RD,ea_alt is op=3 & RD & op3=0x17 & ea_alt { *ea_alt = RD; } +:stba RD,ea_alt is op=3 & RD & op3=0x15 & ea_alt { *ea_alt = RD:1; } +:stha RD,ea_alt is op=3 & RD & op3=0x16 & ea_alt { *ea_alt = RD:2; } +:stwa RD,ea_alt is op=3 & RD & op3=0x14 & ea_alt { *ea_alt = RD:4; } +:stxa RD,ea_alt is op=3 & RD & op3=0x1e & ea_alt { *ea_alt = RD; } +:stda RD,ea_alt is op=3 & RD & op3=0x17 & ea_alt { *ea_alt = RD; } # --------------- -:sub RS1,regorimm,rd is op=2 & rd & op3=0x4 & RS1 & regorimm {rd = RS1 - regorimm;} +:sub RS1,regorimm,rd is op=2 & rd & op3=0x4 & RS1 & regorimm {rd = RS1 - regorimm;} -:subcc RS1,regorimm,rd is op=2 & rd & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); - rd = RS1 - regorimm; - zeroflags(rd); } +:subcc RS1,regorimm,rd is op=2 & rd & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); + rd = RS1 - regorimm; + zeroflags(rd); +} -:subc RS1,regorimm,rd is op=2 & rd & op3=0xc & RS1 & regorimm {rd = RS1 - regorimm - zext(i_cf);} +:subc RS1,regorimm,rd is op=2 & rd & op3=0xc & RS1 & regorimm {rd = RS1 - regorimm - zext(i_cf);} -:subccc RS1,regorimm,rd is op=2 & rd & op3=0x1c & RS1 & regorimm {subflags(RS1,regorimm); - rd = RS1 - regorimm - zext(i_cf); - zeroflags(rd); } +:subccc RS1,regorimm,rd is op=2 & rd & op3=0x1c & RS1 & regorimm {subflags(RS1,regorimm); + rd = RS1 - regorimm - zext(i_cf); + zeroflags(rd); +} # --------------- -:nop is op=0x0 & rd=0x0 & op2=0x4 & disp22=0x0 { } +:nop is op=0x0 & rd=0x0 & op2=0x4 & disp22=0x0 { } # ---------------COMPARES -:cmp RS1,regorimm is op=0x2 & rd=0x0 & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); - local tmp = RS1 - regorimm; - zeroflags(tmp); } +:cmp RS1,regorimm is op=0x2 & rd=0x0 & op3=0x14 & RS1 & regorimm {subflags(RS1,regorimm); + local tmp = RS1 - regorimm; + zeroflags(tmp); +} # ---------------MOVES -:mov regorimm,rd is op=2 & rd & op3=0x2 & rs1=0 & regorimm {rd = regorimm;} +:mov regorimm,rd is op=2 & rd & op3=0x2 & rs1=0 & regorimm {rd = regorimm;} # This will not work until the rs1 field in a token can be used without being # part of the display portion below -RCOND: "z" is rcond3=1 & RS1 { tmp:1 = (RS1 == 0); export tmp; } -RCOND: "lez" is rcond3=2 & RS1 { tmp:1 = (RS1 s<= 0); export tmp; } -RCOND: "lz" is rcond3=3 & RS1 { tmp:1 = (RS1 s< 0); export tmp; } -RCOND: "nz" is rcond3=5 & RS1 { tmp:1 = (RS1 != 0); export tmp; } -RCOND: "gz" is rcond3=6 & RS1 { tmp:1 = (RS1 s> 0); export tmp; } -RCOND: "gez" is rcond3=7 & RS1 { tmp:1 = (RS1 s>= 0); export tmp; } -:movr^RCOND RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RCOND & regorimm10 & RS1 { - if !RCOND goto ; - rd = regorimm10; - +RCOND: "z" is rcond3=1 & RS1 { tmp:1 = (RS1 == 0); export tmp; } +RCOND: "lez" is rcond3=2 & RS1 { tmp:1 = (RS1 s<= 0); export tmp; } +RCOND: "lz" is rcond3=3 & RS1 { tmp:1 = (RS1 s< 0); export tmp; } +RCOND: "nz" is rcond3=5 & RS1 { tmp:1 = (RS1 != 0); export tmp; } +RCOND: "gz" is rcond3=6 & RS1 { tmp:1 = (RS1 s> 0); export tmp; } +RCOND: "gez" is rcond3=7 & RS1 { tmp:1 = (RS1 s>= 0); export tmp; } + +:movr^RCOND RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RCOND & regorimm10 & RS1 { + if !RCOND goto ; + rd = regorimm10; + } + #:movrz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=1 & regorimm10 { if (RS1 == 0) goto inst_next; rd = regorimm10; } #:movrlez RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=2 & regorimm10 { if (RS1 s<= 0) goto inst_next; rd = regorimm10; } #:movrlz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=3 & regorimm10 { if (RS1 s< 0) goto inst_next; rd = regorimm10; } #:movrnz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=5 & regorimm10 { if (RS1 != 0) goto inst_next; rd = regorimm10; } #:movrgz RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=6 & regorimm10 { if (RS1 s> 0) goto inst_next; rd = regorimm10; } #:movrgez RS1,regorimm10,rd is op=0x2 & rd & op3=0x2f & RS1 & rcond3=7 & regorimm10 { if (RS1 s>= 0) goto inst_next; rd = regorimm10; } +m_icc: "a" is cond4=0x8 { tmp:1=1; export tmp; } +m_icc: "n" is cond4=0x0 { tmp:1=0; export tmp; } +m_icc: "ne" is cond4=0x9 { tmp:1=!i_zf; export tmp; } +m_icc: "e" is cond4=0x1 { tmp:1=i_zf; export tmp; } +m_icc: "g" is cond4=0xa { tmp:1=!(i_zf || (i_nf ^^ i_vf)); export tmp; } +m_icc: "le" is cond4=0x2 { tmp:1=(i_zf || (i_nf ^^ i_vf)); export tmp; } +m_icc: "ge" is cond4=0xb { tmp:1=!(i_nf ^^ i_vf); export tmp; } +m_icc: "l" is cond4=0x3 { tmp:1=(i_nf ^^ i_vf); export tmp; } +m_icc: "gu" is cond4=0xc { tmp:1=!(i_cf || i_zf); export tmp; } +m_icc: "leu" is cond4=0x4 { tmp:1=(i_cf || i_zf); export tmp; } +m_icc: "cc" is cond4=0xd { tmp:1=!(i_cf); export tmp; } +m_icc: "cs" is cond4=0x5 { export i_cf; } +m_icc: "pos" is cond4=0xe { tmp:1=!(i_nf); export tmp; } +m_icc: "neg" is cond4=0x6 { export i_nf; } +m_icc: "vc" is cond4=0xf { tmp:1=!(i_vf); export tmp; } +m_icc: "vs" is cond4=0x7 { export i_vf; } -m_icc: "a" is cond4=0x8 { tmp:1=1; export tmp; } -m_icc: "n" is cond4=0x0 { tmp:1=0; export tmp; } -m_icc: "ne" is cond4=0x9 { tmp:1=!i_zf; export tmp; } -m_icc: "e" is cond4=0x1 { tmp:1=i_zf; export tmp; } -m_icc: "g" is cond4=0xa { tmp:1=!(i_zf || (i_nf ^^ i_vf)); export tmp; } -m_icc: "le" is cond4=0x2 { tmp:1=(i_zf || (i_nf ^^ i_vf)); export tmp; } -m_icc: "ge" is cond4=0xb { tmp:1=!(i_nf ^^ i_vf); export tmp; } -m_icc: "l" is cond4=0x3 { tmp:1=(i_nf ^^ i_vf); export tmp; } -m_icc: "gu" is cond4=0xc { tmp:1=!(i_cf || i_zf); export tmp; } -m_icc: "leu" is cond4=0x4 { tmp:1=(i_cf || i_zf); export tmp; } -m_icc: "cc" is cond4=0xd { tmp:1=!(i_cf); export tmp; } -m_icc: "cs" is cond4=0x5 { export i_cf; } -m_icc: "pos" is cond4=0xe { tmp:1=!(i_nf); export tmp; } -m_icc: "neg" is cond4=0x6 { export i_nf; } -m_icc: "vc" is cond4=0xf { tmp:1=!(i_vf); export tmp; } -m_icc: "vs" is cond4=0x7 { export i_vf; } - -m_xcc: "a" is cond4=0x8 { tmp:1=1; export tmp; } -m_xcc: "n" is cond4=0x0 { tmp:1=0; export tmp; } -m_xcc: "ne" is cond4=0x9 { tmp:1=!x_zf; export tmp; } -m_xcc: "e" is cond4=0x1 { tmp:1=x_zf; export tmp; } -m_xcc: "g" is cond4=0xa { tmp:1=!(x_zf || (x_nf ^^ x_vf)); export tmp; } -m_xcc: "le" is cond4=0x2 { tmp:1=(x_zf || (x_nf ^^ x_vf)); export tmp; } -m_xcc: "ge" is cond4=0xb { tmp:1=!(x_nf ^^ x_vf); export tmp; } -m_xcc: "l" is cond4=0x3 { tmp:1=(x_nf ^^ x_vf); export tmp; } -m_xcc: "gu" is cond4=0xc { tmp:1=!(x_cf || x_zf); export tmp; } -m_xcc: "leu" is cond4=0x4 { tmp:1=(x_cf || x_zf); export tmp; } -m_xcc: "cc" is cond4=0xd { tmp:1=!(x_cf); export tmp; } -m_xcc: "cs" is cond4=0x5 { export x_cf; } -m_xcc: "pos" is cond4=0xe { tmp:1=!(x_nf); export tmp; } -m_xcc: "neg" is cond4=0x6 { export x_nf; } -m_xcc: "vc" is cond4=0xf { tmp:1=!(x_vf); export tmp; } -m_xcc: "vs" is cond4=0x7 { export x_vf; } +m_xcc: "a" is cond4=0x8 { tmp:1=1; export tmp; } +m_xcc: "n" is cond4=0x0 { tmp:1=0; export tmp; } +m_xcc: "ne" is cond4=0x9 { tmp:1=!x_zf; export tmp; } +m_xcc: "e" is cond4=0x1 { tmp:1=x_zf; export tmp; } +m_xcc: "g" is cond4=0xa { tmp:1=!(x_zf || (x_nf ^^ x_vf)); export tmp; } +m_xcc: "le" is cond4=0x2 { tmp:1=(x_zf || (x_nf ^^ x_vf)); export tmp; } +m_xcc: "ge" is cond4=0xb { tmp:1=!(x_nf ^^ x_vf); export tmp; } +m_xcc: "l" is cond4=0x3 { tmp:1=(x_nf ^^ x_vf); export tmp; } +m_xcc: "gu" is cond4=0xc { tmp:1=!(x_cf || x_zf); export tmp; } +m_xcc: "leu" is cond4=0x4 { tmp:1=(x_cf || x_zf); export tmp; } +m_xcc: "cc" is cond4=0xd { tmp:1=!(x_cf); export tmp; } +m_xcc: "cs" is cond4=0x5 { export x_cf; } +m_xcc: "pos" is cond4=0xe { tmp:1=!(x_nf); export tmp; } +m_xcc: "neg" is cond4=0x6 { export x_nf; } +m_xcc: "vc" is cond4=0xf { tmp:1=!(x_vf); export tmp; } +m_xcc: "vs" is cond4=0x7 { export x_vf; } m_cc:m_icc is cc2_4=1 & cc1_4=0 & cc0_4=0 & m_icc { export m_icc; } m_cc:m_xcc is cc2_4=1 & cc1_4=1 & cc0_4=0 & m_xcc { export m_xcc; } -MICC: "%icc" is cc2_4=1 &cc1_4=0 { } -MICC: "%xcc" is cc2_4=1 &cc1_4=1 { } +MICC: "%icc" is cc2_4=1 &cc1_4=0 { } +MICC: "%xcc" is cc2_4=1 &cc1_4=1 { } -:mov^m_cc MICC,regorimm11,rd is op=0x2 & rd & op3=0x2c & m_cc & MICC & regorimm11 { - if (!m_cc) goto ; - rd = regorimm11; - +:mov^m_cc MICC,regorimm11,rd is op=0x2 & rd & op3=0x2c & m_cc & MICC & regorimm11 { + if (!m_cc) goto ; + rd = regorimm11; + } # ---------------BRANCHES +icc: "a" is cond=0x8 { tmp:1=1; export tmp; } +icc: "ne" is cond=0x9 { tmp:1=!i_zf; export tmp; } +icc: "e" is cond=0x1 { tmp:1=i_zf; export tmp; } +icc: "g" is cond=0xa { tmp:1=!(i_zf || (i_nf ^^ i_vf)); export tmp; } +icc: "le" is cond=0x2 { tmp:1=(i_zf || (i_nf ^^ i_vf)); export tmp; } +icc: "ge" is cond=0xb { tmp:1=!(i_nf ^^ i_vf); export tmp; } +icc: "l" is cond=0x3 { tmp:1=(i_nf ^^ i_vf); export tmp; } +icc: "gu" is cond=0xc { tmp:1=!(i_cf || i_zf); export tmp; } +icc: "leu" is cond=0x4 { tmp:1=(i_cf || i_zf); export tmp; } +icc: "cc" is cond=0xd { tmp:1=!(i_cf); export tmp; } +icc: "cs" is cond=0x5 { export i_cf; } +icc: "pos" is cond=0xe { tmp:1=!(i_nf); export tmp; } +icc: "neg" is cond=0x6 { export i_nf; } +icc: "vc" is cond=0xf { tmp:1=!(i_vf); export tmp; } +icc: "vs" is cond=0x7 { export i_vf; } -icc: "a" is cond=0x8 { tmp:1=1; export tmp; } -icc: "ne" is cond=0x9 { tmp:1=!i_zf; export tmp; } -icc: "e" is cond=0x1 { tmp:1=i_zf; export tmp; } -icc: "g" is cond=0xa { tmp:1=!(i_zf || (i_nf ^^ i_vf)); export tmp; } -icc: "le" is cond=0x2 { tmp:1=(i_zf || (i_nf ^^ i_vf)); export tmp; } -icc: "ge" is cond=0xb { tmp:1=!(i_nf ^^ i_vf); export tmp; } -icc: "l" is cond=0x3 { tmp:1=(i_nf ^^ i_vf); export tmp; } -icc: "gu" is cond=0xc { tmp:1=!(i_cf || i_zf); export tmp; } -icc: "leu" is cond=0x4 { tmp:1=(i_cf || i_zf); export tmp; } -icc: "cc" is cond=0xd { tmp:1=!(i_cf); export tmp; } -icc: "cs" is cond=0x5 { export i_cf; } -icc: "pos" is cond=0xe { tmp:1=!(i_nf); export tmp; } -icc: "neg" is cond=0x6 { export i_nf; } -icc: "vc" is cond=0xf { tmp:1=!(i_vf); export tmp; } -icc: "vs" is cond=0x7 { export i_vf; } +xcc: "a" is cond=0x8 { tmp:1=1; export tmp; } +xcc: "ne" is cond=0x9 { tmp:1=!x_zf; export tmp; } +xcc: "e" is cond=0x1 { tmp:1=x_zf; export tmp; } +xcc: "g" is cond=0xa { tmp:1=!(x_zf || (x_nf ^^ x_vf)); export tmp; } +xcc: "le" is cond=0x2 { tmp:1=(x_zf || (x_nf ^^ x_vf)); export tmp; } +xcc: "ge" is cond=0xb { tmp:1=!(x_nf ^^ x_vf); export tmp; } +xcc: "l" is cond=0x3 { tmp:1=(x_nf ^^ x_vf); export tmp; } +xcc: "gu" is cond=0xc { tmp:1=!(x_cf || x_zf); export tmp; } +xcc: "leu" is cond=0x4 { tmp:1=(x_cf || x_zf); export tmp; } +xcc: "cc" is cond=0xd { tmp:1=!(x_cf); export tmp; } +xcc: "cs" is cond=0x5 { export x_cf; } +xcc: "pos" is cond=0xe { tmp:1=!(x_nf); export tmp; } +xcc: "neg" is cond=0x6 { export x_nf; } +xcc: "vc" is cond=0xf { tmp:1=!(x_vf); export tmp; } +xcc: "vs" is cond=0x7 { export x_vf; } -xcc: "a" is cond=0x8 { tmp:1=1; export tmp; } -xcc: "ne" is cond=0x9 { tmp:1=!x_zf; export tmp; } -xcc: "e" is cond=0x1 { tmp:1=x_zf; export tmp; } -xcc: "g" is cond=0xa { tmp:1=!(x_zf || (x_nf ^^ x_vf)); export tmp; } -xcc: "le" is cond=0x2 { tmp:1=(x_zf || (x_nf ^^ x_vf)); export tmp; } -xcc: "ge" is cond=0xb { tmp:1=!(x_nf ^^ x_vf); export tmp; } -xcc: "l" is cond=0x3 { tmp:1=(x_nf ^^ x_vf); export tmp; } -xcc: "gu" is cond=0xc { tmp:1=!(x_cf || x_zf); export tmp; } -xcc: "leu" is cond=0x4 { tmp:1=(x_cf || x_zf); export tmp; } -xcc: "cc" is cond=0xd { tmp:1=!(x_cf); export tmp; } -xcc: "cs" is cond=0x5 { export x_cf; } -xcc: "pos" is cond=0xe { tmp:1=!(x_nf); export tmp; } -xcc: "neg" is cond=0x6 { export x_nf; } -xcc: "vc" is cond=0xf { tmp:1=!(x_vf); export tmp; } -xcc: "vs" is cond=0x7 { export x_vf; } +cc: icc is cc1=0 & cc0=0 & icc { export icc; } +cc: xcc is cc1=1 & cc0=0 & xcc { export xcc; } -cc: icc is cc1=0 & cc0=0 & icc { export icc; } -cc: xcc is cc1=1 & cc0=0 & xcc { export xcc; } +d16off: reloc is d16hi & d16lo [reloc = inst_start+4*((d16hi<<14) | d16lo);] { export *:$(SIZE) reloc; } -d16off: reloc is d16hi & d16lo [reloc = inst_start+4*((d16hi<<14) | d16lo);] {export *:$(SIZE) reloc;} +predict: ",pt" is p=1 { } +predict: ",pn" is p=0 { } -predict: ",pt" is p=1 { } -predict: ",pn" is p=0 { } +:brz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x1 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 == 0) goto d16off;} +:brlez^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x2 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s<= 0) goto d16off;} +:brlz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x3 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s< 0) goto d16off;} +:brnz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x5 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 != 0) goto d16off;} +:brgz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x6 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s> 0) goto d16off;} +:brgez^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x7 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s>= 0) goto d16off;} -:brz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x1 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 == 0) goto d16off;} -:brlez^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x2 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s<= 0) goto d16off;} -:brlz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x3 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s< 0) goto d16off;} -:brnz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x5 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 != 0) goto d16off;} -:brgz^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x6 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s> 0) goto d16off;} -:brgez^predict RS1,d16off is op=0 & a=0 & bit28=0 & rcond2=0x7 & op2=0x3 & RS1 & d16off & predict { delayslot(1); if (RS1 s>= 0) goto d16off;} +:brz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x1 & op2=0x3 & RS1 & d16off & predict { if (RS1 != 0) goto inst_next; delayslot(1); goto d16off;} +:brlez^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x2 & op2=0x3 & RS1 & d16off & predict { if (RS1 s> 0) goto inst_next; delayslot(1); goto d16off;} +:brlz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x3 & op2=0x3 & RS1 & d16off & predict { if (RS1 s>= 0) goto inst_next; delayslot(1); goto d16off;} +:brnz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x5 & op2=0x3 & RS1 & d16off & predict { if (RS1 == 0) goto inst_next; delayslot(1); goto d16off;} +:brgz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x6 & op2=0x3 & RS1 & d16off & predict { if (RS1 s<= 0) goto inst_next; delayslot(1); goto d16off;} +:brgez^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x7 & op2=0x3 & RS1 & d16off & predict { if (RS1 s< 0) goto inst_next; delayslot(1); goto d16off;} -:brz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x1 & op2=0x3 & RS1 & d16off & predict { if (RS1 != 0) goto inst_next; delayslot(1); goto d16off;} -:brlez^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x2 & op2=0x3 & RS1 & d16off & predict { if (RS1 s> 0) goto inst_next; delayslot(1); goto d16off;} -:brlz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x3 & op2=0x3 & RS1 & d16off & predict { if (RS1 s>= 0) goto inst_next; delayslot(1); goto d16off;} -:brnz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x5 & op2=0x3 & RS1 & d16off & predict { if (RS1 == 0) goto inst_next; delayslot(1); goto d16off;} -:brgz^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x6 & op2=0x3 & RS1 & d16off & predict { if (RS1 s<= 0) goto inst_next; delayslot(1); goto d16off;} -:brgez^",a"^predict RS1,d16off is op=0 & a=1 & bit28=0 & rcond2=0x7 & op2=0x3 & RS1 & d16off & predict { if (RS1 s< 0) goto inst_next; delayslot(1); goto d16off;} +BCC: "%icc" is cc0=0 & cc1=0 { } +BCC: "%xcc" is cc0=0 & cc1=1 { } -BCC: "%icc" is cc0=0 & cc1=0 { } -BCC: "%xcc" is cc0=0 & cc1=1 { } +reloff: reloc is disp22 [reloc=inst_start+(4*disp22);] { export *:$(SIZE) reloc; } +reloff64: reloc is disp19 [reloc=inst_start+(4*disp19);] { export *:$(SIZE) reloc; } -reloff: reloc is disp22 [reloc=inst_start+(4*disp22);] { export *:$(SIZE) reloc; } -reloff64: reloc is disp19 [reloc=inst_start+(4*disp19);] { export *:$(SIZE) reloc; } +skip: reloc is epsilon [reloc=inst_start+8;] { export *:$(SIZE) reloc; } -skip: reloc is epsilon [reloc=inst_start+8;] { export *:$(SIZE) reloc; } +:ba reloff is op=0x0 & op2=0x2 & a=0x0 & cond=0x8 & reloff { delayslot(1); goto reloff; } +:"ba,a" reloff is op=0x0 & op2=0x2 & a=0x1 & cond=0x8 & reloff { goto reloff; } -:ba reloff is op=0x0 & op2=0x2 & a=0x0 & cond=0x8 & reloff { delayslot(1); goto reloff; } -:"ba,a" reloff is op=0x0 & op2=0x2 & a=0x1 & cond=0x8 & reloff { goto reloff; } +:bn reloff is op=0x0 & op2=0x2 & a=0x0 & cond=0x0 & reloff { } +:"bn,a" reloff,skip is op=0x0 & op2=0x2 & a=0x1 & cond=0x0 & reloff & skip { goto skip; } -:bn reloff is op=0x0 & op2=0x2 & a=0x0 & cond=0x0 & reloff { } -:"bn,a" reloff,skip is op=0x0 & op2=0x2 & a=0x1 & cond=0x0 & reloff & skip { goto skip; } +:b^icc reloff is op=0x0 & op2=0x2 & a=0x0 & icc & reloff { delayslot(1); if (icc) goto reloff; } +:b^icc^",a" reloff is op=0x0 & op2=0x2 & a=0x1 & icc & reloff { if (!icc) goto inst_next; delayslot(1); goto reloff; } -:b^icc reloff is op=0x0 & op2=0x2 & a=0x0 & icc & reloff { delayslot(1); if (icc) goto reloff; } -:b^icc^",a" reloff is op=0x0 & op2=0x2 & a=0x1 & icc & reloff { if (!icc) goto inst_next; delayslot(1); goto reloff; } +:bpa^predict reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond=0x8 & reloff64 & predict { delayslot(1); goto reloff64; } +:"bpa,a"^predict reloff64 is op=0x0 & op2=0x1 & a=0x1 & cond=0x8 & reloff64 & predict { goto reloff64; } -:bpa^predict reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond=0x8 & reloff64 & predict { delayslot(1); goto reloff64; } -:"bpa,a"^predict reloff64 is op=0x0 & op2=0x1 & a=0x1 & cond=0x8 & reloff64 & predict { goto reloff64; } +:bpn^predict reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond=0x0 & reloff64 & predict { } +:"bpn,a"^predict reloff64,skip is op=0x0 & op2=0x1 & a=0x1 & cond=0x0 & reloff64 & predict & skip { goto skip; } -:bpn^predict reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond=0x0 & reloff64 & predict { } -:"bpn,a"^predict reloff64,skip is op=0x0 & op2=0x1 & a=0x1 & cond=0x0 & reloff64 & predict & skip { goto skip; } - -:bp^cc^predict BCC,reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond & cc & reloff64 & predict & BCC { delayslot(1); if (cc) goto reloff64; } -:bp^cc^",a"^predict BCC,reloff64 is op=0x0 & op2=0x1 & a=0x1 & cond & cc & reloff64 & predict & BCC { if (!cc) goto inst_next; delayslot(1); goto reloff64; } +:bp^cc^predict BCC,reloff64 is op=0x0 & op2=0x1 & a=0x0 & cond & cc & reloff64 & predict & BCC { delayslot(1); if (cc) goto reloff64; } +:bp^cc^",a"^predict BCC,reloff64 is op=0x0 & op2=0x1 & a=0x1 & cond & cc & reloff64 & predict & BCC { if (!cc) goto inst_next; delayslot(1); goto reloff64; } #:br^cc^predict reloff64 is op=0x0 & a=0x0 & op2=0x3 & cc & reloff64 & predict { delayslot(1); if (cc) goto reloff64; } #:br^cc^",a"^predict reloff64 is op=0x0 & a=0x1 & op2=0x3 & cc & reloff64 & predict { if (!cc) goto inst_next; delayslot(1); goto reloff64; } - #---------------CALL +callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] { export *:$(SIZE) reloc; } -callreloff: reloc is disp30 [reloc=inst_start+4*disp30;] {export *:$(SIZE) reloc;} - -:call callreloff is op=0x1 & callreloff -{ - o7=inst_start; didrestore=0; delayslot(1); call callreloff; if (didrestore==0) goto inst_next; return [o7]; +:call callreloff is op=0x1 & callreloff { + o7=inst_start; didrestore=0; delayslot(1); call callreloff; if (didrestore==0) goto inst_next; return [o7]; } # changing to jump for PIC call if destination is right below this one. -:call callreloff is op=0x1 & disp30=2 & callreloff -{ - o7=inst_start; delayslot(1); goto callreloff; +:call callreloff is op=0x1 & disp30=2 & callreloff { + o7=inst_start; delayslot(1); goto callreloff; } #----------------RET #----------------MULTIPLY AND DIVIDE 64 bit -:mulx RS1,regorimm,rd is op=2 & rd & op3=0x09 & RS1 & regorimm {rd = RS1 * regorimm;} -:sdivx RS1,regorimm,rd is op=2 & rd & op3=0x2d & RS1 & regorimm {rd = RS1 s/ regorimm;} -:udivx RS1,regorimm,rd is op=2 & rd & op3=0x0d & RS1 & regorimm {rd = RS1 / regorimm;} +:mulx RS1,regorimm,rd is op=2 & rd & op3=0x09 & RS1 & regorimm {rd = RS1 * regorimm;} +:sdivx RS1,regorimm,rd is op=2 & rd & op3=0x2d & RS1 & regorimm {rd = RS1 s/ regorimm;} +:udivx RS1,regorimm,rd is op=2 & rd & op3=0x0d & RS1 & regorimm {rd = RS1 / regorimm;} #----------------MULTIPLY 32 bit - @if SIZE=="8" -:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} -:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} -:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} -:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} +:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} +:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32;} +:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} +:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} + @else # size = 4 -:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm { - tmp_RS1:8 = zext(RS1); tmp_regorimm:8 = zext(regorimm); - tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; } +:umul RS1,regorimm,rd is op=2 & rd & op3=0x0a & RS1 & regorimm { + tmp_RS1:8 = zext(RS1); tmp_regorimm:8 = zext(regorimm); + tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; +} -:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm { - tmp_RS1:8 = sext(RS1); tmp_regorimm:8 = sext(regorimm); - tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; } - -:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} -:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} +:smul RS1,regorimm,rd is op=2 & rd & op3=0x0b & RS1 & regorimm { + tmp_RS1:8 = sext(RS1); tmp_regorimm:8 = sext(regorimm); + tmp:8 = tmp_RS1 * tmp_regorimm; rd = tmp:4; tmp2:8 = tmp >> 32; Y = tmp2:4; +} +:umulcc RS1,regorimm,rd is op=2 & rd & op3=0x1a & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} +:smulcc RS1,regorimm,rd is op=2 & rd & op3=0x1b & RS1 & regorimm {rd = zext(RS1:4) * zext(regorimm:4); Y=rd>>32; zeroflags(rd); logicflags();} @endif #----------------MULTIPLY Step -:mulscc RS1,regorimm,rd is op=2 & rd & op3=0x24 & RS1 & regorimm { tmp:4 = RS1:4 >> 1; - ccr:4 = zext(i_nf ^^ i_vf); - ccr = ccr << 31; - tmp = tmp | ccr; - multiplicand:4 = (Y:4 & 0x1) * regorimm:4; - addflags32(tmp, multiplicand); - tmp = tmp + multiplicand; - rd = zext(tmp); - zeroflags(rd); - local tbit = (RS1 & 0x1) << 31; - Y = (Y >> 1) | tbit; - } +:mulscc RS1,regorimm,rd is op=2 & rd & op3=0x24 & RS1 & regorimm { tmp:4 = RS1:4 >> 1; + ccr:4 = zext(i_nf ^^ i_vf); + ccr = ccr << 31; + tmp = tmp | ccr; + multiplicand:4 = (Y:4 & 0x1) * regorimm:4; + addflags32(tmp, multiplicand); + tmp = tmp + multiplicand; + rd = zext(tmp); + zeroflags(rd); + local tbit = (RS1 & 0x1) << 31; + Y = (Y >> 1) | tbit; +} #----------------DIVIDE (64-bit / 32-bit) # NB- Beware, the plus + operator has higher precdence than shift << # (These are Java rules. C rules have shift and + at the same level, so left to right) -:udiv RS1,regorimm,rd is op=2 & rd & op3=0x0e & RS1 & regorimm { - numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); - denom:$(SIZE) = regorimm & 0xffffffff; - rd = numerator / denom; - } -:sdiv RS1,regorimm,rd is op=2 & rd & op3=0x0f & RS1 & regorimm { - numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); - denom:$(SIZE) = regorimm & 0xffffffff; - rd = numerator s/ denom; - } +:udiv RS1,regorimm,rd is op=2 & rd & op3=0x0e & RS1 & regorimm { + numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); + denom:$(SIZE) = regorimm & 0xffffffff; + rd = numerator / denom; +} +:sdiv RS1,regorimm,rd is op=2 & rd & op3=0x0f & RS1 & regorimm { + numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); + denom:$(SIZE) = regorimm & 0xffffffff; + rd = numerator s/ denom; +} -:udivcc RS1,regorimm,rd is op=2 & rd & op3=0x1e & RS1 & regorimm { - numerator:$(SIZE)= ( Y << 32) + (RS1 & 0xffffffff); - denom:$(SIZE) = regorimm & 0xffffffff; - rd = numerator / denom; - zeroflags(rd); - i_vf = rd > 0xffffffff; - i_cf = 0; - x_vf = 0; - x_cf = 0; - } -:sdivcc RS1,regorimm,rd is op=2 & rd & op3=0x1f & RS1 & regorimm { - numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); - denom:$(SIZE) = regorimm & 0xffffffff; - rd = numerator s/ denom; - zeroflags(rd); - i_vf = (rd s>= 0x80000000) || (rd s<= -0x7ffffffff); - i_cf = 0; - x_vf = 0; - x_cf = 0; - } +:udivcc RS1,regorimm,rd is op=2 & rd & op3=0x1e & RS1 & regorimm { + numerator:$(SIZE)= ( Y << 32) + (RS1 & 0xffffffff); + denom:$(SIZE) = regorimm & 0xffffffff; + rd = numerator / denom; + zeroflags(rd); + i_vf = rd > 0xffffffff; + i_cf = 0; + x_vf = 0; + x_cf = 0; +} +:sdivcc RS1,regorimm,rd is op=2 & rd & op3=0x1f & RS1 & regorimm { + numerator:$(SIZE)= (Y << 32) + (RS1 & 0xffffffff); + denom:$(SIZE) = regorimm & 0xffffffff; + rd = numerator s/ denom; + zeroflags(rd); + i_vf = (rd s>= 0x80000000) || (rd s<= -0x7ffffffff); + i_cf = 0; + x_vf = 0; + x_cf = 0; +} #---------------SHIFT -:sll RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=0 & RS1 & reg_or_shcnt { rd=RS1<>reg_or_shcnt; } +:sll RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=0 & RS1 & reg_or_shcnt { rd=RS1<>reg_or_shcnt; } -:sllx RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=1 & RS1 & reg_or_shcnt { rd=RS1<>reg_or_shcnt; } +:sllx RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x25 & x=1 & RS1 & reg_or_shcnt { rd=RS1<>reg_or_shcnt; } -:sra RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=0 & RS1 & reg_or_shcnt { tmp:4=RS1:4; rd=sext(tmp s>> reg_or_shcnt); } -:srax RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=1 & RS1 & reg_or_shcnt { rd=RS1 s>> reg_or_shcnt; } +:sra RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=0 & RS1 & reg_or_shcnt { tmp:4=RS1:4; rd=sext(tmp s>> reg_or_shcnt); } +:srax RS1,reg_or_shcnt,rd is op=0x2 & rd & op3=0x27 & x=1 & RS1 & reg_or_shcnt { rd=RS1 s>> reg_or_shcnt; } - -rreg: "%ASI" is rs1_3=3 & i=0 { tmp:$(SIZE) = zext(ASI); export tmp; } -rreg: "%fprs" is rs1_3=6 & i=0 { tmp:$(SIZE) = zext(fprs); export tmp; } -rreg: "%ccr" is rs1_3=2 & i=0 { tmp:$(SIZE) = zext(CCR); export tmp; } -rreg: PC is rs1_3=5 & PC & i=0 { export inst_start; } -rreg: rs1_3 is rs1_3 & i=0 { export rs1_3; } +rreg: "%ASI" is rs1_3=3 & i=0 { tmp:$(SIZE) = zext(ASI); export tmp; } +rreg: "%fprs" is rs1_3=6 & i=0 { tmp:$(SIZE) = zext(fprs); export tmp; } +rreg: "%ccr" is rs1_3=2 & i=0 { tmp:$(SIZE) = zext(CCR); export tmp; } +rreg: PC is rs1_3=5 & PC & i=0 { export inst_start; } +rreg: rs1_3 is rs1_3 & i=0 { export rs1_3; } #---------------RD special register +:rd rreg,rd is op=0x2 & rd & op3=0x28 & rreg & i=0 { rd = rreg; } +:rd rreg,rd is op=0x2 & rd & op3=0x28 & rs1_3=2 & rreg & i=0 { packflags(rd); } -:rd rreg,rd is op=0x2 & rd & op3=0x28 & rreg & i=0 { rd = rreg; } -:rd rreg,rd is op=0x2 & rd & op3=0x28 & rs1_3=2 & rreg & i=0 { packflags(rd); } +wrASI: "%ASI" is rd=3 { } -wrASI: "%ASI" is rd=3 {} -wrFPRS: "%fprs" is rd=6 {} -wrCCR: "%ccr" is rd=2 {} +wrFPRS: "%fprs" is rd=6 { } + +wrCCR: "%ccr" is rd=2 { } #---------------WR special register -:wr regorimm,wrASI is op=0x2 & regorimm & op3=0x30 & rd=3 & wrASI { ASI = regorimm:1; } -:wr regorimm,wrFPRS is op=0x2 & regorimm & op3=0x30 & rd=6 & wrFPRS { fprs = regorimm:1; } -:wr regorimm,wrCCR is op=0x2 & regorimm & op3=0x30 & rd=2 & wrCCR { unpackflags(regorimm); } -:wr regorimm,rd is op=0x2 & regorimm & op3=0x30 & rd { rd = regorimm; } +:wr regorimm,wrASI is op=0x2 & regorimm & op3=0x30 & rd=3 & wrASI { ASI = regorimm:1; } +:wr regorimm,wrFPRS is op=0x2 & regorimm & op3=0x30 & rd=6 & wrFPRS { fprs = regorimm:1; } +:wr regorimm,wrCCR is op=0x2 & regorimm & op3=0x30 & rd=2 & wrCCR { unpackflags(regorimm); } +:wr regorimm,rd is op=0x2 & regorimm & op3=0x30 & rd { rd = regorimm; } #---------------MISC +sethidisp: "%hi("^hi^")" is udisp22 [hi=udisp22<<10;] { export *[const]:$(SIZE) hi; } -sethidisp: "%hi("^hi^")" is udisp22 [hi=udisp22<<10;] { export *[const]:$(SIZE) hi; } +:sethi sethidisp,rd is rd & op=0x0 & op2=0x4 & sethidisp { rd=sethidisp; } -:sethi sethidisp,rd is rd & op=0x0 & op2=0x4 & sethidisp { rd=sethidisp; } +:popc regorimm, rd is op=0x2 & rd & op3=0x2e & rs1=0 & regorimm { rd = popc(regorimm); } -:popc regorimm, rd is op=0x2 & rd & op3=0x2e & rs1=0 & regorimm { rd = popc(regorimm); } +:save RS1,regorimm,rd is op=0x2 & rd & op3=0x3c & RS1 & regorimm { local tmp = RS1 + regorimm; save(); rd = tmp; } -:save RS1,regorimm,rd is op=0x2 & rd & op3=0x3c & RS1 & regorimm { local tmp = RS1 + regorimm; save(); rd = tmp; } +:restore RS1,regorimm,rd is op=0x2 & rd & op3=0x3d & RS1 & regorimm { local tmp = RS1 + regorimm; restore(); didrestore=1; rd = tmp; } +:restore is op=0x2 & rd=0 & op3=0x3d { restore(); didrestore=1; } -:restore RS1,regorimm,rd is op=0x2 & rd & op3=0x3d & RS1 & regorimm { local tmp = RS1 + regorimm; restore(); didrestore=1; rd = tmp; } -:restore is op=0x2 & rd=0 & op3=0x3d { restore(); didrestore=1; } +:return retea is op=0x2 & op3=0x39 & retea { restore(); delayslot(1); didrestore=1; return [retea]; } -:return retea is op=0x2 & op3=0x39 & retea { restore(); delayslot(1); didrestore=1; return [retea]; } +jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; } -jmplreloff: reloc is rd [reloc=inst_start+8;] { export reloc; } - -:jmpl retea,rd is op=0x2 & rd & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); goto [retea]; } +:jmpl retea,rd is op=0x2 & rd & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); goto [retea]; } # special case where link register is loaded with return address -:jmpl retea,rd is op=0x2 & rd & prd=15 & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); call [retea]; } +:jmpl retea,rd is op=0x2 & rd & prd=15 & op3=0x38 & retea & jmplreloff { rd = inst_start; delayslot(1); call [retea]; } -:jmpl retea is op=0x2 & rd=0 & op3=0x38 & retea { o7=inst_start; delayslot(1); goto [retea]; } -:ret is op=0x2 & rd=0 & rs1=31 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; } -:retl is op=0x2 & rd=0 & rs1=15 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; } +:jmpl retea is op=0x2 & rd=0 & op3=0x38 & retea { o7=inst_start; delayslot(1); goto [retea]; } +:ret is op=0x2 & rd=0 & rs1=31 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; } +:retl is op=0x2 & rd=0 & rs1=15 & op3=0x38 & i=1 & simm13=8 & retea { delayslot(1); return [retea]; } +casa_ea: [RS1]imm_asi is i=0 & RS1 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+segment(tmp1); export tmp; } +casa_ea: [RS1]%ASI is i=1 & RS1 & ASI { local tmp = RS1+segment(ASI); export tmp; } -casa_ea: [RS1]imm_asi is i=0 & RS1 & imm_asi { local tmp1:1 = imm_asi; local tmp = RS1+segment(tmp1); export tmp; } -casa_ea: [RS1]%ASI is i=1 & RS1 & ASI { local tmp = RS1+segment(ASI); export tmp; } +:casa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3c & casa_ea & RS2 { local tmp:4=rd:4; rd=zext(*:4 casa_ea); if ((RS2 & 0xFFFFFFFF)!=rd) goto ; *:4 casa_ea=tmp; } +:casxa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3e & casa_ea & RS2 { local tmp=rd; rd=*:$(SIZE) casa_ea; if (RS2!=rd) goto ; *:$(SIZE) casa_ea=tmp; } -:casa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3c & casa_ea & RS2 { local tmp:4=rd:4; rd=zext(*:4 casa_ea); if ((RS2 & 0xFFFFFFFF)!=rd) goto inst_next; *:4 casa_ea=tmp; } -:casxa casa_ea,RS2,rd is op=0x3 & rd & op3=0x3e & casa_ea & RS2 { local tmp=rd; rd=*:$(SIZE) casa_ea; if (RS2!=rd) goto inst_next; *:$(SIZE) casa_ea=tmp; } +:impdef1 is op=0x2 & op3=0x36 unimpl +:impdef2 is op=0x2 & op3=0x37 unimpl -:impdef1 is op=0x2 & op3=0x36 unimpl -:impdef2 is op=0x2 & op3=0x37 unimpl +:ldstub ea,rd is op=0x3 & rd & op3=0xd & ea { rd = zext(*:1 ea); *:1 ea = 0xFF; } +:ldstuba ea_alt,rd is op=0x3 & rd & op3=0x1d & ea_alt { rd = zext(*:1 ea_alt); *:1 ea_alt = 0xFF; } -:ldstub ea,rd is op=0x3 & rd & op3=0xd & ea { rd = zext(*:1 ea); *:1 ea = 0xFF; } -:ldstuba ea_alt,rd is op=0x3 & rd & op3=0x1d & ea_alt { rd = zext(*:1 ea_alt); *:1 ea_alt = 0xFF; } +:swap ea,rd is op=0x3 & rd & op3=0xF & ea { tmp:4=rd:4; rd = zext(*:4 ea); *:4 ea = tmp; } +:swapa ea_alt,rd is op=0x3 & rd & op3=0x1F & ea_alt { tmp:4=rd:4; rd = zext(*:4 ea_alt); *:4 ea_alt = tmp; } -:swap ea,rd is op=0x3 & rd & op3=0xF & ea { tmp:4=rd:4; rd = zext(*:4 ea); *:4 ea = tmp; } -:swapa ea_alt,rd is op=0x3 & rd & op3=0x1F & ea_alt { tmp:4=rd:4; rd = zext(*:4 ea_alt); *:4 ea_alt = tmp; } +:taddcc RS1,regorimm,rd is op=2 & rd & op3=0x20 & RS1 & regorimm {taddflags(RS1,regorimm); + rd = RS1 + regorimm; + zeroflags(rd); +} +:taddcctv RS1,regorimm,rd is op=2 & rd & op3=0x22 & RS1 & regorimm {taddflags(RS1,regorimm); + rd = RS1 + regorimm; + zeroflags(rd); +} +:tsubcc RS1,regorimm,rd is op=2 & rd & op3=0x21 & RS1 & regorimm {taddflags(RS1,regorimm); + rd = RS1 - regorimm; + zeroflags(rd); +} +:tsubcctv RS1,regorimm,rd is op=2 & rd & op3=0x23 & RS1 & regorimm {taddflags(RS1,regorimm); + rd = RS1 - regorimm; + zeroflags(rd); +} -:taddcc RS1,regorimm,rd is op=2 & rd & op3=0x20 & RS1 & regorimm {taddflags(RS1,regorimm); - rd = RS1 + regorimm; - zeroflags(rd); } -:taddcctv RS1,regorimm,rd is op=2 & rd & op3=0x22 & RS1 & regorimm {taddflags(RS1,regorimm); - rd = RS1 + regorimm; - zeroflags(rd); } -:tsubcc RS1,regorimm,rd is op=2 & rd & op3=0x21 & RS1 & regorimm {taddflags(RS1,regorimm); - rd = RS1 - regorimm; - zeroflags(rd); } -:tsubcctv RS1,regorimm,rd is op=2 & rd & op3=0x23 & RS1 & regorimm {taddflags(RS1,regorimm); - rd = RS1 - regorimm; - zeroflags(rd); } -tcc: icc is cc1_4=0 & cc0_4=0 & icc { export icc; } -tcc: xcc is cc1_4=1 & cc0_4=0 & xcc { export xcc; } -TICC: "%icc" is cc1_4=0 &cc0_4=0 { } -TICC: "%xcc" is cc1_4=1 &cc0_4=0 { } -trap: RS1+RS2 is i=0 & RS1 & RS2 { local tmp = ((RS1 + RS2) & 0x7F); export tmp; } -trap: RS1+swtrap is i=1 & RS1 & swtrap { local tmp = ((RS1 + swtrap) & 0x7F); export tmp; } +tcc: icc is cc1_4=0 & cc0_4=0 & icc { export icc; } +tcc: xcc is cc1_4=1 & cc0_4=0 & xcc { export xcc; } -:t^tcc TICC, trap is op=0x2 & op3=0x3a & tcc & TICC & trap { sw_trap(trap); } +TICC: "%icc" is cc1_4=0 &cc0_4=0 { } +TICC: "%xcc" is cc1_4=1 &cc0_4=0 { } -membar_mask: is cmask & mmask { tmp:1 = (cmask << 4) | mmask; export tmp; } -:membar membar_mask is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=1 & membar_mask {} +trap: RS1+RS2 is i=0 & RS1 & RS2 { local tmp = ((RS1 + RS2) & 0x7F); export tmp; } +trap: RS1+swtrap is i=1 & RS1 & swtrap { local tmp = ((RS1 + swtrap) & 0x7F); export tmp; } -:stbar is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=0 {} +:t^tcc TICC, trap is op=0x2 & op3=0x3a & tcc & TICC & trap { sw_trap(trap); } + +membar_mask: is cmask & mmask { tmp:1 = (cmask << 4) | mmask; export tmp; } + +:membar membar_mask is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=1 & membar_mask {} + +:stbar is op=0x2 & rd=0 & op3=0x28 & rs1=0xF & i=0 {} + +:sir simm13 is op=0x2 & rd=0xF & op3=0x30 & rs1=0x0 & i=1 & simm13 { reset(); } -:sir simm13 is op=0x2 & rd=0xF & op3=0x30 & rs1=0x0 & i=1 & simm13 { reset(); } - attach variables [ prs1 prd ] [ TPC1 TNPC1 TSTATE1 TT1 TCK TBA PSTATE TL PIL CWP CANSAVE CANRESTORE CLEANWIN OTHERWIN WSTATE FQ GL _ _ _ _ _ _ _ _ _ _ _ _ _ _ VER ]; -tnpc: "%tnpc" is fcn {local reloc = zext(TL == 1)*&TNPC1 + zext(TL == 2)*&TNPC2 + zext(TL == 3)*&TNPC3 + zext(TL ==4)*&TNPC4; export reloc;} -tpc: "%tpc" is fcn {local reloc = zext(TL == 1)*&TPC1 + zext(TL == 2)*&TPC2 + zext(TL == 3)*&TPC3 + zext(TL ==4)*&TPC4; export reloc;} -tt: "%tt" is fcn {local tmp = zext(TL == 1)* &TT1 + zext(TL == 2)*&TT2 + zext(TL == 3)*&TT3 + zext(TL ==4)*&TT4; export tmp;} -tstate: "%tstate" is fcn {local tmp = zext(TL == 1)* &TSTATE1 + zext(TL == 2)* &TSTATE2 + zext(TL == 3)* &TSTATE3 + zext(TL==4)* &TSTATE4; export tmp;} +tnpc: "%tnpc" is fcn { local reloc = zext(TL == 1)*&TNPC1 + zext(TL == 2)*&TNPC2 + zext(TL == 3)*&TNPC3 + zext(TL ==4)*&TNPC4; export reloc; } + +tpc: "%tpc" is fcn { local reloc = zext(TL == 1)*&TPC1 + zext(TL == 2)*&TPC2 + zext(TL == 3)*&TPC3 + zext(TL ==4)*&TPC4; export reloc; } + +tt: "%tt" is fcn { local tmp = zext(TL == 1)* &TT1 + zext(TL == 2)*&TT2 + zext(TL == 3)*&TT3 + zext(TL ==4)*&TT4; export tmp; } + +tstate: "%tstate" is fcn { local tmp = zext(TL == 1)* &TSTATE1 + zext(TL == 2)* &TSTATE2 + zext(TL == 3)* &TSTATE3 + zext(TL==4)* &TSTATE4; export tmp; } # prs1 is same bits as rs1 # prd is same bits as rd -:rdpr prs1,rd is op=0x2 & rd & op3=0x2A & prs1 {rd = prs1; } -:rdpr tpc,rd is op=0x2 & prs1 = 0 & rd & op3=0x2A & tpc { rd = *[register]:$(SIZE) tpc; } -:rdpr tnpc,rd is op=0x2 & prs1 = 1 & rd & op3=0x2A & tnpc {rd = *[register]:$(SIZE) tnpc; } -:rdpr tt,rd is op=0x2 & prs1 = 2 & rd & op3=0x2A & tt { rd = *[register]:$(SIZE) tt; } -:rdpr tstate,rd is op=0x2 & prs1 = 3 & rd & op3=0x2A & tstate {rd = *[register]:$(SIZE) tstate;} +:rdpr prs1,rd is op=0x2 & rd & op3=0x2A & prs1 {rd = prs1; } +:rdpr tpc,rd is op=0x2 & prs1 = 0 & rd & op3=0x2A & tpc { rd = *[register]:$(SIZE) tpc; } +:rdpr tnpc,rd is op=0x2 & prs1 = 1 & rd & op3=0x2A & tnpc {rd = *[register]:$(SIZE) tnpc; } +:rdpr tt,rd is op=0x2 & prs1 = 2 & rd & op3=0x2A & tt { rd = *[register]:$(SIZE) tt; } +:rdpr tstate,rd is op=0x2 & prs1 = 3 & rd & op3=0x2A & tstate {rd = *[register]:$(SIZE) tstate;} -:wrpr RS1,regorimm,prd is op=0x2 & prd & op3=0x32 & RS1 & regorimm {prd = RS1^regorimm; } -:wrpr RS1,regorimm,tpc is op=0x2 & prd = 0 & op3=0x32 & RS1 & regorimm & tpc { *[register]:$(SIZE) tpc = RS1^regorimm; } -:wrpr RS1,regorimm,tnpc is op=0x2 & prd = 1 & op3=0x32 & RS1 & regorimm & tnpc { *[register]:$(SIZE) tnpc = RS1^regorimm; } -:wrpr RS1,regorimm,tstate is op=0x2 & prd = 2 & op3=0x32 & RS1 & regorimm & tstate { *[register]:$(SIZE) tstate = RS1^regorimm; } -:wrpr RS1,regorimm,tt is op=0x2 & prd = 3 & op3=0x32 & RS1 & regorimm & tt { *[register]:$(SIZE) tt = RS1^regorimm; } +:wrpr RS1,regorimm,prd is op=0x2 & prd & op3=0x32 & RS1 & regorimm {prd = RS1^regorimm; } +:wrpr RS1,regorimm,tpc is op=0x2 & prd = 0 & op3=0x32 & RS1 & regorimm & tpc { *[register]:$(SIZE) tpc = RS1^regorimm; } +:wrpr RS1,regorimm,tnpc is op=0x2 & prd = 1 & op3=0x32 & RS1 & regorimm & tnpc { *[register]:$(SIZE) tnpc = RS1^regorimm; } +:wrpr RS1,regorimm,tstate is op=0x2 & prd = 2 & op3=0x32 & RS1 & regorimm & tstate { *[register]:$(SIZE) tstate = RS1^regorimm; } +:wrpr RS1,regorimm,tt is op=0x2 & prd = 3 & op3=0x32 & RS1 & regorimm & tt { *[register]:$(SIZE) tt = RS1^regorimm; } + +hpstate: "%hpstate" is fcn { local reloc = zext(TL == 1)*&HPSTATE1 + zext(TL == 2)*&HPSTATE2 + zext(TL == 3)*&HPSTATE3 + zext(TL ==4)*&HPSTATE4; export reloc; } + +htstate: "%htstate" is fcn { local reloc = zext(TL == 1)*&HTSTATE1 + zext(TL == 2)*&HTSTATE2 + zext(TL == 3)*&HTSTATE3 + zext(TL ==4)*&HTSTATE4; export reloc; } + +hintp: "%hintp" is fcn { local reloc = zext(TL == 1)*&HINTP1 + zext(TL == 2)*&HINTP2 + zext(TL == 3)*&HINTP3 + zext(TL ==4)*&HINTP4; export reloc; } + +htba: "%htba" is fcn { local reloc = zext(TL == 1)*&HTBA1 + zext(TL == 2)*&HTBA2 + zext(TL == 3)*&HTBA3 + zext(TL ==4)*&HTBA4; export reloc; } + +hver: "%hver" is fcn { local reloc = zext(TL == 1)*&HVER1 + zext(TL == 2)*&HVER2 + zext(TL == 3)*&HVER3 + zext(TL ==4)*&HVER4; export reloc; } + +hsys_tick_cmpr: "%hstick_cmpr" is fcn { local reloc = zext(TL == 1)*&HSTICK_CMPR1 + zext(TL == 2)*&HSTICK_CMPR2 + zext(TL == 3)*&HSTICK_CMPR3 + zext(TL ==4)*&HSTICK_CMPR4; export reloc; } + +resv30: "%resv30" is fcn { local reloc = zext(TL == 1)*&RESV30_1 + zext(TL == 2)*&RESV30_2 + zext(TL == 3)*&RESV30_3 + zext(TL ==4)*&RESV30_4; export reloc; } + +:rdhpr hpstate,rd is op=0x2 & prs1 = 0 & rd & op3=0x29 & hpstate { rd = *[register]:$(SIZE) hpstate; } +:rdhpr htstate,rd is op=0x2 & prs1 = 1 & rd & op3=0x29 & htstate { rd = *[register]:$(SIZE) htstate; } +:rdhpr hintp,rd is op=0x2 & prs1 = 3 & rd & op3=0x29 & hintp { rd = *[register]:$(SIZE) hintp; } +:rdhpr htba,rd is op=0x2 & prs1 = 5 & rd & op3=0x29 & htba { rd = *[register]:$(SIZE) htba; } +:rdhpr hver,rd is op=0x2 & prs1 = 6 & rd & op3=0x29 & hver { rd = *[register]:$(SIZE) hver; } +:rdhpr hsys_tick_cmpr,rd is op=0x2 & prs1 = 31 & rd & op3=0x29 & hsys_tick_cmpr { rd = *[register]:$(SIZE) hsys_tick_cmpr; } +:rdhpr resv30,rd is op=0x2 & prs1 = 30 & rd & op3=0x29 & resv30 { rd = *[register]:$(SIZE) resv30; } + +:wrhpr RS1,regorimm,hpstate is op=0x2 & prd = 0 & op3=0x33 & RS1 & regorimm & hpstate { *[register]:$(SIZE) hpstate = RS1^regorimm; } +:wrhpr RS1,regorimm,htstate is op=0x2 & prd = 1 & op3=0x33 & RS1 & regorimm & htstate { *[register]:$(SIZE) htstate = RS1^regorimm; } +:wrhpr RS1,regorimm,hintp is op=0x2 & prd = 3 & op3=0x33 & RS1 & regorimm & hintp { *[register]:$(SIZE) hintp = RS1^regorimm; } +:wrhpr RS1,regorimm,htba is op=0x2 & prd = 5 & op3=0x33 & RS1 & regorimm & htba { *[register]:$(SIZE) htba = RS1^regorimm; } +:wrhpr RS1,regorimm,hsys_tick_cmpr is op=0x2 & prd = 31 & op3=0x33 & RS1 & regorimm & hsys_tick_cmpr { *[register]:$(SIZE) hsys_tick_cmpr = RS1^regorimm; } +:wrhpr RS1,regorimm,resv30 is op=0x2 & prd = 30 & op3=0x33 & RS1 & regorimm & resv30 { *[register]:$(SIZE) resv30 = RS1^regorimm; } -hpstate: "%hpstate" is fcn {local reloc = zext(TL == 1)*&HPSTATE1 + zext(TL == 2)*&HPSTATE2 + zext(TL == 3)*&HPSTATE3 + zext(TL ==4)*&HPSTATE4; export reloc;} -htstate: "%htstate" is fcn {local reloc = zext(TL == 1)*&HTSTATE1 + zext(TL == 2)*&HTSTATE2 + zext(TL == 3)*&HTSTATE3 + zext(TL ==4)*&HTSTATE4; export reloc;} -hintp: "%hintp" is fcn {local reloc = zext(TL == 1)*&HINTP1 + zext(TL == 2)*&HINTP2 + zext(TL == 3)*&HINTP3 + zext(TL ==4)*&HINTP4; export reloc;} -htba: "%htba" is fcn {local reloc = zext(TL == 1)*&HTBA1 + zext(TL == 2)*&HTBA2 + zext(TL == 3)*&HTBA3 + zext(TL ==4)*&HTBA4; export reloc;} -hver: "%hver" is fcn {local reloc = zext(TL == 1)*&HVER1 + zext(TL == 2)*&HVER2 + zext(TL == 3)*&HVER3 + zext(TL ==4)*&HVER4; export reloc;} -hsys_tick_cmpr: "%hstick_cmpr" is fcn {local reloc = zext(TL == 1)*&HSTICK_CMPR1 + zext(TL == 2)*&HSTICK_CMPR2 + zext(TL == 3)*&HSTICK_CMPR3 + zext(TL ==4)*&HSTICK_CMPR4; export reloc;} +:done is op = 2 & fcn = 0 & op3 = 0x3e & tnpc {TL=TL-1;return [tnpc]; } +:retry is op = 2 & fcn = 1 & op3 = 0x3e & tpc {TL=TL-1;return [tpc]; } -resv30: "%resv30" is fcn {local reloc = zext(TL == 1)*&RESV30_1 + zext(TL == 2)*&RESV30_2 + zext(TL == 3)*&RESV30_3 + zext(TL ==4)*&RESV30_4; export reloc;} - -:rdhpr hpstate,rd is op=0x2 & prs1 = 0 & rd & op3=0x29 & hpstate { rd = *[register]:$(SIZE) hpstate; } -:rdhpr htstate,rd is op=0x2 & prs1 = 1 & rd & op3=0x29 & htstate { rd = *[register]:$(SIZE) htstate; } -:rdhpr hintp,rd is op=0x2 & prs1 = 3 & rd & op3=0x29 & hintp { rd = *[register]:$(SIZE) hintp; } -:rdhpr htba,rd is op=0x2 & prs1 = 5 & rd & op3=0x29 & htba { rd = *[register]:$(SIZE) htba; } -:rdhpr hver,rd is op=0x2 & prs1 = 6 & rd & op3=0x29 & hver { rd = *[register]:$(SIZE) hver; } -:rdhpr hsys_tick_cmpr,rd is op=0x2 & prs1 = 31 & rd & op3=0x29 & hsys_tick_cmpr { rd = *[register]:$(SIZE) hsys_tick_cmpr; } -:rdhpr resv30,rd is op=0x2 & prs1 = 30 & rd & op3=0x29 & resv30 { rd = *[register]:$(SIZE) resv30; } - -:wrhpr RS1,regorimm,hpstate is op=0x2 & prd = 0 & op3=0x33 & RS1 & regorimm & hpstate { *[register]:$(SIZE) hpstate = RS1^regorimm; } -:wrhpr RS1,regorimm,htstate is op=0x2 & prd = 1 & op3=0x33 & RS1 & regorimm & htstate { *[register]:$(SIZE) htstate = RS1^regorimm; } -:wrhpr RS1,regorimm,hintp is op=0x2 & prd = 3 & op3=0x33 & RS1 & regorimm & hintp { *[register]:$(SIZE) hintp = RS1^regorimm; } -:wrhpr RS1,regorimm,htba is op=0x2 & prd = 5 & op3=0x33 & RS1 & regorimm & htba { *[register]:$(SIZE) htba = RS1^regorimm; } -:wrhpr RS1,regorimm,hsys_tick_cmpr is op=0x2 & prd = 31 & op3=0x33 & RS1 & regorimm & hsys_tick_cmpr { *[register]:$(SIZE) hsys_tick_cmpr = RS1^regorimm; } -:wrhpr RS1,regorimm,resv30 is op=0x2 & prd = 30 & op3=0x33 & RS1 & regorimm & resv30 { *[register]:$(SIZE) resv30 = RS1^regorimm; } - - - -:done is op = 2 & fcn = 0 & op3 = 0x3e & tnpc {TL=TL-1;return [tnpc]; } -:retry is op = 2 & fcn = 1 & op3 = 0x3e & tpc {TL=TL-1;return [tpc]; } - -:flush ea is op = 2 & op3 = 0x3b & ea {} -:flushw is op = 2 & op3 = 0x2b & i = 0 {} +:flush ea is op = 2 & op3 = 0x3b & ea {} +:flushw is op = 2 & op3 = 0x2b & i = 0 {} define pcodeop IllegalInstructionTrap; -:illtrap const22 is op = 0 & op3 = 0 & const22 { +:illtrap const22 is op = 0 & op3 = 0 & const22 { IllegalInstructionTrap(const22:4); tmp:$(SIZE) = 0; # trap - don't fall-thru - return [ tmp ]; + return [ tmp ]; } -:prefetch ea,fcn is op=3 & fcn & op3 = 0x2d & ea {} -:prefetcha ea_alt,fcn is op=3 & fcn & op3 = 0x3d & ea_alt {} -:restored is op = 2 & fcn=1 & op3 = 0x31 {} -:saved is op = 2 & fcn = 0 & op3 = 0x31 {} +:prefetch ea,fcn is op=3 & fcn & op3 = 0x2d & ea {} +:prefetcha ea_alt,fcn is op=3 & fcn & op3 = 0x3d & ea_alt {} +:restored is op = 2 & fcn=1 & op3 = 0x31 {} +:saved is op = 2 & fcn = 0 & op3 = 0x31 {} -# TODO: floating point - - - attach variables [fsrd fsrs1 fsrs2 ] [ fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 @@ -1062,223 +1058,219 @@ define pcodeop sta; define pcodeop stda; define pcodeop stqa; -:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = abs(fsrs2); } -:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = abs(fdrs2); } -:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = abs(fqrs2); } +:fabss fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x9 & fsrs2 { fsrd = abs(fsrs2); } +:fabsd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xa & fdrs2 { fdrd = abs(fdrs2); } +:fabsq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xb & fqrs2 { fqrd = abs(fqrs2); } -:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fsrs1 f+ fsrs2; } -:faddd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x42 & fdrs2 { fdrd = fdrs1 f+ fdrs2; } -:faddq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x43 & fqrs2 { fqrd = fqrs1 f+ fqrs2; } +:fadds fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x41 & fsrs2 { fsrd = fsrs1 f+ fsrs2; } +:faddd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x42 & fdrs2 { fdrd = fdrs1 f+ fdrs2; } +:faddq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x43 & fqrs2 { fqrd = fqrs1 f+ fqrs2; } -:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fsrs1 f/ fsrs2; } -:fdivd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4e & fdrs2 { fdrd = fdrs1 f/ fdrs2; } -:fdivq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4f & fqrs2 { fqrd = fqrs1 f/ fqrs2; } +:fdivs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x4d & fsrs2 { fsrd = fsrs1 f/ fsrs2; } +:fdivd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4e & fdrs2 { fdrd = fdrs1 f/ fdrs2; } +:fdivq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4f & fqrs2 { fqrd = fqrs1 f/ fqrs2; } -:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 -{ +:fdmulq fdrs1,fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fdrs1 & opf=0x6e & fdrs2 { tmp1:16 = float2float(fdrs1); tmp2:16 = float2float(fdrs2); fqrd = tmp1 f* tmp2; } -:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 -{ +:fsmuld fsrs1,fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fsrs1 & opf=0x69 & fsrs2 { tmp1:8 = float2float(fsrs1); tmp2:8 = float2float(fsrs2); fdrd = tmp1 f* tmp2; } -:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = int2float(fsrs2); } -:fitod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fdrs2 { fdrd = int2float(fdrs2); } -:fitoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fqrs2 { fqrd = int2float(fqrs2); } +:fitos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc4 & fsrs2 { fsrd = int2float(fsrs2); } +:fitod fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc8 & fsrs2 { fdrd = int2float(fsrs2); } +:fitoq fsrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcc & fsrs2 { fqrd = int2float(fsrs2); } -:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fsrs2; } -:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fdrs2; } -:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fqrs2; } +:fmovs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x1 & fsrs2 { fsrd = fsrs2; } +:fmovd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2 & fdrs2 { fdrd = fdrs2; } +:fmovq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x3 & fqrs2 { fqrd = fqrs2; } -:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fsrs1 f* fsrs2; } -:fmuld fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4a & fdrs2 { fdrd = fdrs1 f* fdrs2; } -:fmulq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4b & fqrs2 { fqrd = fqrs1 f* fqrs2; } +:fmuls fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x49 & fsrs2 { fsrd = fsrs1 f* fsrs2; } +:fmuld fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x4a & fdrs2 { fdrd = fdrs1 f* fdrs2; } +:fmulq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x4b & fqrs2 { fqrd = fqrs1 f* fqrs2; } -:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = f- fsrs2; } -:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = f- fdrs2; } -:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = f- fqrs2; } +:fnegs fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x5 & fsrs2 { fsrd = f- fsrs2; } +:fnegd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x6 & fdrs2 { fdrd = f- fdrs2; } +:fnegq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x7 & fqrs2 { fqrd = f- fqrs2; } -:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsrs1 f- fsrs2; } -:fsubd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x46 & fdrs2 { fdrd = fdrs1 f- fdrs2; } -:fsubq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x47 & fqrs2 { fqrd = fqrs1 f- fqrs2; } +:fsubs fsrs1,fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & fsrs1 & opf=0x45 & fsrs2 { fsrd = fsrs1 f- fsrs2; } +:fsubd fdrs1,fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & fdrs1 & opf=0x46 & fdrs2 { fdrd = fdrs1 f- fdrs2; } +:fsubq fqrs1,fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & fqrs1 & opf=0x47 & fqrs2 { fqrd = fqrs1 f- fqrs2; } -:fxtos fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fsrs2 { fsrd = int2float(fsrs2); } -:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = int2float(fdrs2); } -:fxtoq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fqrs2 { fqrd = int2float(fqrs2); } +:fxtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x84 & fdrs2 { fsrd = int2float(fdrs2); } +:fxtod fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x88 & fdrs2 { fdrd = int2float(fdrs2); } +:fxtoq fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x8c & fdrs2 { fqrd = int2float(fdrs2); } -:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = trunc(fsrs2); } -:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = trunc(fdrs2); } -:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = trunc(fqrs2); } +:fstoi fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xd1 & fsrs2 { fsrd = trunc(fsrs2); } +:fdtoi fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xd2 & fdrs2 { fdrd = trunc(fdrs2); } +:fqtoi fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xd3 & fqrs2 { fqrd = trunc(fqrs2); } -:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = trunc(fsrs2); } -:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = trunc(fdrs2); } -:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = trunc(fqrs2); } +:fstox fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x81 & fsrs2 { fsrd = trunc(fsrs2); } +:fdtox fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x82 & fdrs2 { fdrd = trunc(fdrs2); } +:fqtox fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x83 & fqrs2 { fqrd = trunc(fqrs2); } -:fstod fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc9 & fsrs2 { fsrd = trunc(fsrs2); } -:fstoq fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcd & fdrs2 { fdrd = trunc(fdrs2); } +:fstod fsrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc9 & fsrs2 { fdrd = float2float(fsrs2); } +:fstoq fsrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcd & fsrs2 { fqrd = float2float(fsrs2); } -:fdtos fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xc6 & fqrs2 { fqrd = trunc(fqrs2); } -:fdtoq fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xce & fsrs2 { fsrd = trunc(fsrs2); } +:fdtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc6 & fdrs2 { fsrd = float2float(fdrs2); } +:fdtoq fdrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xce & fdrs2 { fqrd = float2float(fdrs2); } -:fqtos fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xc7 & fdrs2 { fdrd = trunc(fdrs2); } -:fqtod fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0xcb & fqrs2 { fqrd = trunc(fqrs2); } +:fqtos fdrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0xc7 & fdrs2 { fsrd = float2float(fdrs2); } +:fqtod fqrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0xcb & fqrs2 { fdrd = float2float(fqrs2); } -:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = sqrt(fsrs2); } -:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = sqrt(fdrs2); } -:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = sqrt(fqrs2); } +:fsqrts fsrs2,fsrd is op=0x2 & fsrd & op3=0x34 & opf=0x29 & fsrs2 { fsrd = sqrt(fsrs2); } +:fsqrtd fdrs2,fdrd is op=0x2 & fdrd & op3=0x34 & opf=0x2a & fdrs2 { fdrd = sqrt(fdrs2); } +:fsqrtq fqrs2,fqrd is op=0x2 & fqrd & op3=0x34 & opf=0x2b & fqrs2 { fqrd = sqrt(fqrs2); } -:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = *:4 ea; } -:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = *:8 ea; } -:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = *:16 ea; } -:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { fsr = *:2 ea; } -:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { fsr = *:2 ea; } +:ld ea,fsrd is op=3 & fsrd & op3=0x20 & ea { fsrd = *:4 ea; } +:ldd ea,fdrd is op=3 & fdrd & op3=0x23 & ea { fdrd = *:8 ea; } +:ldq ea,fqrd is op=3 & fqrd & op3=0x22 & ea { fqrd = *:16 ea; } +:ld ea,"%fsr" is op=3 & op3=0x21 & rd=0 & ea { fsr = *:2 ea; } +:ldx ea,"%fsr" is op=3 & op3=0x21 & rd=1 & ea { fsr = *:2 ea; } -:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = *:4 ea_alt; } -:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = *:8 ea_alt; } -:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = *:16 ea_alt; } +:lda ea_alt,fsrd is op=3 & fsrd & op3=0x30 & ea_alt { fsrd = *:4 ea_alt; } +:ldda ea_alt,fdrd is op=3 & fdrd & op3=0x33 & ea_alt { fdrd = *:8 ea_alt; } +:ldqa ea_alt,fqrd is op=3 & fqrd & op3=0x32 & ea_alt { fqrd = *:16 ea_alt; } -:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { *ea = fsrd:4; } -:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { *ea = fdrd:8; } -:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { *ea = fqrd:16; } -:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { *ea = fsr; } -:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { *ea = fsr; } +:st fsrd,ea is op=3 & fsrd & op3=0x24 & ea { *ea = fsrd:4; } +:std fdrd,ea is op=3 & fdrd & op3=0x27 & ea { *ea = fdrd:8; } +:stq fqrd,ea is op=3 & fqrd & op3=0x26 & ea { *ea = fqrd:16; } +:st "%fsr",ea is op=3 & op3=0x25 & rd=0 & ea { *ea = fsr; } +:stx "%fsr",ea is op=3 & op3=0x25 & rd=1 & ea { *ea = fsr; } -:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { *ea_alt = fsrd:4; } -:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { *ea_alt = fdrd:8; } -:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { *ea_alt = fqrd:16; } +:sta fsrd,ea_alt is op=3 & fsrd & op3=0x34 & ea_alt { *ea_alt = fsrd:4; } +:stda fdrd,ea_alt is op=3 & fdrd & op3=0x37 & ea_alt { *ea_alt = fdrd:8; } +:stqa fqrd,ea_alt is op=3 & fqrd & op3=0x36 & ea_alt { *ea_alt = fqrd:16; } -fcc0_or_fccn: is op2=6 { export fcc0; } -fcc0_or_fccn: is op2=5 & fccn {export fccn; } +fcc0_or_fccn: is op2=6 { export fcc0; } +fcc0_or_fccn: is op2=5 & fccn { export fccn; } +fcc: "u" is cond=0x7 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 3); export tmp; } +fcc: "g" is cond=0x6 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2); export tmp; } +fcc: "ug" is cond=0x5 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2 || fcc0_or_fccn == 3); export tmp; } +fcc: "l" is cond=0x4 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1); export tmp; } +fcc: "ul" is cond=0x3 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn ==3); export tmp; } +fcc: "lg" is cond=0x2 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn ==2); export tmp; } +fcc: "ne" is cond=0x1 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn == 2 || fcc0_or_fccn ==3); export tmp; } +fcc: "e" is cond=0x9 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0); export tmp; } +fcc: "ue" is cond=0xa & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 3); export tmp; } +fcc: "ge" is cond=0xb & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 2); export tmp; } +fcc: "uge" is cond=0xc & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 2 || fcc0_or_fccn == 3); export tmp; } +fcc: "le" is cond=0xd & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1); export tmp; } +fcc: "ule" is cond=0xe & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1 || fcc0_or_fccn ==3); export tmp; } +fcc: "o" is cond=0xf & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1 || fcc0_or_fccn ==2); export tmp; } -fcc: "u" is cond=0x7 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0); export tmp; } -fcc: "g" is cond=0x6 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2); export tmp; } -fcc: "ug" is cond=0x5 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 2 || fcc0_or_fccn == 3); export tmp; } -fcc: "l" is cond=0x4 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1); export tmp; } -fcc: "ul" is cond=0x3 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn ==3); export tmp; } -fcc: "lg" is cond=0x2 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn ==2); export tmp; } -fcc: "ne" is cond=0x1 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 1 || fcc0_or_fccn == 2 || fcc0_or_fccn ==3); export tmp; } -fcc: "e" is cond=0x9 & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0); export tmp; } -fcc: "ue" is cond=0xa & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 3); export tmp; } -fcc: "ge" is cond=0xb & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 2); export tmp; } -fcc: "uge" is cond=0xc & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 2 || fcc0_or_fccn == 3); export tmp; } -fcc: "le" is cond=0xd & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1); export tmp; } -fcc: "ule" is cond=0xe & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1 || fcc0_or_fccn ==3); export tmp; } -fcc: "o" is cond=0xf & fcc0_or_fccn { tmp:1=(fcc0_or_fccn == 0 || fcc0_or_fccn == 1 || fcc0_or_fccn ==2); export tmp; } +:fba reloff is op=0x0 & op2=0x6 & a=0x0 & cond=0x8 & reloff { delayslot(1); goto reloff; } +:"fba,a" reloff is op=0x0 & op2=0x6 & a=0x1 & cond=0x8 & reloff { goto reloff; } -:fba reloff is op=0x0 & op2=0x6 & a=0x0 & cond=0x8 & reloff { delayslot(1); goto reloff; } -:"fba,a" reloff is op=0x0 & op2=0x6 & a=0x1 & cond=0x8 & reloff { goto reloff; } +:fbn reloff is op=0x0 & op2=0x6 & a=0x0 & cond=0x0 & reloff { } +:"fbn,a" reloff,skip is op=0x0 & op2=0x6 & a=0x1 & cond=0x0 & reloff & skip { goto skip; } -:fbn reloff is op=0x0 & op2=0x6 & a=0x0 & cond=0x0 & reloff { } -:"fbn,a" reloff,skip is op=0x0 & op2=0x6 & a=0x1 & cond=0x0 & reloff & skip { goto skip; } +:fb^fcc reloff is op=0x0 & op2=0x6 & a=0x0 & fcc & reloff { delayslot(1); if (fcc) goto reloff; } +:fb^fcc^",a" reloff is op=0x0 & op2=0x6 & a=0x1 & fcc & reloff { if (!fcc) goto inst_next; delayslot(1); goto reloff; } -:fb^fcc reloff is op=0x0 & op2=0x6 & a=0x0 & fcc & reloff { delayslot(1); if (fcc) goto reloff; } -:fb^fcc^",a" reloff is op=0x0 & op2=0x6 & a=0x1 & fcc & reloff { if (!fcc) goto inst_next; delayslot(1); goto reloff; } +:fb^fcc^predict "%"fccn,reloff64 is op=0x0 & op2=0x5 & a=0x0 & fcc & reloff64 & predict & fccn { delayslot(1); if (fcc) goto reloff64; } +:fb^fcc^",a"^predict "%"^fccn,reloff64 is op=0x0 & op2=0x5 & a=0x1 & fcc & reloff64 & predict & fccn { if (!fcc) goto inst_next; delayslot(1); goto reloff64; } -:fb^fcc^predict "%"fccn,reloff64 is op=0x0 & op2=0x5 & a=0x0 & fcc & reloff64 & predict & fccn { delayslot(1); if (fcc) goto reloff64; } -:fb^fcc^",a"^predict "%"^fccn,reloff64 is op=0x0 & op2=0x5 & a=0x1 & fcc & reloff64 & predict & fccn { if (!fcc) goto inst_next; delayslot(1); goto reloff64; } - -macro fcmp(f1, f2, fccn) -{ +macro fcmp(f1, f2, fccn) { # fcc value | relation # 0 | f1 = f2 # 1 | f1 < f2 # 2 | f1 > f2 # 3 | f1 or f2 NaN - fccn = (1*(f1 s< f2)) + (2*(f1 s> f2)) + (3*(nan(f1) || nan(f2))); + fccn = (1*(f1 f< f2)) + (2*(f1 f> f2)) + (3*(nan(f1) || nan(f2))); } -:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } -:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } -:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } -:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } -:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } -:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } +:fcmps %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x51 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } +:fcmpd %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x52 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } +:fcmpq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x53 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } +:fcmpes %fccn2,fsrs1,fsrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x55 & fsrs1 & fsrs2 { fcmp(fsrs1, fsrs2, fccn2); } +:fcmped %fccn2,fdrs1,fdrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x56 & fdrs1 & fdrs2 { fcmp(fdrs1, fdrs2, fccn2); } +:fcmpeq %fccn2,fqrs1,fqrs2 is op=0x2 & fpc=0 & fccn2 & op3=0x35 & opf=0x57 & fqrs1 & fqrs2 { fcmp(fqrs1, fqrs2, fccn2); } Z: is opf_cc=4 { export i_zf; } Z: is opf_cc=6 { export x_zf; } + C: is opf_cc=4 { export i_cf; } C: is opf_cc=6 { export x_cf; } + N: is opf_cc=4 { export i_nf; } N: is opf_cc=6 { export x_nf; } + V: is opf_cc=4 { export i_vf; } V: is opf_cc=6 { export x_vf; } - # floating-point move with integer condition codes - -fmicc: "a" is cond4=0x8 { tmp:1=1; export tmp; } -fmicc: "n" is cond4=0x0 { tmp:1=0; export tmp; } -fmicc: "ne" is cond4=0x9 & Z { tmp:1=!Z; export tmp; } -fmicc: "e" is cond4=0x1 & Z { export Z; } -fmicc: "g" is cond4=0xa & Z & N & V { tmp:1=!(Z|(N^V)) ; export tmp; } -fmicc: "le" is cond4=0x2 & Z & N & V { tmp:1= (Z|(N^V)) ; export tmp; } -fmicc: "ge" is cond4=0xb & N & V { tmp:1=!(N^V) ; export tmp; } -fmicc: "l" is cond4=0x3 & N & V { tmp:1= (N^V) ; export tmp; } -fmicc: "gu" is cond4=0xc & C & Z { tmp:1=!(C|Z); export tmp; } -fmicc: "leu" is cond4=0x4 & C & Z { tmp:1= (C|Z); export tmp; } -fmicc: "cc" is cond4=0xd & C { tmp:1=!C; export tmp; } -fmicc: "cs" is cond4=0x5 & C { tmp:1=C; export tmp; } -fmicc: "pos" is cond4=0xe & N { tmp:1=!N; export tmp; } -fmicc: "neg" is cond4=0x6 & N { tmp:1=N; export tmp; } -fmicc: "vc" is cond4=0xf & V { tmp:1=!V; export tmp; } -fmicc: "vs" is cond4=0x7 & V { tmp:1=V; export tmp; } +fmicc: "a" is cond4=0x8 { tmp:1=1; export tmp; } +fmicc: "n" is cond4=0x0 { tmp:1=0; export tmp; } +fmicc: "ne" is cond4=0x9 & Z { tmp:1=!Z; export tmp; } +fmicc: "e" is cond4=0x1 & Z { export Z; } +fmicc: "g" is cond4=0xa & Z & N & V { tmp:1=!(Z|(N^V)); export tmp; } +fmicc: "le" is cond4=0x2 & Z & N & V { tmp:1= (Z|(N^V)); export tmp; } +fmicc: "ge" is cond4=0xb & N & V { tmp:1=!(N^V); export tmp; } +fmicc: "l" is cond4=0x3 & N & V { tmp:1= (N^V); export tmp; } +fmicc: "gu" is cond4=0xc & C & Z { tmp:1=!(C|Z); export tmp; } +fmicc: "leu" is cond4=0x4 & C & Z { tmp:1= (C|Z); export tmp; } +fmicc: "cc" is cond4=0xd & C { tmp:1=!C; export tmp; } +fmicc: "cs" is cond4=0x5 & C { tmp:1=C; export tmp; } +fmicc: "pos" is cond4=0xe & N { tmp:1=!N; export tmp; } +fmicc: "neg" is cond4=0x6 & N { tmp:1=N; export tmp; } +fmicc: "vc" is cond4=0xf & V { tmp:1=!V; export tmp; } +fmicc: "vs" is cond4=0x7 & V { tmp:1=V; export tmp; } # floating-point move with floating-point condition codes +fmfcc: "a" is cond4=0x8 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } +fmfcc: "n" is cond4=0x0 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } +fmfcc: "u" is cond4=0x7 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } +fmfcc: "g" is cond4=0x6 & fccn_4 { tmp:1=(fccn_4 == 2); export tmp; } +fmfcc: "ug" is cond4=0x5 & fccn_4 { tmp:1=(fccn_4 == 2 || fccn_4 == 3); export tmp; } +fmfcc: "l" is cond4=0x4 & fccn_4 { tmp:1=(fccn_4 == 1); export tmp; } +fmfcc: "ul" is cond4=0x3 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 ==3); export tmp; } +fmfcc: "lg" is cond4=0x2 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 ==2); export tmp; } +fmfcc: "ne" is cond4=0x1 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 == 2 || fccn_4 ==3); export tmp; } +fmfcc: "e" is cond4=0x9 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } +fmfcc: "ue" is cond4=0xa & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 3); export tmp; } +fmfcc: "ge" is cond4=0xb & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 2); export tmp; } +fmfcc: "uge" is cond4=0xc & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 2 || fccn_4 == 3); export tmp; } +fmfcc: "le" is cond4=0xd & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1); export tmp; } +fmfcc: "ule" is cond4=0xe & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==3); export tmp; } +fmfcc: "o" is cond4=0xf & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==2); export tmp; } -fmfcc: "a" is cond4=0x8 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } -fmfcc: "n" is cond4=0x0 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } -fmfcc: "u" is cond4=0x7 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } -fmfcc: "g" is cond4=0x6 & fccn_4 { tmp:1=(fccn_4 == 2); export tmp; } -fmfcc: "ug" is cond4=0x5 & fccn_4 { tmp:1=(fccn_4 == 2 || fccn_4 == 3); export tmp; } -fmfcc: "l" is cond4=0x4 & fccn_4 { tmp:1=(fccn_4 == 1); export tmp; } -fmfcc: "ul" is cond4=0x3 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 ==3); export tmp; } -fmfcc: "lg" is cond4=0x2 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 ==2); export tmp; } -fmfcc: "ne" is cond4=0x1 & fccn_4 { tmp:1=(fccn_4 == 1 || fccn_4 == 2 || fccn_4 ==3); export tmp; } -fmfcc: "e" is cond4=0x9 & fccn_4 { tmp:1=(fccn_4 == 0); export tmp; } -fmfcc: "ue" is cond4=0xa & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 3); export tmp; } -fmfcc: "ge" is cond4=0xb & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 2); export tmp; } -fmfcc: "uge" is cond4=0xc & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 2 || fccn_4 == 3); export tmp; } -fmfcc: "le" is cond4=0xd & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1); export tmp; } -fmfcc: "ule" is cond4=0xe & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==3); export tmp; } -fmfcc: "o" is cond4=0xf & fccn_4 { tmp:1=(fccn_4 == 0 || fccn_4 == 1 || fccn_4 ==2); export tmp; } - -fmfcc_or_fmicc: fmfcc is bit18=0 & fmfcc { export fmfcc; } -fmfcc_or_fmicc: fmicc is bit18=1 & fmicc { export fmicc; } +fmfcc_or_fmicc: fmfcc is bit18=0 & fmfcc { export fmfcc; } +fmfcc_or_fmicc: fmicc is bit18=1 & fmicc { export fmicc; } -fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 { } -fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 { } -fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 { } +fcc_icc_xcc: "%"^fccn_4 is bit18=0 & fccn_4 { } +fcc_icc_xcc: "%icc" is bit18=1 & opf_cc=4 { } +fcc_icc_xcc: "%xcc" is bit18=1 & opf_cc=6 { } :fmovs^fmfcc_or_fmicc fcc_icc_xcc,fsrs2,fsrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=1 & fsrs2 & fsrd - { if !(fmfcc_or_fmicc) goto inst_next; fsrd = fsrs2; } + { if !(fmfcc_or_fmicc) goto ; fsrd = fsrs2; } :fmovd^fmfcc_or_fmicc fcc_icc_xcc,fdrs2,fdrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=2 & fdrs2 & fdrd - { if !(fmfcc_or_fmicc) goto inst_next; fdrd = fdrs2; } + { if !(fmfcc_or_fmicc) goto ; fdrd = fdrs2; } :fmovq^fmfcc_or_fmicc fcc_icc_xcc,fqrs2,fqrd is op=2 & op3=0x35 & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & opf_low=3 & fqrs2 & fqrd - { if !(fmfcc_or_fmicc) goto inst_next; fqrd = fqrs2; } + { if !(fmfcc_or_fmicc) goto ; fqrd = fqrs2; } :movf^fmfcc_or_fmicc fcc_icc_xcc,regorimm11,rd is op=2 & rd & op3=0x2c & bit18=0 & fmfcc_or_fmicc & fcc_icc_xcc & regorimm11 - { if !(fmfcc_or_fmicc) goto inst_next; rd = regorimm11; } + { if !(fmfcc_or_fmicc) goto ; rd = regorimm11; } -fmovrcc: "z" is rcond3=0x1 & RS1 {tmp:1 = (RS1 f== 0); export tmp;} -fmovrcc: "lez" is rcond3=0x2 & RS1 {tmp:1 = (RS1 f<= 0); export tmp;} -fmovrcc: "lz" is rcond3=0x3 & RS1 {tmp:1 = (RS1 f< 0); export tmp;} -fmovrcc: "nz" is rcond3=0x5 & RS1 {tmp:1 = (RS1 f!= 0); export tmp;} -fmovrcc: "gz" is rcond3=0x6 & RS1 {tmp:1 = (RS1 f> 0); export tmp;} -fmovrcc: "gez" is rcond3=0x7 & RS1 {tmp:1 = (RS1 f>= 0); export tmp;} +fmovrcc: "z" is rcond3=0x1 & RS1 { tmp:1 = (RS1 f== 0); export tmp; } +fmovrcc: "lez" is rcond3=0x2 & RS1 { tmp:1 = (RS1 f<= 0); export tmp; } +fmovrcc: "lz" is rcond3=0x3 & RS1 { tmp:1 = (RS1 f< 0); export tmp; } +fmovrcc: "nz" is rcond3=0x5 & RS1 { tmp:1 = (RS1 f!= 0); export tmp; } +fmovrcc: "gz" is rcond3=0x6 & RS1 { tmp:1 = (RS1 f> 0); export tmp; } +fmovrcc: "gez" is rcond3=0x7 & RS1 { tmp:1 = (RS1 f>= 0); export tmp; } -:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 - { if !(fmovrcc) goto inst_next; fsrd = fsrs2; } -:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 - { if !(fmovrcc) goto inst_next; fdrd = fdrs2; } -:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 - { if !(fmovrcc) goto inst_next; fqrd = fqrs2; } +:fmovrs^fmovrcc RS1,fsrs2,fsrd is op=2 & fsrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x5 & fsrs2 + { if !(fmovrcc) goto ; fsrd = fsrs2; } +:fmovrd^fmovrcc RS1,fdrs2,fdrd is op=2 & fdrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x6 & fdrs2 + { if !(fmovrcc) goto ; fdrd = fdrs2; } +:fmovrq^fmovrcc RS1,fqrs2,fqrd is op=2 & fqrd & op3=0x35 & bit13=0 & RS1 & fmovrcc & opf_low=0x7 & fqrs2 + { if !(fmovrcc) goto ; fqrd = fqrs2; } # Include support for the VIS1 vector instructions @include "SparcVIS.sinc" From 087216607aa8c4c9c7bb9312c1ce6cc0ac1d30a9 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Mon, 7 Oct 2019 09:27:58 -0400 Subject: [PATCH 4/6] GT-3202: Sparcv9, corrected pcode for 32-bit std instruction. --- .../Sparc/data/languages/SparcV9.sinc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 632a1def96..2e2cb1f412 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -537,20 +537,19 @@ macro unpackflags(ccr) { # size = 4, but this extended store insn needs to write 8 bytes :stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea { - # There is a bug in the sleigh compiler that implements the tmp_hi:4 = rd_d[32,32] instruction incorrectly - #tmp_lo:4 = rd_d[0,32]; - #tmp_hi:4 = rd_d[32,32]; - #tmp:8 = zext(tmp_lo) + zext(tmp_hi << 32); - *ea = rd_d;#tmp; + tmp_lo:4 = rd_d[0,32]; + tmp_hi:4 = rd_d[32,32]; + tmp:8 = zext(tmp_lo) + (zext(tmp_hi) << 32); + *ea = tmp; } :clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; } :std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea { - #tmp_lo:4 = rd_d[0,32]; - #tmp_hi:4 = rd_d[32,32]; - #tmp:8 = zext(tmp_lo) + zext(tmp_hi << 32); - *ea = rd_d;#tmp; + tmp_lo:4 = rd_d[0,32]; + tmp_hi:4 = rd_d[32,32]; + tmp:8 = zext(tmp_lo) + (zext(tmp_hi) << 32); + *ea = tmp; } :clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; } From 40a02a6981ed62e26ef98985ea9d97aa06a96009 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 8 Oct 2019 15:43:30 -0400 Subject: [PATCH 5/6] GT-3202: Fix for DECOMPILE_MODE flag being interpreted incorrectly --- Ghidra/Processors/Sparc/data/languages/SparcV9.sinc | 4 ++-- .../ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java | 6 ++++++ .../ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java | 6 ++++++ .../ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java | 6 ++++++ .../ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java | 6 ++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 2e2cb1f412..3bddef8b88 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -252,7 +252,7 @@ attach variables [ rs1_3 ] [ Y _ CCR _ TICK PC _ # CWP++ macro save() { -if (!DECOMPILE_MODE) goto ; +if (DECOMPILE_MODE) goto ; # Save inputs *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+0)*$(SIZE)) = i0; *[register]:$(SIZE) (&w010 + (CWP:4*$(REGWINSZ)+1)*$(SIZE)) = i1; @@ -312,7 +312,7 @@ macro restore() { sp = fp; o7 = i7; # address of CALLer address -if (!DECOMPILE_MODE) goto ; +if (DECOMPILE_MODE) goto ; # restore original inputs i0 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+0)*$(SIZE))); i1 = *[register]:$(SIZE) ((&w010) + ((CWP:4*$(REGWINSZ)+1)*$(SIZE))); diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java index b63beeb408..f8f5e88d75 100644 --- a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O0_EmulatorTest.java @@ -15,6 +15,8 @@ */ package ghidra.test.processors; +import ghidra.program.model.listing.Program; +import ghidra.test.processors.support.EmulatorTestRunner; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import junit.framework.Test; @@ -34,6 +36,10 @@ public class SparcV9_32_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { return "sparcV9_32_GCC_O0"; } + protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception { + testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off + } + public static Test suite() { return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O0_EmulatorTest.class); } diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java index 7e225ba66a..e959c430e3 100644 --- a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_32_O3_EmulatorTest.java @@ -15,6 +15,8 @@ */ package ghidra.test.processors; +import ghidra.program.model.listing.Program; +import ghidra.test.processors.support.EmulatorTestRunner; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import junit.framework.Test; @@ -34,6 +36,10 @@ public class SparcV9_32_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { return "sparcV9_32_GCC_O3"; } + protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception { + testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off + } + public static Test suite() { return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_32_O3_EmulatorTest.class); } diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java index ba005c1d31..31bb61b0e5 100644 --- a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O0_EmulatorTest.java @@ -15,6 +15,8 @@ */ package ghidra.test.processors; +import ghidra.program.model.listing.Program; +import ghidra.test.processors.support.EmulatorTestRunner; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import junit.framework.Test; @@ -34,6 +36,10 @@ public class SparcV9_64_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { return "sparcV9_64_GCC_O0"; } + protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception { + testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off + } + public static Test suite() { return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O0_EmulatorTest.class); } diff --git a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java index 82c9417fca..a68eff42b4 100644 --- a/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java +++ b/Ghidra/Processors/Sparc/src/test.processors/java/ghidra/test/processors/SparcV9_64_O3_EmulatorTest.java @@ -15,6 +15,8 @@ */ package ghidra.test.processors; +import ghidra.program.model.listing.Program; +import ghidra.test.processors.support.EmulatorTestRunner; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import junit.framework.Test; @@ -34,6 +36,10 @@ public class SparcV9_64_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { return "sparcV9_64_GCC_O3"; } + protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception { + testRunner.setRegister("DECOMPILE_MODE", 0x0); // turn decompile mode off + } + public static Test suite() { return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(SparcV9_64_O3_EmulatorTest.class); } From f871320726315a87ff86f0451c22bc555e51c8ec Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 15 Oct 2019 13:52:31 -0400 Subject: [PATCH 6/6] GT-3202: Code review fixes, implemented data organization section --- .../Sparc/data/languages/SparcV9.sinc | 56 +++++++------------ .../Sparc/data/languages/SparcV9_32.cspec | 22 ++++++++ .../Sparc/data/languages/SparcV9_64.cspec | 22 ++++++++ 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 3bddef8b88..ba19cdb377 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -116,23 +116,25 @@ define register offset=0x7000 size=$(SIZE) [ # Floating-point registers define register offset=0x2000 size=4 [ - fs3 fs2 fs1 fs0 fs7 fs6 fs5 fs4 - fs11 fs10 fs9 fs8 fs15 fs14 fs13 fs12 - fs19 fs18 fs17 fs16 fs23 fs22 fs21 fs20 - fs27 fs26 fs25 fs24 fs31 fs30 fs29 fs28 + fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7 + fs8 fs9 fs10 fs11 fs12 fs13 fs14 fs15 + fs16 fs17 fs18 fs19 fs20 fs21 fs22 fs23 + fs24 fs25 fs26 fs27 fs28 fs29 fs30 fs31 ]; define register offset=0x2000 size=8 [ - fd2 fd0 fd6 fd4 fd10 fd8 fd14 fd12 - fd18 fd16 fd22 fd20 fd26 fd24 fd30 fd28 - fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 - fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 + fd0 fd2 fd4 fd6 fd8 fd10 fd12 fd14 + fd16 fd18 fd20 fd22 fd24 fd26 fd28 fd30 + fd32 fd34 fd36 fd38 fd40 fd42 fd44 fd46 + fd48 fd50 fd52 fd54 fd56 fd58 fd60 fd62 ]; define register offset=0x2000 size=16 [ - fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 - fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 + fq0 fq4 fq8 fq12 fq16 fq20 fq24 fq28 + fq32 fq36 fq40 fq44 fq48 fq52 fq56 fq60 ]; + + define pcodeop segment; define pcodeop popc; @@ -503,14 +505,8 @@ macro unpackflags(ccr) { @if SIZE=="8" :ldd ea,rd is op=3 & rd & op3=0x03 & ea { rd = *:$(SIZE) ea; } - @else -:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea -{ - tmp:8 = *:8 ea; - rd_d[32,32] = tmp(4); - rd_d[0,32] = tmp(0); -} +:ldd ea,rd is op=3 & rd & rd_d & op3=0x03 & ea { rd_d = *:8 ea; } @endif @@ -532,29 +528,15 @@ macro unpackflags(ccr) { @if SIZE=="8" :stx RD,ea is op=3 & RD & op3=0x0e & ea { *ea = RD; } :std RD,ea is op=3 & RD & op3=0x07 & ea { *ea = RD; } - @else -# size = 4, but this extended store insn needs to write 8 bytes -:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea -{ - tmp_lo:4 = rd_d[0,32]; - tmp_hi:4 = rd_d[32,32]; - tmp:8 = zext(tmp_lo) + (zext(tmp_hi) << 32); - *ea = tmp; -} -:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; } - -:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea -{ - tmp_lo:4 = rd_d[0,32]; - tmp_hi:4 = rd_d[32,32]; - tmp:8 = zext(tmp_lo) + (zext(tmp_hi) << 32); - *ea = tmp; -} -:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; } - +# size = 4, but this extended store instruction needs to write 8 bytes +:stx RD,ea is op=3 & RD & rd_d & op3=0x0e & ea { *ea = rd_d; } +:std RD,ea is op=3 & RD & rd_d & op3=0x07 & ea { *ea = rd_d; } @endif +:clrx ea is op=3 & rd=0 & op3=0x0e & ea { *ea = 0:8; } +:clrd ea is op=3 & rd=0 & op3=0x07 & ea { *ea = 0:8; } + :stba RD,ea_alt is op=3 & RD & op3=0x15 & ea_alt { *ea_alt = RD:1; } :stha RD,ea_alt is op=3 & RD & op3=0x16 & ea_alt { *ea_alt = RD:2; } :stwa RD,ea_alt is op=3 & RD & op3=0x14 & ea_alt { *ea_alt = RD:4; } diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec index bc1aaa1967..a966df3d51 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_32.cspec @@ -1,6 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec index 9eab4e95bc..239e2388a9 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9_64.cspec @@ -1,6 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + +