From 756706787f648dfc9786e8245f6b43861580d4e4 Mon Sep 17 00:00:00 2001 From: kaitz Date: Fri, 15 Feb 2019 21:52:32 +0200 Subject: [PATCH] v4 -jpeg cfg updated from paq8fthis4 -vm jit optimize array access and other code -fix vm and jit compression differences -vm is now signed (int,short, char), only << and >> are unsigned -add jpeg detection as external code for vm, for testing -change all config files --- jpeg.cfg | 332 +++++++++++++++++++++++++++++++++++---------------- jpeg.det | 73 +++++++++++ paq8pxv.cpp | 305 ++++++++++------------------------------------ test3d.cfg | 26 ++-- test3i8.cfg | 243 ++++++++++++++++++------------------- test3img.cfg | 28 ++--- vm.cpp | 296 ++++++++++++++++++++++++++++----------------- 7 files changed, 694 insertions(+), 609 deletions(-) create mode 100644 jpeg.det diff --git a/jpeg.cfg b/jpeg.cfg index ea6301a..f138de4 100644 --- a/jpeg.cfg +++ b/jpeg.cfg @@ -47,7 +47,7 @@ int zzv[64]={ int *hufmax; int *hufval; int mcusize; // number of coefficients in an MCU - int linesize; // width of image in MCU + // int linesize; // width of image in MCU int *hufsel1; // DC/AC, mcupos/64 -> huf decode table int *hufsel2; // Image state @@ -65,9 +65,9 @@ int zzv[64]={ // xx is the first 2 extra bits, and the last 2 bits are 1 (since // this never occurs in a valid RS code). int cpos; // position in cbuf - int huff1, huff2, huff3, huff4; // hashes of last codes - int rs1, rs2, rs3, rs4; // last 4 RS codes - int ssum, ssum1, ssum2, ssum3, ssum4; + //int huff1, huff2, huff3, huff4; // hashes of last codes + int rs1;//, rs2, rs3, rs4; // last 4 RS codes + int ssum, ssum1, ssum2, ssum3;//, ssum4; // sum of S in RS codes in block and last 4 values // Context model int N; // number of contexts @@ -75,7 +75,20 @@ int zzv[64]={ int hbcount; int *cxt;// context hashes int *cp; // context pointers - + + char *cbuf2; + int *adv_pred;//, *sum; + + //for parsing Quantization tables + int dqt_state, dqt_end , qnum; + char *qtab;//(256); // table + int *qmap;//(10); // block -> table number + int zz , acomp , q , cpos_dc ,st,zz2,tq; + int *sumu, *sumv; + int *ls; // block -> distance to previous block + int *lcp, *zpos; + int zu, zv,a,b,comp0; + int kk; int min(int a, int b) {return a>24^i>>12^i)&255; mask=i&(tsize-1);//mask; - bi=mask, b=1024; // best replacement so far + bi=mask, br=1024; // best replacement so far for ( j=0; j1; if (bpos && !jpeg) return next_jpeg; if (!bpos && app>0) --app; if (app>0) return next_jpeg; @@ -137,7 +149,7 @@ int jpegModel(int bpos,int pos,int y) { // Detect JPEG (SOI, APPx) if (!jpeg && buf(4)==FF && buf(3)==SOI && buf(2)==FF && buf(1)>>4==0xe) { jpeg=1; - app=sos=sof=htsize=data=mcusize=linesize=0; + app=sos=sof=htsize=data=mcusize=0; huffcode=huffbits=huffsize=mcupos=cpos=0, rs=-1; for (i=0;i<128;i++) hufmin[i]=0; for (i=0;i<128;i++) hufmax[i]=0; @@ -161,11 +173,30 @@ int jpegModel(int bpos,int pos,int y) { if (buf(5)==FF && buf(4)==SOS) { len=buf(3)*256+buf(2); if (len==6+2*buf(1) && buf(1) && buf(1)<=4) // buf(1) is Ns - {sos=pos-5, data=sos+len+2;} + {sos=pos-5, data=sos+len+2, jpeg=2;} } if (buf(4)==FF && buf(3)==DHT && htsize<8) ht[htsize++]=pos-4; if (buf(4)==FF && buf(3)==SOF0) sof=pos-4; - + + // Parse Quantizazion tables + if (buf(4)==FF && buf(3)==DQT) { + dqt_end = pos + buf(2)*256 + buf(1) - 1; + dqt_state = 0; + } else if (dqt_state >=0) { + if (pos >= dqt_end) { + dqt_state = -1; + } else { + if (dqt_state % 65 == 0) { + qnum = buf(1); + } else { + jassert(buf(1) > 0,29); + jassert(qnum>=0 && qnum<4,30); + qtab[qnum * 64 + ((dqt_state % 65) - 1)] = buf(1) - 1; + //printf("%d, ",buf(1) - 1); + } + dqt_state++; + } + } // Restart if (buf(2)==FF && (buf(1)&0xf8)==RST0) { huffcode=huffbits=huffsize=mcupos=0, rs=-1; @@ -194,16 +225,16 @@ int jpegModel(int bpos,int pos,int y) { code=0; for ( j=0; j<16; ++j) { hufmin[j+hufi]=code; - code=code+bufr(p+j+1); + code=code+bufr(p+j+1); hufmax[j+hufi]=code; hufval[j+hufi]=val; val=val+bufr(p+j+1); - code=code*2; + code=code<<1; } p=val; - } + } } - + jassert(p==end,4); } huffcode=huffbits=huffsize=0, rs=-1; @@ -229,15 +260,26 @@ int jpegModel(int bpos,int pos,int y) { hufsel2[mcusize]=bufr(sos+2*i+6)&15; jassert (hufsel1[mcusize]<4 && hufsel2[mcusize]<4,8); color[mcusize]=i; + tq=bufr(sof+3*j+12); // quantization table index (0..3) + jassert(tq>=0 && tq<4,28); + qmap[mcusize]=tq; // Quantizazion table mapping --hv; ++mcusize; } } } } + jassert(mcusize<10,99); + jassert(hmax>=1 && hmax<=10,9); + for ( j=0; j0,10); @@ -251,17 +293,15 @@ int jpegModel(int bpos,int pos,int y) { { if (mcusize && buf(1+(!bpos))!=FF) { // skip stuffed byte jassert(huffbits<=32,11); - huffcode=huffcode+huffcode+y; + huffcode=(huffcode<<1)|y; ++huffbits; - if (rs>0x7FFFFFFF) { + if (rs<0) { jassert(huffbits>=1 && huffbits<=16,12); ac=(mcupos&63)>0; jassert(mcupos>=0 && (mcupos>>6)<10,13); jassert(ac==0 || ac==1,14); - if (ac==0) - sel=hufsel1[mcupos>>6]; - else if (ac==1) - sel=hufsel2[mcupos>>6]; + if (ac==0) sel=hufsel1[mcupos>>6]; + else if (ac==1) sel=hufsel2[mcupos>>6]; else printf("error ac"); jassert(sel>=0 && sel<4,15); i=huffbits-1; @@ -274,22 +314,16 @@ int jpegModel(int bpos,int pos,int y) { huffsize=huffbits; } } - if (rs<= 0x7FFFFFFF) { + if (rs>=0) { if (huffsize+(rs&15)==huffbits) { // done decoding - //huff4=huff3; - //huff3=huff2; - //huff2=huff1; - huff1=h2(huffcode, huffbits); - //rs4=rs3; - rs3=rs2; - rs2=rs1; rs1=rs; - x=0; // decoded extra bits + x=0; // decoded extra bits if (mcupos&63) { // AC if (rs==0) { // EOB mcupos=mcupos+63&-64; jassert(mcupos>=0 && mcupos<=mcusize && mcupos<=640,18); - while (cpos&63) cbuf[(cpos++)&0x1FFFF]=0; + while (cpos&63) {cbuf2[cpos&0x1FFFF]=0; + cbuf[(cpos++)&0x1FFFF]=0;} } else { // rs = r zeros + s extra bits for the next nonzero value // If first extra bit is 0 then value is negative. @@ -300,7 +334,10 @@ int jpegModel(int bpos,int pos,int y) { mcupos=mcupos+r+1; x=huffcode&(1<>s-1)) x=x-(1<=1; --i) cbuf[(cpos++)&0x1FFFF]=i<<4|s; + for ( i=r; i>=1; --i) { + cbuf2[cpos&0x1FFFF]=0; + cbuf[(cpos++)&0x1FFFF]=i<<4|s;} + cbuf2[cpos&0x1FFFF]=x; cbuf[(cpos++)&0x1FFFF]=s<<4|huffcode<<2>>s&3|12; ssum=ssum+s; } @@ -316,8 +353,8 @@ int jpegModel(int bpos,int pos,int y) { pred[comp]=pred[comp]+x; dc=pred[comp]; jassert((cpos&63)==0,24); + cbuf2[cpos&0x1FFFF]=dc; cbuf[(cpos++)&0x1FFFF]=dc+1023>>3; - ssum4=ssum3; ssum3=ssum2; ssum2=ssum1; ssum1=ssum; @@ -329,6 +366,62 @@ int jpegModel(int bpos,int pos,int y) { if (++column==width) column=0, ++row; } huffcode=huffsize=huffbits=0, rs=-1; + + // UPDATE_ADV_PRED !!!! + { + acomp=mcupos>>6, q=64*qmap[acomp]; + zz=mcupos&63, cpos_dc=cpos-zz; + if (zz==0) { + for ( i=0; i<8; ++i) sumu[i]=sumv[i]=0; + for ( i=0; i<64; ++i) { + sumu[zzu[i]]=sumu[zzu[i]]+(zzv[i]?256:181)*(zzv[i]&1?-1:+1)*(qtab[q+i]+1)*cbuf2[(cpos_dc+i-mcusize*width)&0x1FFFF]; + sumv[zzv[i]]=sumv[zzv[i]]+(zzu[i]?256:181)*(zzu[i]&1?-1:+1)*(qtab[q+i]+1)*cbuf2[(cpos_dc+i-ls[acomp])&0x1FFFF];; + } + } + else { + sumu[zzu[zz-1]]=sumu[zzu[zz-1]]-(zzv[zz-1]?256:181)*(qtab[q+zz-1]+1)*cbuf2[(cpos-1)&0x1FFFF]; + sumv[zzv[zz-1]]=sumv[zzv[zz-1]]-(zzu[zz-1]?256:181)*(qtab[q+zz-1]+1)*cbuf2[(cpos-1)&0x1FFFF]; + } + j=cbuf2[(cpos_dc-ls[acomp])&0x1FFFF]; + for ( i=0; i<3; ++i) + for ( st=0; st<8; ++st) { + zz2 = min(zz+st, 63); + p=(sumu[zzu[zz2]]*i+sumv[zzv[zz2]]*(2-i))/2; + p=p/((qtab[q+zz2]+1)*181); + if (zz2==0) p=p-j, p=(p<0?-1:+1)*ilog(14*abs(p)+1)/10; + else p=(p<0?-1:+1)*ilog(10*abs(p)+1)/10; + if (st==0) { + adv_pred[i]=p; + adv_pred[i+4]=p/4; + } + else if (abs(p)>abs(adv_pred[i])+1) { + adv_pred[i]=adv_pred[i]+st*2+(p>0)<<6; + st=8;//break; + } + } + x=2*sumu[zzu[zz]]+2*sumv[zzv[zz]]; + for ( i=0; i<8; ++i) { + if (zzu[zz]2 || huffbits==0) hbcount=0; hc=huffcode|1<>6]; + comp0=comp==0; coef=(mcupos&63)|(comp<<6); zu=zzu[mcupos&63]; zv=zzv[mcupos&63]; - jassert(coef>=0 && coef<256,26); - if (hbcount==0) { - mpos=mcupos>>4|!(mcupos&-64)<<7; + jassert(coef>=0 && coef<256,26); + if (hbcount==0) { + //mpos=mcupos>>4|!(mcupos&-64)<<7; i=0; - cxt[0]=h4(++i, hc, mcupos>>2, min(3, mcupos&63)); - cxt[1]=h4(++i, hc, mpos>>4, cbuf[(cpos-mcusize)&0x1FFFF]); - cxt[2]=h4(++i, hc, mpos>>4, cbuf[(cpos-width*mcusize)&0x1FFFF]); - cxt[3]=h4(++i, hc, ilog(ssum3), coef); - cxt[4]=h4(++i, hc, coef, column>>3); - cxt[5]=h4(++i, hc, coef, column>>1); - cxt[6]=h4(++i, hc, rs1, mpos); - cxt[7]=h4(++i, hc, rs1, rs2); - cxt[8]=h5(++i, hc, rs1, rs2, rs3); - cxt[9]=h4(++i, hc, ssum>>4, mcupos); - cxt[10]=h4(++i, hc, mpos, cbuf[(cpos-1)&0x1FFFF]); - cxt[11]=h3(++i, hc, dc); - cxt[12]=h4(++i, hc, rs1, coef); - cxt[13]=h5(++i, hc, rs1, rs2, coef); - cxt[14]=h4(++i, hc, mcupos>>3, ssum3>>3); - cxt[15]=h3(++i, hc, huff1); - cxt[16]=h4(++i, hc, coef, huff1); - cxt[17]=h4(++i, hc, zu, comp); - cxt[18]=h4(++i, hc, zv, comp); + cxt[0]=h4(++i, hc, coef, adv_pred[2]); + cxt[1]=h4(++i, hc, coef, adv_pred[0]); + cxt[2]=h4(++i, hc, coef, adv_pred[1]); + cxt[3]=h5(++i, hc, rs1, comp0, adv_pred[2]); + cxt[4]=h5(++i, hc, rs1, comp0, adv_pred[0]); + cxt[5]=h5(++i, hc, rs1, comp0, adv_pred[1]); + cxt[6]=h4(++i, hc, adv_pred[2], adv_pred[0]); + cxt[7]=h5(++i, hc, comp0, cbuf[(cpos-width*mcusize)&0x1FFFF], adv_pred[3]); + cxt[8]=h5(++i, hc, comp0, cbuf[(cpos-ls[mcupos>>6])&0x1FFFF], adv_pred[3]); + cxt[9]=h5(++i, hc, lcp[0], lcp[1], adv_pred[1]); + cxt[10]=h5(++i, hc, lcp[0], lcp[1], coef); + cxt[11]=h5(++i, hc, zu+8*comp0, lcp[0], lcp[2]/2); + cxt[12]=h5(++i, hc, zv+8*comp0, lcp[1], lcp[3]/2); + cxt[13]=h4(++i, hc, mcupos>>2, min(3, mcupos&63)); + cxt[14]=h4(++i, hc, coef, column>>1); + cxt[15]=h3(++i, hc, dc); + cxt[16]=h4(++i, hc, ssum>>4, coef); + cxt[17]=h4(++i, hc, rs1, coef); + cxt[18]=h5(++i, hc, mcupos>>3, ssum3>>3, adv_pred[1]); + cxt[19]=h5(++i, hc, lcp[0]>>2, lcp[1]>>2, adv_pred[5]); + cxt[20]=h3(++i, hc, adv_pred[1]); + cxt[21]=h5(++i, hc, rs1, comp0, adv_pred[5]); + cxt[22]=h4(++i, hc, comp0, adv_pred[2]); + cxt[23]=h4(i, hc, comp0, adv_pred[0]); + cxt[24]=h4(i, hc, comp0, adv_pred[1]); + cxt[25]=h4(++i, hc, coef, adv_pred[4]); + cxt[26]=h4(++i, hc, coef, adv_pred[6]); + cxt[27]=h5(++i, hc, lcp[0], lcp[1], adv_pred[3]); } // Predict next bit @@ -382,24 +489,22 @@ int jpegModel(int bpos,int pos,int y) { if (hbcount==0) cp[i]=find(cxt[i])+1; else if (hbcount==1) cp[i]=cp[i]+1+(huffcode&1)*3; else cp[i]=cp[i]+1+(huffcode&1); - mxa(1,stretch(smp(i,t[cp[i]],1023))); + smp(i,t[cp[i]],1023); } - mxs(1,0, 1); + mxc(1); // mix statemap contexts into mixer 1 + mxs(1,column==0, 2); mxs(1, coef,256); - mxs(1,mcupos, 640); + mxs(1,hc&511, 512); pr=mxp(1); - pr=apm(3,pr,hc&1023,7); - pr=apm(4,pr,(hc&255|coef<<8)&0xffff,7); + pr=apm(3,pr,hc&255|(adv_pred[1]&63)<<8,7); + pr=apm(4,pr,hc&255|coef<<8,7); mxa(0,stretch(pr)); return 1; } // update is called in VM after every bit int update(int y,int c0,int bpos,int c4,int pos){ - int i; int pr0,pr; int d,c; - int col,h,above; - int fl,matched,r,vv; int isjpeg; mxa(0,256); isjpeg=jpegModel(bpos,pos,y); // 1 if JPEG is detected, else 0 @@ -412,7 +517,6 @@ int update(int y,int c0,int bpos,int c4,int pos){ } if (bpos== 0){ c1= buf(1), c2= buf(2), c3= buf(3); - if (c1>255 ||c2>255 ||c3>255) printf("suur "); w4= w4*4+mpw[c1>>4]; } @@ -433,33 +537,49 @@ int update(int y,int c0,int bpos,int c4,int pos){ } else c=(c3>>7)+( c4>>31)*2+4*(c2>>6)+(c1&240); - mxs(0,c, 1536); - mxs(0,prm, 2048); + mxs(0,c, 1536); + mxs(0,prm, 2048); pr0=mxp(0); pr =apm(0,pr0,c0,7); prm=pr>>1; - return (apm(2,pr, (c0+256*c1)&0xffff,7)+apm(1,pr0, h2(c0,w4&0xfffff)&0xffff,7)+1)>>1; + return (apm(2,pr, c0+256*c1,7)+apm(1,pr0, h2(c0,w4&0xfffff),7)+1)>>1; } void block(int a,int b) { - + int i; + jpeg=app=sos=sof=htsize=data=mcusize=0; + huffcode=huffbits=huffsize=mcupos=cpos=0, rs=-1; + for (i=0;i<128;i++) hufmin[i]=0; + for (i=0;i<128;i++) hufmax[i]=0; + for (i=0;i<128;i++) hufval[i]=0; + for (i=0;i<4;i++) pred[i]=0; } // main is called only once after VM init. int main() { int i; - N=15+2+2; - tsize=0x1000000; - if (!(t = malloc((tsize*8)*sizeof(char)))) { exit(-1); } - if (!(cbuf = malloc(0x20000*sizeof(char)))) { exit(-1); } - if (!(cxt = malloc(N*sizeof(int)))) { exit(-1); } - if (!(cp = malloc(N*sizeof(int)))) { exit(-1); } - if (!(color = malloc(10*sizeof(int)))) { exit(-1); } - if (!(pred = malloc(4*sizeof(int)))) { exit(-1); } - if (!(ht = malloc(8*sizeof(int)))) { exit(-1); } - if (!(hufsel1 = malloc(10*sizeof(int)))) { exit(-1); } - if (!(hufsel2 = malloc(10*sizeof(int)))) { exit(-1); } - if (!(hufmin = malloc(128*sizeof(int)))) { exit(-1); } - if (!(hufmax = malloc(128*sizeof(int)))) { exit(-1); } - if (!(hufval = malloc(128*sizeof(int)))) { exit(-1); } + printf("JPEG model v4\n"); + N=28; + tsize=0x1000000;// MEM at -8 + if (!(t = malloc((tsize*BC),sizeof(char)))) exit(-1); + if (!(cbuf = malloc(0x20000,sizeof(char)))) exit(-1); + if (!(cxt = malloc(N,sizeof(int)))) exit(-1); + if (!(cp = malloc(N,sizeof(int)))) exit(-1); + if (!(color = malloc(10,sizeof(int)))) exit(-1); + if (!(pred = malloc(4,sizeof(int)))) exit(-1); + if (!(ht = malloc(8,sizeof(int)))) exit(-1); + if (!(hufsel1 = malloc(10,sizeof(int)))) exit(-1); + if (!(hufsel2 = malloc(10,sizeof(int)))) exit(-1); + if (!(hufmin = malloc(128,sizeof(int)))) exit(-1); + if (!(hufmax = malloc(128,sizeof(int)))) exit(-1); + if (!(hufval = malloc(128,sizeof(int)))) exit(-1); + if (!(cbuf2 = malloc(0x20000,sizeof(int)))) exit(-1); + if (!(adv_pred = malloc(7,sizeof(int)))) exit(-1); + if (!(qtab = malloc(256,sizeof(char)))) exit(-1); + if (!(qmap = malloc(10,sizeof(int)))) exit(-1); + if (!(sumu = malloc(8,sizeof(int)))) exit(-1); + if (!(sumv = malloc(8,sizeof(int)))) exit(-1); + if (!(ls = malloc(10,sizeof(int)))) exit(-1); + if (!(lcp = malloc(4,sizeof(int)))) exit(-1); + if (!(zpos = malloc(64,sizeof(int)))) exit(-1); // SMC,APM1,APM2,RCM,SCM,MCM, CM,MX, MC (1,2,3,4,5,6,7,8,9) vms( N, 5, 0, 0, 0, 0, 0, 2, 1) ; @@ -468,18 +588,18 @@ int main() { vmi(APM1,0,256,0,-1); //APM1(0) contexts, 0, no mixer vmi(APM1,1,0x10000,0,-1); vmi(APM1,2,0x10000,0,-1); - vmi(APM1,3,1024,0,-1); + vmi(APM1,3,0x1000,0,-1); vmi(APM1,4,0x10000,0,-1); - vmi(MX,0,682+200+18,6665+256+2048,9); //MX(0) 51 inputs, contexts, context count - vmi(MX,1,N+1,897,4); + vmi(MX,0,682+200+18,264+256+256+256+2048+1536+2048,7); + vmi(MX,1,N+1,770,4); w4=0; prm=1024; - hbcount=jpeg=next_jpeg=0; - app=sof=sos=data=0; + hbcount=2; + jpeg=next_jpeg=app=sof=sos=data=0; htsize=huffcode=huffbits=huffsize=0; rs=-1; - mcupos=mcusize=linesize=dc=0; - width=row=column=cpos=0; - huff1=huff2=huff3=huff4=0; - ssum=ssum1=ssum2=ssum3=ssum4=0; + mcupos=mcusize=dc=width=row=column=cpos=0; + ssum=ssum1=ssum2=ssum3=0; + dqt_state = -1, dqt_end=qnum=0; + c1=c2=c3=0; } diff --git a/jpeg.det b/jpeg.det new file mode 100644 index 0000000..4a9d920 --- /dev/null +++ b/jpeg.det @@ -0,0 +1,73 @@ +int soi, sof, sos, app,eoi; +int type,state,jstart,jend; +int buf0,buf1; +enum {DEFAULT=1,JPEG}; //internal enum +enum {NONE=0,START,INFO,END,REQUEST=0xffffffff}; //external enum +// function will report its state +// or if i=-1 then state results otherwise i is pos +// c4 is last 4 bytes +int detect(int c4,int i) { + int c1; + + //if state parameters recuested + if (i==REQUEST){ + //printf("DETECT: State requested %d\n",state); + if (state==NONE){return 0xffffffff;} + if (state==START) return jstart; + if (state==END) return jend; + if (state==INFO) return 0xffffffff; + } + c1=c4&255; + buf1=(buf1<<8)|(buf0>>24); + buf0=buf0<<8|c1; + //detect header + if (!soi && i>=3 && (( + ((c4&0xffffff00)==0xffd8ff00 && (c1==0xC0 || c1==0xC4 || (c1>=0xDB && c1<=0xFE))) + ||(c4&0xfffffff0)==0xffd8ffe0 ) ) + ) soi=i, app=i+2, sos=sof=0; + if (soi) { + if (app==i && (c4>>24)==0xff && + ((c4>>16)&0xff)>0xc0 && ((c4>>16)&0xff)<0xff) app=i+(c4&0xffff)+2; + if (appsoi && i-sof<0x1000 && (c4&0xffff)==0xffda) { + sos=i; + if (type!=JPEG){ + type=JPEG; + state=START; + jstart=soi-3; + soi=buf0=buf1=0; + //printf("DETECT: JPEG start %d\n",jstart); + return state; + } + } + if (i-soi>0x40000 && !sos) soi=0; + } + if (type==JPEG && soi && (c4&0xffff)==0xffd9) { + eoi=i; + } + if (type==JPEG && soi && sos && eoi && (c4&0xffff)==0xffd8) { + state=END; + type=DEFAULT; + jend=i;//-1; + soi=buf0=buf1=0; + //printf("DETECT: JPEG end-1 %d\n",jend); + return state; + } + if (type==JPEG && sos && i>sos && (c4&0xff00)==0xff00 + && (c4&0xff)!=0 && ((c4&0xf8)!=0xd0 )) { + state=END; + type=DEFAULT; + jend=i+1; + soi=buf0=buf1=0; + //printf("DETECT: JPEG end %d\n",jend); + return state; + } + return NONE; +} + +int main() { + soi=sof=sos=app=eoi=jstart=jend=buf0=buf1=0; + type=DEFAULT; + state=NONE; +} \ No newline at end of file diff --git a/paq8pxv.cpp b/paq8pxv.cpp index 4e74b5d..f1df44d 100644 --- a/paq8pxv.cpp +++ b/paq8pxv.cpp @@ -546,12 +546,18 @@ and 1/3 faster overall. (However I found that SSE2 code on an AMD-64, which computes 8 elements at a time, is not any faster). -DIFFERENCES FROM PAQ8PXV_V2 --jpeg model cfg +DIFFERENCES FROM PAQ8PXV_V3 +-jpeg cfg updated from paq8fthis4 +-vm jit optimize array access and other code +-fix vm and jit compression differences +-vm is now signed (int,short, char), only << and >> are unsigned +-add jpeg detection as external code for vm, for testing +-change all config files + */ -#define VERSION "v3" -#define PROGNAME "paq8pxd" VERSION // Please change this if you change the program. +#define VERSION "4" +#define PROGNAME "paq8pxv" VERSION // Please change this if you change the program. #define SIMD_GET_SSE //uncomment to use SSE2 in ContexMap //#define MT //uncomment for multithreading, compression only #define VMJIT // uncomment to compile with x86 JIT @@ -3527,180 +3533,13 @@ bool CAlpha2(U32 ins) { // All of the models below take a Mixer as a parameter and write // predictions to it. -/* - -const U8 AsciiGroupC0[254] ={ - 0, 10, - 0, 1, 10, 10, - 0, 4, 2, 3, 10, 10, 10, 10, - 0, 0, 5, 4, 2, 2, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 5, 5, 9, 4, 2, 2, 2, 2, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 5, 9, 9, 6, 5, 2, 2, 2, 2, 2, 2, 2, 8, 3, 3, 3, 3, 3, 3, 3, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 8, 8, 8, 5, 5, 9, 9, 9, 9, 9, 7, 8, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 -}; -const U8 AsciiGroup[128] = { - 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 5, 5, 4, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 7, 8, 17, 17, 9, 17, 10, - 11, 12, 17, 17, 13, 14, 15, 16, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 18, 19, 20, 23, 21, 22, - 23, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 24, 27, 25, 27, 26, - 27, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 28, 30, 29, 30, 30 -};*/ + class Model { public: virtual int p(Mixer& m,int val1,int val2)=0; virtual int inputs()=0; }; -/* -class SparseMatchModel { -private: - BlockData& x; - Buf& buffer; - enum Parameters : U32 { - MaxLen = 0xFFFF, // longest allowed match - MinLen = 3, // default minimum required match length - NumHashes = 4, // number of hashes used - }; - struct sparseConfig { - U32 offset;// = 0; // number of last input bytes to ignore when searching for a match - U32 stride ;// = 1; // look for a match only every stride bytes after the offset - U32 deletions;// = 0; // when a match is found, ignore these many initial post-match bytes, to model deletions - U32 minLen ;// = MinLen; - U32 bitMask ;// = 0xFF; // match every byte according to this bit mask - }; - const sparseConfig sparse[NumHashes] = { {0,1,0,5,0xDF},{1,1,0,4,0xFF}, {0,2,0,4,0xDF}, {0,1,0,5,0x0F}}; - Array Table; - StationaryMap Maps[4]; - IndirectContext iCtx8; - IndirectContext iCtx16; - MTFList list; - U32 hashes[NumHashes]; - U32 hashIndex; // index of hash used to find current match - U32 length; // rebased length of match (length=1 represents the smallest accepted match length), or 0 if no match - U32 index; // points to next byte of match in buffer, 0 when there is no match - U32 mask; - U8 expectedByte; // prediction is based on this byte (buffer[index]), valid only when length>0 - bool valid; - void Update() { - // update sparse hashes - for (U32 i=0; i=0; i=list.GetNext()) { - index = Table[hashes[i]]; - if (index>0) { - U32 offset = sparse[i].offset+1; - while (length=sparse[i].minLen) { - length-=(sparse[i].minLen-1); - index+=sparse[i].deletions; - hashIndex = i; - list.MoveToFront(i); - break; - } - } - length = index = 0; - } - } - // update position information in hashtable - for (U32 i=0; i1; // only predict after at least one byte following the match - if (valid) { - Maps[0].set(hash(expectedByte, x.c0, buffer(1), buffer(2), ilog2(length+1)*NumHashes+hashIndex)); - Maps[1].set((expectedByte<<8)|buffer(1)); - iCtx8=(buffer(1)<<8)|expectedByte, iCtx16=(buffer(1)<<8)|expectedByte; - Maps[2].set(iCtx8()); - Maps[3].set(iCtx16()); - } - } -public: - SparseMatchModel(BlockData& bd, U32 val1=0) : - x(bd),buffer(bd.buf), - Table(CMlimit(MEM()/2)),//? - Maps{ {22, 1}, {17, 4}, {8, 1}, {19,1} }, - iCtx8{19,1}, - iCtx16{16}, - list(NumHashes), - hashes{ 0 }, - hashIndex(0), - length(0), - mask(CMlimit(MEM()/2)-1), - expectedByte(0), - valid(false) - { - //assert(ispowerof2(Size)); - } - int inputs() {return 4*2+3;} - int p(Mixer& m,int val1=0,int val2=0) { - const U8 B = x.c0<<(8-x.bpos); - if (x.bpos==0) - Update(); - else if (valid) { - U8 B = x.c0<<(8-x.bpos); - Maps[0].set(hash(expectedByte, x.c0, buffer(1), buffer(2), ilog2(length+1)*NumHashes+hashIndex)); - if (x.bpos==4) - Maps[1].set(0x10000|((expectedByte^U8(x.c0<<4))<<8)|buffer(1)); - iCtx8+=x.y, iCtx8=(x.bpos<<16)|(buffer(1)<<8)|(expectedByte^B); - Maps[2].set(iCtx8()); - Maps[3].set((x.bpos<<16)|(iCtx16()^U32(B|(B<<8)))); - } - - // check if next bit matches the prediction, accounting for the required bitmask - if (length>0 && (((expectedByte^B)&sparse[hashIndex].bitMask)>>(8-x.bpos))!=0) - length = 0; - - if (valid) { - if (length>1 && ((sparse[hashIndex].bitMask>>(7-x.bpos))&1)>0) { - const int expectedBit = (expectedByte>>(7-x.bpos))&1; - const int sign = 2*expectedBit-1; - m.add(sign*(min(length-1, 64)<<4)); // +/- 16..1024 - m.add(sign*(1<>(8-x.bpos))), NumHashes*2048); //8192 - return length; - } -};*/ //////////////////////////// matchModel /////////////////////////// class MatchContext { private: @@ -4521,22 +4360,6 @@ U8 GetCWord(File*f){ if(b&1) return ((f->getc()<<8)|b)>>1; return b>>1; } -/* -int parse_zlib_header(int header) { - switch (header) { - case 0x2815 : return 0; case 0x2853 : return 1; case 0x2891 : return 2; case 0x28cf : return 3; - case 0x3811 : return 4; case 0x384f : return 5; case 0x388d : return 6; case 0x38cb : return 7; - case 0x480d : return 8; case 0x484b : return 9; case 0x4889 : return 10; case 0x48c7 : return 11; - case 0x5809 : return 12; case 0x5847 : return 13; case 0x5885 : return 14; case 0x58c3 : return 15; - case 0x6805 : return 16; case 0x6843 : return 17; case 0x6881 : return 18; case 0x68de : return 19; - case 0x7801 : return 20; case 0x785e : return 21; case 0x789c : return 22; case 0x78da : return 23; - } - return -1; -} -int zlib_inflateInit(z_streamp strm, int zh) { - if (zh==-1) return inflateInit2(strm, -MAX_WBITS); else return inflateInit(strm); -}*/ - bool IsGrayscalePalette(File* in, int n = 256, int isRGBA = 0){ U64 offset = in->curpos(); @@ -4667,7 +4490,7 @@ U64 gif, plt, gray ; }; - +char *jpegdet; Filetype detect(File* in, U64 n, Filetype type, int &info, int &info2, int it=0,int s1=0) { U32 buf4=0,buf3=0, buf2=0, buf1=0, buf0=0; // last 8 bytes U64 start= in->curpos(); @@ -4759,13 +4582,14 @@ Filetype detect(File* in, U64 n, Filetype type, int &info, int &info2, int it=0, static U64 tiffImageStart=0; static U64 tiffImageEnd=0; bool tiffMM=false; - + static BlockData z; + static VM vm(jpegdet,z); static int deth=0,detd=0; // detected header/data size in bytes static Filetype dett; // detected block type if (deth >1) return in->setpos(start+deth),deth=0,dett; else if (deth ==-1) return in->setpos(start),deth=0,dett; else if (detd) return in->setpos( start+detd),detd=0,DEFAULT; - + int dstate=0; for (U64 i=0; igetc(); @@ -4776,6 +4600,24 @@ Filetype detect(File* in, U64 n, Filetype type, int &info, int &info2, int it=0, buf1=buf1<<8|buf0>>24; buf0=buf0<<8|c; + // detect jpeg data with jpeg.det + // get state + dstate=vm.detect(buf0,i); + if (dstate==1 && type!=JPEG){ //start + //request current state data + int jst=vm.detect(buf0,-1); + //printf("start %d\n",jst); + return in->setpos(start+jst), JPEG; + } + if (dstate==2){ //info + } + if (dstate==3){ //end + //request current state data + int jst=vm.detect(buf0,-1); + // printf("end %d\n",jst); + return in->setpos( start+jst),DEFAULT; + } + if ((c<128 && c>=32) || c==10 || c==13 || c==0x12 || c==9 || c==4 ) textbin++,info=textbin; if(tiffImages>=0){ @@ -5173,7 +5015,7 @@ Filetype detect(File* in, U64 n, Filetype type, int &info, int &info2, int it=0, // SOF0 (FF C0 xx xx 08) and SOS (FF DA) within a reasonable distance. // Detect end by any code other than RST0-RST7 (FF D9-D7) or // a byte stuff (FF 00). - +/* if (!soi && i>=3 && (( ((buf0&0xffffff00)==0xffd8ff00 && ((U8)buf0==0xC0 || (U8)buf0==0xC4 || ((U8)buf0>=0xDB && (U8)buf0<=0xFE))) ||(buf0&0xfffffff0)==0xffd8ffe0 ) ) @@ -5197,7 +5039,7 @@ Filetype detect(File* in, U64 n, Filetype type, int &info, int &info2, int it=0, && (buf0&0xff)!=0 && ((buf0&0xf8)!=0xd0 )) { return DEFAULT; } - if (type==JPEG) continue; + if (type==JPEG) continue;*/ // Detect .wav file header if (buf0==0x52494646) wavi=i,wavm=0; @@ -8595,15 +8437,17 @@ int expand(String& archive, String& s, const char* fname, int base) { U64 filestreamsize[streamc]; -char *pp ="int c,c1,*t; \n void update(int y,int c0,int b,int c4,int p){ \n" +char *pp = +"int c,c1,*t; \n void update(int y,int c0,int b,int c4,int p){ \n" "int cc1; \n cc1=c+c1; \n if (y) t[cc1]=t[cc1]+((65536-t[cc1])>>5); \n" "else t[cc1]=t[cc1]-(t[cc1]>>5); \n" "if ((c=c*2+y)>=512) c1=(c1+(c&255)<<9)&0x1ffffff,c=1; \n" "return apm(0,(t[c+c1]>>4),c,7);} \n void block(int a,int b){} \n" -"int main() { \n int i; \n if (!(t=malloc(0x2000000*sizeof(int)))) exit(-1); \n" +"int main() { \n int i; \n if (!(t=malloc(0x2000000,sizeof(int)))) exit(-1); \n" "vms(0,1,0,0,0,0,0,0,0); \n vmi(2,0,256,0,-1);\nc1=0,c=1; \n" "for (i=0; i<0x2000000; i++) t[i]=32768;}"; + void compressStream(int streamid,U64 size, File* in, File* out) { int i; //stream i=streamid; @@ -8615,6 +8459,8 @@ void compressStream(int streamid,U64 size, File* in, File* out) { int datasegmentinfo; Filetype datasegmenttype; U64 scompsize=0; + int modelSize=0; + int modelSizeCompressed=0; U8 *p; datasegmentsize=size; U64 total=size; @@ -8667,6 +8513,7 @@ void compressStream(int streamid,U64 size, File* in, File* out) { fseek ( moin , 0 , SEEK_END ); int fsz=ftello(moin); + modelSize=fsz; assert(fsz>0); fseek ( moin , 0 , SEEK_SET ); //compress model file @@ -8675,15 +8522,13 @@ void compressStream(int streamid,U64 size, File* in, File* out) { enm->flush(); delete enm; delete prm; - printf("Compressed model from %d",fsz); + fsz=modelo->curpos(); //ftello(modelo); + modelSizeCompressed=fsz; modelo->setpos(0);// fseek ( modelo , 0 , SEEK_SET ); p = (U8 *)calloc(fsz+1,1); modelo->blockread(p,fsz) ;//fread( p, 1,fsz,modelo); p[fsz] = 0; - printf(" to %d bytes\n",fsz); - // write compressed model to archive - //fwrite(&p[0], 1, fsz, out); out->blockwrite(&p[0],fsz); //read again model file fseek ( moin , 0 , SEEK_END ); @@ -8804,7 +8649,8 @@ void compressStream(int streamid,U64 size, File* in, File* out) { if (level>0) delete threadpredict; delete threadencode; - printf("Stream(%d) compressed from %d to %d bytes\n",i,(U32)size, (U32)out->curpos()); + printf("Stream(%d) compressed from %d to %d bytes\n",i,(U32)size, (U32)out->curpos()-modelSizeCompressed); + printf(" Model compressed from %d to %d bytes\n",modelSize, modelSizeCompressed); } #ifdef MT @@ -9033,13 +8879,18 @@ printf("\n"); DEFAULT_OPTION); quit(); } - /* char *pp = "int c,c1,*t; \n void update(int y,int c0,int b,int c4,int p){ \n" - "if (y) t[c+c1]=t[c+c1]+((65536-t[c+c1])>>5); \n" - "else t[c+c1]=t[c+c1]-(t[c+c1]>>5); \n" - "if ((c=c*2+y)>=512) c1=(c1+(c&255)<<9)&0x1ffffff,c=1; \n" - "return (t[c+c1]>>4);} \n void block(int a,int b){} \n" - "int main() { \n int i; \n if (!(t=malloc(0x2000000*sizeof(int)))) exit(-1); \n" - "c1=0,c=1; \n for (i=0; i<0x2000000; i++) t[i]=32768;}";*/ + + // jpeg detection code for vm + // hardcoded for testing + FILE *det=fopen("jpeg.det","rb"); + fseeko(det, 0, SEEK_END); + U32 szi=(U32)ftello(det); + fseeko(det, 0, SEEK_SET); + jpegdet = (char *)calloc(szi+1,1); + fread( jpegdet, 1,szi,det); + jpegdet[szi+1]=0; + fclose(det); + File* archive=0; // compressed file int files=0; // number of files to compress/decompress Array fname(1); // file names (resized to files) @@ -9164,7 +9015,7 @@ printf("\n"); Predictors* predictord; predictord=new Predictor(pp); en=new Encoder(mode, archive,*predictord); - + en->predictor.setdebug(1); // Compress header if (mode==COMPRESS) { int len=header_string.size(); @@ -9497,15 +9348,8 @@ printf("\n"); //load config file from archive stream //read compressed file header and data int fsz=0; - Encoder* enm; + Encoder* enm; Predictors* prm; - /* char *ppp = "int c,c1,*t; \n void update(int y,int c0,int b,int c4,int p){ \n" - "if (y) t[c+c1]=t[c+c1]+((65536-t[c+c1])>>5); \n" - "else t[c+c1]=t[c+c1]-(t[c+c1]>>5); \n" - "if ((c=c*2+y)>=512) c1=(c1+(c&255)<<9)&0x1ffffff,c=1; \n" - "return (t[c+c1]>>4);} \n void block(int a,int b){} \n" - "int main() { \n int i; \n if (!(t=malloc(0x2000000*sizeof(int)))) exit(-1); \n" - "c1=0,c=1; \n for (i=0; i<0x2000000; i++) t[i]=32768;}";*/ prm=new Predictor(pp); enm=new Encoder(DECOMPRESS, archive,*prm); prm->set(); @@ -9537,34 +9381,7 @@ printf("\n"); case 10: { printf("%stext wrt stream(%d).\n",i==10?"big":"",i); break;} case 11: { printf("dec stream(11).\n"); break;} } - /*if (level>0){ - switch(i) { - case 0: { - predictord=new Predictor(); - break;} - case 1: { - predictord=new PredictorJPEG(); break;} - case 2: { - predictord=new PredictorIMG1(); break;} - case 3: { - predictord=new PredictorIMG4(); break;} - case 4: { - predictord=new PredictorIMG8(); break;} - case 5: { - predictord=new PredictorIMG24(); break;} - case 6: { - predictord=new PredictorAUDIO2(); break;} - case 7: { - predictord=new PredictorEXE(); break;} - case 8: { - predictord=new PredictorTXTWRT(); break;} - case 9: - case 10: { - predictord=new PredictorTXTWRT(); break;} - case 11: { - predictord=new PredictorDEC(); break;} - } - }*/ + defaultencoder=new Encoder (mode, archive,*predictord); if ((i>=0 && i<=7)||i==10||i==11){ while (datasegmentsize>0) { diff --git a/test3d.cfg b/test3d.cfg index 4684045..987a680 100644 --- a/test3d.cfg +++ b/test3d.cfg @@ -51,10 +51,9 @@ int update(int y,int c0,int bpos,int c4,int pos){ int fl,matched,r,vv,order; if (bpos== 0){ c1= buf(1), c2= buf(2), c3= buf(3); - if (c1>255 ||c2>255 ||c3>255) printf("suur "); - f4= f4*16+(c1>>4); - w4= w4*4+mpw[c1>>4]; - tt=tt*8+mtt[c1>>4]; + f4= f4<<4|(c1>>4); + w4= w4<<2|mpw[c1>>4]; + tt=tt<<3|mtt[c1>>4]; //normal for (i=13; i>0; --i) // update order 0-11 context hashes t[i]=t[i-1]*257+c1; @@ -99,7 +98,7 @@ int update(int y,int c0,int bpos,int c4,int pos){ if (c>='a' && c<='z' || c>=128) { word0=h2(word0, c); text0=text0*15952+c;//997*16 - words=words+1; + words=words|1; wordlen++; wordlen=min(wordlen,45); } @@ -342,14 +341,14 @@ void block(int a,int b) { } // main is called only once after VM init. int main() { - if (!(t = malloc(14*sizeof(int)))) { exit(-1); } - if (!(t1 = malloc(256*sizeof(int)))) { exit(-1); } - if (!(t2 = malloc(0x10000*sizeof(int)))) { exit(-1); } - if (!(cpos1 = malloc(256*sizeof(int)))) { exit(-1); } - if (!(cpos2 = malloc(256*sizeof(int)))) { exit(-1); } - if (!(cpos3 = malloc(256*sizeof(int)))) { exit(-1); } - if (!(cpos4 = malloc(256*sizeof(int)))) { exit(-1); } - if (!(wpos1 = malloc(0x10000*sizeof(int)))) { exit(-1); } + if (!(t = malloc(14,sizeof(int)))) { exit(-1); } + if (!(t1 = malloc(256,sizeof(int)))) { exit(-1); } + if (!(t2 = malloc(0x10000,sizeof(int)))) { exit(-1); } + if (!(cpos1 = malloc(256,sizeof(int)))) { exit(-1); } + if (!(cpos2 = malloc(256,sizeof(int)))) { exit(-1); } + if (!(cpos3 = malloc(256,sizeof(int)))) { exit(-1); } + if (!(cpos4 = malloc(256,sizeof(int)))) { exit(-1); } + if (!(wpos1 = malloc(0x10000,sizeof(int)))) { exit(-1); } //SMC,APM1,APM2,RCM,SCM,MCM,CM,MX,MC (1,2,3,4,5,6,7,8,9) vms( 0,3,0,3,5,0,10,1,1) ; //set 3 apm, 3 rcm,1 scm,9 cm, 1 mixer,1 match vmi(RCM,0,-4,0,0); //RCM(0) mem/4, 0, mixer 0 @@ -384,5 +383,4 @@ int main() { ic=bc=pc=vc=qc=lvc=wc=f4=words=number1=number0=0; frstchar=spaces=spacecount=wordcount=wordlen=wordlen1=spafdo=w4=f4=tt=0; prm=1024; - mpw[0]=4; } diff --git a/test3i8.cfg b/test3i8.cfg index 802328e..7e17039 100644 --- a/test3i8.cfg +++ b/test3i8.cfg @@ -82,141 +82,142 @@ int update(int y,int c0,int bpos,int c4,int pos){ if (itype==0){ //faster, for smooth images - vmx(MCM, 0,h3(++i, pW ,0)); - vmx(MCM, 0,h3(++i, pN ,0)); - vmx(MCM, 0,h3(++i, pNE ,0)); - vmx(MCM, 0,h3(++i, pWW ,0)); - vmx(MCM, 0,h3(++i, pNN ,0)); - vmx(MCM, 0,h3(++i, pNWNW ,pW )); - vmx(MCM, 0,h3(++i, pNWW ,0)); - vmx(MCM, 0,h3(++i, pNNE ,0)); - vmx(MCM, 0,h3(++i, HBB1,0)); // - vmx(MCM, 0,h3(++i, HBB2,0)); // - vmx(MCM, 0,h3(++i, pGw ,pW )); + vmx(CM, 0,h3(++i, pW ,0)); + vmx(CM, 0,h3(++i, pN ,0)); + vmx(CM, 0,h3(++i, pNE ,0)); + vmx(CM, 0,h3(++i, pWW ,0)); + vmx(CM, 0,h3(++i, pNN ,0)); + vmx(CM, 0,h3(++i, pNWNW ,pW )); + vmx(CM, 0,h3(++i, pNWW ,0)); + vmx(CM, 0,h3(++i, pNNE ,0)); + vmx(CM, 0,h3(++i, HBB1,0)); // + vmx(CM, 0,h3(++i, HBB2,0)); // + vmx(CM, 0,h3(++i, pGw ,pW )); - vmx(MCM, 0,h3(++i, pGn ,pW )); - vmx(MCM, 0,h3(++i, pDh ,pW )); - vmx(MCM, 0,h3(++i, pDv ,pW )); - vmx(MCM, 0,h3(++i, pGv,pW)); // - vmx(MCM, 0,h3(++i, pGh,pW)); // - vmx(MCM, 0,h3(++i, pGv,pN)); // - vmx(MCM, 0,h3(++i, pGh,pN)); // - vmx(MCM, 0,h3(++i, errrp,pW )); + vmx(CM, 0,h3(++i, pGn ,pW )); + vmx(CM, 0,h3(++i, pDh ,pW )); + vmx(CM, 0,h3(++i, pDv ,pW )); + vmx(CM, 0,h3(++i, pGv,pW)); // + vmx(CM, 0,h3(++i, pGh,pW)); // + vmx(CM, 0,h3(++i, pGv,pN)); // + vmx(CM, 0,h3(++i, pGh,pN)); // + vmx(CM, 0,h3(++i, errrp,pW )); - vmx(MCM, 0,h3(++i,mean,logvar)); - vmx(MCM, 0,h3(++i,pGn ,pGw )); - vmx(MCM, 0,h3(++i,pDh , pDv )); - vmx(MCM, 0,h3(++i,pGv, pGh)); // + vmx(CM, 0,h3(++i,mean,logvar)); + vmx(CM, 0,h3(++i,pGn ,pGw )); + vmx(CM, 0,h3(++i,pDh , pDv )); + vmx(CM, 0,h3(++i,pGv, pGh)); // - vmx(MCM, 0,h3(++i,abs(min(pW,min( pN, pNW)) + max(pW,max(pN,pNW)) -pNW),0)); // + vmx(CM, 0,h3(++i,abs(min(pW,min( pN, pNW)) + max(pW,max(pN,pNW)) -pNW),0)); // - vmx(MCM, 0,h3(++i, pW2, pNW2)); - vmx(MCM, 0,h3(++i, pW2, pN2)); - vmx(MCM, 0,h3(++i, pNW2, buf(w*2)>>2)); - vmx(MCM, 0,h3(++i, pW2, pN2)); - vmx(MCM, 0,h3(++i, pNW2, pNWW>>2)); - vmx(MCM, 0,h3(++i, pNWW>>2, buf(w+2)>>2)); - vmx(MCM, 0,h2(++i, (pNWW+pNNE)>>1)); - vmx(MCM, 0,h2(++i, (pN+pNNE)>>1)); + vmx(CM, 0,h3(++i, pW2, pNW2)); + vmx(CM, 0,h3(++i, pW2, pN2)); + vmx(CM, 0,h3(++i, pNW2, buf(w*2)>>2)); + vmx(CM, 0,h3(++i, pW2, pN2)); + vmx(CM, 0,h3(++i, pNW2, pNWW>>2)); + vmx(CM, 0,h3(++i, pNWW>>2, buf(w+2)>>2)); + vmx(CM, 0,h2(++i, (pNWW+pNNE)>>1)); + vmx(CM, 0,h2(++i, (pN+pNNE)>>1)); - vmx(MCM, 0,h3(++i, pGw ,pN )); + vmx(CM, 0,h3(++i, pGw ,pN )); - vmx(MCM, 0,h3(++i, pGn ,pN )); - vmx(MCM, 0,h4(++i, pNN ,pNE ,pW )); - vmx(MCM, 0,h2(++i, (pW+pNW)>>1)); - vmx(MCM, 0,h2(++i, (pW+pN)>>1)); - vmx(MCM, 0,h2(++i, (pNW+buf(w*2))>>1)); - vmx(MCM, 0,h2(++i, (pW+pN)>>1)); - vmx(MCM, 0,h2(++i, (pNW+pNWW)>>1)); - vmx(MCM, 0,h2(++i, (pNWW+buf(w+2))>>1)); - vmx(MCM, 0,h2(++i, (pNWW+pNNE)>>1)); - //vmx(MCM, 0,h2(++i, (pN+pNNE)>>1)); - vmx(MCM, 0,h4(++i, pNNE ,pN ,pW )); - vmx(MCM, 0,h5(++i, pNWW ,pN ,pNE ,pW)); - vmx(MCM, 0,h4(++i, pGn ,pNE ,pNNE )); - vmx(MCM, 0,h5(++i, pWW ,pNWW ,pNW ,pN)); - vmx(MCM, 0,h4(++i,pNNW , pNW ,pW )); - vmx(MCM, 0,h4(++i, pNW2, pWWW>>2, pN2)); - vmx(MCM, 0,h4(++i, pWWW>>2, pNE>>2, pNNE>>2)); + vmx(CM, 0,h3(++i, pGn ,pN )); + vmx(CM, 0,h4(++i, pNN ,pNE ,pW )); + vmx(CM, 0,h2(++i, (pW+pNW)>>1)); + vmx(CM, 0,h2(++i, (pW+pN)>>1)); + vmx(CM, 0,h2(++i, (pNW+buf(w*2))>>1)); + vmx(CM, 0,h2(++i, (pW+pN)>>1)); + vmx(CM, 0,h2(++i, (pNW+pNWW)>>1)); + vmx(CM, 0,h2(++i, (pNWW+buf(w+2))>>1)); + vmx(CM, 0,h2(++i, (pNWW+pNNE)>>1)); + //vmx(CM, 0,h2(++i, (pN+pNNE)>>1)); + vmx(CM, 0,h4(++i, pNNE ,pN ,pW )); + vmx(CM, 0,h5(++i, pNWW ,pN ,pNE ,pW)); + vmx(CM, 0,h4(++i, pGn ,pNE ,pNNE )); + vmx(CM, 0,h5(++i, pWW ,pNWW ,pNW ,pN)); + vmx(CM, 0,h4(++i,pNNW , pNW ,pW )); + vmx(CM, 0,h4(++i, pNW2, pWWW>>2, pN2)); + vmx(CM, 0,h4(++i, pWWW>>2, pNE>>2, pNNE>>2)); - vmx(MCM, 0,h4(++i, pNW2, pW2, pN2)); - vmx(MCM, 0,h4(++i, pN2, pNW2, pNWW>>2)); - vmx(MCM, 0,h4(++i, pW2, pN2, pNN>>2)); + vmx(CM, 0,h4(++i, pNW2, pW2, pN2)); + vmx(CM, 0,h4(++i, pN2, pNW2, pNWW>>2)); + vmx(CM, 0,h4(++i, pW2, pN2, pNN>>2)); } // 2 x else { i=512; - vmx(MCM, 0,h3(++i, pW,0)); - vmx(MCM, 0,h3(++i, pN, 0)); - vmx(MCM, 0,h3(++i, pNW, 0)); - vmx(MCM, 0,h3(++i, pNWW, 0)); - vmx(MCM, 0,h3(++i, pN, 0)); - vmx(MCM, 0,h3(++i, HBB1,0)); // // - vmx(MCM, 0,h3(++i, HBB2,0)); - vmx(MCM, 0,h3(++i, pGv,pW)); - vmx(MCM, 0,h3(++i, pGh,pW)); - vmx(MCM, 0,h3(++i, pGv,pN)); - vmx(MCM, 0,h3(++i, pGh,pN)); - vmx(MCM, 0,h3(++i,pGv, pGh)); - vmx(MCM, 0,h3(++i,abs(min(pW,min( pN, pNW)) + max(pW,max(pN,pNW)) -pNW),0)); - vmx(MCM, 0,h3(++i, (pN+pNW-pNWW), 0)); - vmx(MCM, 0,h3(++i,(pNW+(pN-pNWW)>>1), 0)); - vmx(MCM, 0,h3(++i, (pN+pNWW)>>1, 0)); - vmx(MCM, 0,h3(++i, (pN-pNW), pW1)); - vmx(MCM, 0,h3(++i,(pNW-pNWW), pW1)); - vmx(MCM, 0,h3(++i, (pNWW+pN), pW1)); + vmx(CM, 0,h3(++i, pW,0)); + vmx(CM, 0,h3(++i, pN, 0)); + vmx(CM, 0,h3(++i, pNW, 0)); + vmx(CM, 0,h3(++i, pNWW, 0)); + vmx(CM, 0,h3(++i, pN, 0)); + vmx(CM, 0,h3(++i, HBB1,0)); // // + vmx(CM, 0,h3(++i, HBB2,0)); + vmx(CM, 0,h3(++i, pGv,pW)); + vmx(CM, 0,h3(++i, pGh,pW)); + vmx(CM, 0,h3(++i, pGv,pN)); + vmx(CM, 0,h3(++i, pGh,pN)); + vmx(CM, 0,h3(++i,pGv, pGh)); + vmx(CM, 0,h3(++i,abs(min(pW,min( pN, pNW)) + max(pW,max(pN,pNW)) -pNW),0)); + vmx(CM, 0,h3(++i, (pN+pNW-pNWW), 0)); + vmx(CM, 0,h3(++i,(pNW+(pN-pNWW)>>1), 0)); + vmx(CM, 0,h3(++i, (pN+pNWW)>>1, 0)); + vmx(CM, 0,h3(++i, (pN-pNW), pW1)); + vmx(CM, 0,h3(++i,(pNW-pNWW), pW1)); + vmx(CM, 0,h3(++i, (pNWW+pN), pW1)); - vmx(MCM, 0,h3(++i, pW2, pNW2)); - vmx(MCM, 0,h3(++i, pW2, pN2)); - vmx(MCM, 0,h3(++i, pNW2, buf(w*2)>>2)); - vmx(MCM, 0,h3(++i, pW2, pN2)); - vmx(MCM, 0,h3(++i, pNW2, pNWW>>2)); - vmx(MCM, 0,h3(++i, pNWW>>2, buf(w+2)>>2)); - vmx(MCM, 0,h3(++i, pNWW>>2, pNNE>>2)); - vmx(MCM, 0,h3(++i, pN2, pNNE>>2)); - vmx(MCM, 0,h2(++i, pW+pNW>>1)); - vmx(MCM, 0,h2(++i, pW+pN1)); - vmx(MCM, 0,h2(++i, pNW+buf(w*2)>>1)); - vmx(MCM, 0,h2(++i, pW+pN1)); - vmx(MCM, 0,h2(++i, pNW+pNWW>>1)); - vmx(MCM, 0,h2(++i, pNWW+buf(w+2)>>1)); - vmx(MCM, 0,h2(++i, pNWW+pNNE>>1)); - vmx(MCM, 0,h2(++i, pN+pNNE>>1)); + vmx(CM, 0,h3(++i, pW2, pNW2)); + vmx(CM, 0,h3(++i, pW2, pN2)); + vmx(CM, 0,h3(++i, pNW2, buf(w*2)>>2)); + vmx(CM, 0,h3(++i, pW2, pN2)); + vmx(CM, 0,h3(++i, pNW2, pNWW>>2)); + vmx(CM, 0,h3(++i, pNWW>>2, buf(w+2)>>2)); + vmx(CM, 0,h3(++i, pNWW>>2, pNNE>>2)); + vmx(CM, 0,h3(++i, pN2, pNNE>>2)); + vmx(CM, 0,h2(++i, pW+pNW>>1)); + vmx(CM, 0,h2(++i, pW+pN1)); + vmx(CM, 0,h2(++i, pNW+buf(w*2)>>1)); + vmx(CM, 0,h2(++i, pW+pN1)); + vmx(CM, 0,h2(++i, pNW+pNWW>>1)); + vmx(CM, 0,h2(++i, pNWW+buf(w+2)>>1)); + vmx(CM, 0,h2(++i, pNWW+pNNE>>1)); + vmx(CM, 0,h2(++i, pN+pNNE>>1)); // 3 x - vmx(MCM, 0,h4(++i, pNW2, pW2, pN2)); - vmx(MCM, 0,h4(++i, pN2, pNW2, pNWW>>2)); - vmx(MCM, 0,h4(++i, pW2, pN2, pNN>>2)); + vmx(CM, 0,h4(++i, pNW2, pW2, pN2)); + vmx(CM, 0,h4(++i, pN2, pNW2, pNWW>>2)); + vmx(CM, 0,h4(++i, pW2, pN2, pNN>>2)); // mixed - vmx(MCM, 0,h4(++i, pWWW+pNW>>1, pW2, pN2)); - vmx(MCM, 0,h4(++i, pN+pW1,pNW+buf(w*2)>>1,pN2)); - vmx(MCM, 0,h3(++i, pN+pW2,pN+pNW2)); - vmx(MCM, 0,h3(++i, pN+pW1,pNW+buf(w*2)>>1)); - vmx(MCM, 0,h3(++i, pN+pW1,pN+pNNE>>1)); - vmx(MCM, 0,h3(++i, pN+pW1,pNWW+pNNE>>1)); - vmx(MCM, 0,h3(++i, pNW+buf(w*2)>>1,pN+pNNE>>1)); - vmx(MCM, 0,h3(++i, pN+pNW>>1,pNW+pNWW>>1)); - vmx(MCM, 0,h3(++i, pW+pN1,pNW+buf(w*2)>>1)); - vmx(MCM, 0,h3(++i, pW+pN2,pNW+pNWW>>2)); - vmx(MCM, 0,h2(++i, (pW-pN1)+pNW2)); - vmx(MCM, 0,h2(++i, (pN-pNW>>1)+pW2)); - vmx(MCM, 0,h2(++i, -pW+pN+pNW2)); + vmx(CM, 0,h4(++i, pWWW+pNW>>1, pW2, pN2)); + vmx(CM, 0,h4(++i, pN+pW1,pNW+buf(w*2)>>1,pN2)); + vmx(CM, 0,h3(++i, pN+pW2,pN+pNW2)); + vmx(CM, 0,h3(++i, pN+pW1,pNW+buf(w*2)>>1)); + vmx(CM, 0,h3(++i, pN+pW1,pN+pNNE>>1)); + vmx(CM, 0,h3(++i, pN+pW1,pNWW+pNNE>>1)); + vmx(CM, 0,h3(++i, pNW+buf(w*2)>>1,pN+pNNE>>1)); + vmx(CM, 0,h3(++i, pN+pNW>>1,pNW+pNWW>>1)); + vmx(CM, 0,h3(++i, pW+pN1,pNW+buf(w*2)>>1)); + vmx(CM, 0,h3(++i, pW+pN2,pNW+pNWW>>2)); + vmx(CM, 0,h2(++i, (pW-pN1)+pNW2)); + vmx(CM, 0,h2(++i, (pN-pNW>>1)+pW2)); + + vmx(CM, 0,h2(++i, (pN+pNW2-pW))); - vmx(MCM, 0,h2(++i,(pW*2-pN)>>1)); - vmx(MCM, 0,h3(++i,mean,logvar)); - vmx(MCM, 0,h2(++i,(pNW*2-buf(w*2))>>1)); - vmx(MCM, 0,h2(++i,(pW+pNW-pNWW)>>1)); + vmx(CM, 0,h2(++i,(pW*2-pN)>>1)); + vmx(CM, 0,h3(++i,mean,logvar)); + vmx(CM, 0,h2(++i,(pNW*2-buf(w*2))>>1)); + vmx(CM, 0,h2(++i,(pW+pNW-pNWW)>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pWWW)>>2,(pN+pNW)>>2)); - vmx(MCM, 0,h3(++i, (pWWWW+pWWW)>>1,(pNW+buf(w*2))>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pWWW)>>1,(pN+pNNE)>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pWWW)>>1,(pNWW+pNNE)>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pW)>>2,(buf(w-3)+pNW)>>2)); - vmx(MCM, 0,h3(++i, (pWWWW+pW)>>1,(pNW+buf(w*2))>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pW)>>1,(buf(w-3)+buf(w*2-3))>>1)); - vmx(MCM, 0,h3(++i, (pWWWW+pW)>>1,(buf(w+3)+buf(w*2+3))>>1)); - vmx(MCM, 0,h4(++i, pNW2, pWWW>>2, pN2)); - vmx(MCM, 0,h4(++i, pWWW>>2, pNE>>2, pNNE>>2)); + vmx(CM, 0,h3(++i, (pWWWW+pWWW)>>2,(pN+pNW)>>2)); + vmx(CM, 0,h3(++i, (pWWWW+pWWW)>>1,(pNW+buf(w*2))>>1)); + vmx(CM, 0,h3(++i, (pWWWW+pWWW)>>1,(pN+pNNE)>>1)); + vmx(CM, 0,h3(++i, (pWWWW+pWWW)>>1,(pNWW+pNNE)>>1)); + vmx(CM, 0,h3(++i, (pWWWW+pW)>>2,(buf(w-3)+pNW)>>2)); + vmx(CM, 0,h3(++i, (pWWWW+pW)>>1,(pNW+buf(w*2))>>1)); + vmx(CM, 0,h3(++i, (pWWWW+pW)>>1,(buf(w-3)+buf(w*2-3))>>1)); + vmx(CM, 0,h3(++i, (pWWWW+pW)>>1,(buf(w+3)+buf(w*2+3))>>1)); + vmx(CM, 0,h4(++i, pNW2, pWWW>>2, pN2)); + vmx(CM, 0,h4(++i, pWWW>>2, pNE>>2, pNNE>>2)); } vmx(SCM,0,(pW+pNW)>>1); @@ -255,8 +256,8 @@ void block(int a,int b) { // main is called only once after VM init. int main() { //SMC,APM1,APM2,RCM,SCM,MCM,CM,MX,MC (1,2,3,4,5,6,7,8,9) - vms( 0,3,0,0,6,1,0,1,1); - vmi(MCM,0,16,57+8,0); + vms( 0,3,0,0,6,0,1,1,1); + vmi(CM,0,16,57+8,0); vmi(MC,0,1,4096,0);//match(0), mem*1, maxlen 4096, mixer(0) vmi(SCM,0,16,0,0); vmi(SCM,1,16,0,0); @@ -267,7 +268,7 @@ int main() { vmi(APM1,0,256,0,-1); vmi(APM1,1,0x10000,0,-1); vmi(APM1,2,0x10000,0,-1); - vmi(MX,0,59*7+6*2+8*2+18,3368,7);// mixer(0), 104 inputs, context size 848, context sets 6 + vmi(MX,0,65*6+6*2+8*2+18,3368,7);// mixer(0), 104 inputs, context size 848, context sets 6 col=ml=ml1=itype=blpos=pDv=pW=pNW=0; id8=id9=1; diff --git a/test3img.cfg b/test3img.cfg index 0f20750..52d2c5c 100644 --- a/test3img.cfg +++ b/test3img.cfg @@ -10,15 +10,15 @@ // Mixer MX // SMC,APM1,APM2,RCM,SCM,MCM,CM,MX (1,2,3,4,5,6,7,8,9) enum {SMC=1,APM1,APM2,RCM,SCM,MCM,CM,MX,MC}; -//int *t; +int *t; int r0 ,r1 ,r2 ,r3 ,N ,w; int* cxt; // contexts // update is called in VM after every bit int update(int y,int c0,int bpos,int c4,int pos){ int i; //mxa(0,256); //add to mixer(0) - //for (i=0; i>(7-bpos))&1); @@ -33,7 +33,7 @@ int update(int y,int c0,int bpos,int c4,int pos){ cxt[6]=((r0&1)|((r1>>4)&0x1d)|((r2>>1)&0x60)|(r3&0xC0)); cxt[7]=(((r0>>4)&0x2AC)|(r1&0xA4)|(r2&0x349)|((!r3)&0x14D)); //pr=0; - for (i=0; i>3; //return apm(0,pr>>3,c0,7); mxc(0); //mix components into mixer(0) @@ -51,18 +51,18 @@ void block(int a,int b) { } // main is called only once after VM init. int main() { - //if (!(t = malloc(0x10200*sizeof(int)))) { exit(-1); } - if (!(cxt = malloc(8*sizeof(int)))) { exit(-1); } + if (!(t = malloc(0x10000,sizeof(int)))) { exit(-1); } + if (!(cxt = malloc(8,sizeof(int)))) { exit(-1); } vms( 8,0,0,0,0,0,0,1,1); //8 SMC,1 MX, 1 MC vmi(MC,0,1,65534,0); //match(0), mem*1, maxlen 65534, mixer(0) - vmi( SMC,0,8,0,0); //SMC(0), context size 256,0,mixer(0) - vmi( SMC,1,8,0,0); //... - vmi( SMC,2,15,0,0); - vmi( SMC,3,15,0,0); - vmi( SMC,4,15,0,0); - vmi( SMC,5,15,0,0); - vmi( SMC,6,15,0,0); - vmi( SMC,7,15,0,0); + vmi( SMC,0,256,0,0); //SMC(0), context size 256,0,mixer(0) + vmi( SMC,1,256,0,0); //... + vmi( SMC,2,256,0,0); + vmi( SMC,3,256,0,0); + vmi( SMC,4,256,0,0); + vmi( SMC,5,256,0,0); + vmi( SMC,6,256,0,0); + vmi( SMC,7,256,0,0); vmi(MX,0,8*2+18+1,1280,5); // mixer(0), 12 inputs, context size 1280, context sets 5 r0=0,r1=0,r2=0,r3=0; N=8; diff --git a/vm.cpp b/vm.cpp index dada799..05a9250 100644 --- a/vm.cpp +++ b/vm.cpp @@ -87,10 +87,11 @@ int *e, *le, *text,*codestart, // current position in emitted code loc, // local variable offset line; // current line number int fd, bt, poolsz, *idmain,*idp,*idupdate; + int *iddetect, *iddecode, *idencode;//functions detect,decode and encode //int *iddetect,*iddecode,*idencode; // int *pc, *sp,*sp0, *bp, cycle; // vm registers int i, *t,*pc0,tmp; // temps - unsigned int a; + int a; int initvm( ) ; char *mod; public: @@ -111,8 +112,9 @@ char *mod; int currentc; //current component, used in vmi int *mcomp; //component list set in vmi int initdone; //set to 1 after main exits - Array mem; + //Array mem; int mindex; + //Array vmmem;//array of allocated memory VM(char* m,BlockData& bd); ~VM() ; void next(); @@ -122,17 +124,18 @@ int dovm(int *ttt); #ifdef VMJIT int dojit(); #endif + int detect(int c4,int pos); int block(int info1,int info2); int doupdate(int y, int c0, int bpos,U32 c4,int pos); void killvm( ); void emit(int op,int val); void decompile(); }; -char* vmmalloc(VM* v,size_t i){ - programChecker.alloc(U64(i)); +char* vmmalloc(VM* v,size_t i,int w){ + programChecker.alloc(U64(i*w)); - char*ptr= (char*)calloc(i,1); - v->mem[v->mindex++]=ptr; + char*ptr= (char*)calloc(i*w,1); + //v->mem[v->mindex++]=ptr; if (ptr==0) perror("mem error "),printf("%d ",i),quit("VM mem alloc fail"); return ptr;//malloc(i); } @@ -147,9 +150,9 @@ if ( smc>0 ) delete[] smC; if ( mx>0 ) delete[] mxC; if ( mc>0 ) delete[] mcC; if ( totalc>0 ) free( mcomp); - for (int i=0;i=0) ; + assert(state>=0 && state<256) ; return nex(state,v->x.y); } int smp(VM* v,int a,int cx,int limit){ // StateMap predict @@ -347,7 +350,7 @@ int gcr(VM* v,int a,int b,int c){ //this,mixer,index,component type } return 0; } -VM::VM(char* m,BlockData& bd):x(bd),mem(20) { +VM::VM(char* m,BlockData& bd):x(bd)/*,mem(20) */{ mod=m; smc=apm1=apm2=rcm=scm=mcm=cm=mx=mc=currentc=totalc=initdone=mindex=0; debug=0; @@ -539,7 +542,7 @@ void VM::expr(int lev){ else if (tk == Id) { d = id; next(); if (tk == '(') { - if (d[Val]>ABS && d[Val]ABS && d[Val]%x %.4s", cycle,pc-pc0, &"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LS ,LC ,SI ,SS ,SC ,PSH ," "OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,THIS," - "PRTF,ABS ,SMP ,SMN ,APM ,VMS ,VMI ,VMX ,MXP ,MXA ,MXS ,GCR ,BUF ,BUFR,MALC,MSET,MCMP,MCPY,STRE,SQUA,ILOG,H2 ,H3 ,H4 ,H5 ,EXIT,"[i * 5]); + "PRTF,ABS ,SMP ,SMN ,APM ,VMS ,VMI ,VMX ,MXP ,MXC ,MXA ,MXS ,GCR ,BUF ,BUFR,MALC,MSET,MCMP,MCPY,STRE,SQUA,ILOG,H2 ,H3 ,H4 ,H5 ,EXIT,"[i * 5]); if (i < JMP) kprintf(" %d\n",*pc); //? +1 else if (i <= ADJ) kprintf(" %x\n",(int *)*pc-pc0+1); else kprintf("\n"); - } - if (i == LEA) a = (int)(bp + *pc++); // load local address - else if (i == IMM) a = *pc++; // load global address or immediate + }*/ + if (i == LEA) a = (unsigned int)(bp + *pc++); // load local address + else if (i == IMM) a = (unsigned int)*pc++; // load global address or immediate else if (i == JMP) pc = (int *)*pc; // jump else if (i == JSR) { *--sp = (int)(pc + 1); pc = (int *)*pc; } // jump to subroutine else if (i == BZ) pc = a ? pc + 1 : (int *)*pc; // branch if zero @@ -811,36 +815,33 @@ int VM::dovm(int *ttt){ else if (i == ENT) { *--sp = (int)bp; bp = sp; sp = sp - *pc++; } // enter subroutine else if (i == ADJ) sp = sp + *pc++; // stack adjust else if (i == LEV) { sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; } // leave subroutine - else if (i == LI) a = *(int *)a; // load int - else if (i == LS) a = *(short *)a; // load short - else if (i == LC) a = *(char *)a; // load char - else if (i == SI) *(int *)*sp++ = a; // store int - else if (i == SC) a = *(char *)*sp++ = a; // store char - else if (i == SS) a = *(short *)*sp++ = a; // store short + else if (i == LI) a = *(unsigned int *)a; // load int + else if (i == LS) a = *(unsigned short *)a; // load short + else if (i == LC) a = *(unsigned char *)a; // load char + else if (i == SI) *(unsigned int *)*sp++ = (unsigned int)a; // store int + else if (i == SC) a = *(unsigned char *)*sp++ = (unsigned char)a; // store char + else if (i == SS) a = *(unsigned short *)*sp++ =(unsigned short) a; // store short else if (i == PSH) *--sp = a; // push - else if (i == OR) a = (unsigned int)*sp++ | a; - else if (i == XOR) a = (unsigned int)*sp++ ^ a; - else if (i == AND) a = (unsigned int)*sp++ & a; - else if (i == EQ) a = (unsigned int)*sp++ == a; - else if (i == NE) a = (unsigned int)*sp++ !=a; - else if (i == LT) a = (unsigned int)*sp++ < a; - else if (i == GT) a = (unsigned int)*sp++ > a; - else if (i == LE) a = (unsigned int)*sp++ <= a; - else if (i == GE) a = (unsigned int)*sp++ >= a; - else if (i == SHL) a = (unsigned int)*sp++ << a; - else if (i == SHR) a = (unsigned int)*sp++ >> a; - else if (i == ADD) a = (unsigned int)*sp++ + a; - else if (i == SUB) a = (unsigned int)*sp++ - a; - else if (i == MUL) a = (unsigned int)*sp++ * a; - else if (i == DIV) a = (unsigned int)*sp++ / a; - else if (i == MOD) a = (unsigned int)*sp++ % a; + else if (i == OR) a = (unsigned int)*sp++ | (unsigned int)a; + else if (i == XOR) a = (unsigned int)*sp++ ^ (unsigned int)a; + else if (i == AND) a = (unsigned int)*sp++ & (unsigned int)a; + else if (i == EQ) a = *sp++ == a; + else if (i == NE) a = *sp++ !=a; + else if (i == LT) a = *sp++ < a; + else if (i == GT) a = *sp++ > a; + else if (i == LE) a = *sp++ <= a; + else if (i == GE) a = *sp++ >= a; + else if (i == SHL) a = (unsigned int)*sp++ << (unsigned int)a; + else if (i == SHR) a = (unsigned int)*sp++ >> (unsigned int)a; + else if (i == ADD) a =*sp++ + a; + else if (i == SUB) a = *sp++ - a; + else if (i == MUL) a = *sp++ * a; + else if (i == DIV) a = *sp++ / a; + else if (i == MOD) a = *sp++ % a; - //else if (i == OPEN) a = fopen((char *)sp[1], *sp); - //else if (i == READ) a = fread( (char *)sp[1],sp[2],1, *sp); - //else if (i == CLOS) a = fclose(*sp); else if (i == PRTF) { t = sp + pc[1]; a = printf((char *)t[-1], t[-2], t[-3], t[-4], t[-5], t[-6]); } - else if (i == MALC) a = (int)vmmalloc(this,*sp); + else if (i == MALC) a = (int)vmmalloc(this,sp[1],*sp); else if (i == MSET) a = (int)memset((char *)sp[2], sp[1], *sp); else if (i == MCMP) a = memcmp((char *)sp[2], (char *)sp[1], *sp); else if (i == MCPY) a = (int)memcpy((char *)sp[2], (char *)sp[1], *sp); @@ -868,7 +869,7 @@ int VM::dovm(int *ttt){ else if (i == VTHIS) *--sp; //ignore else if (i == EXIT) { /*printf("exit(%d) cycle = %d\n", *sp, cycle);*/ return *sp; } else { kprintf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1; } - if (debug) printf("a=%d ",a); + // if (debug) printf("a=%d ",a); } } @@ -885,13 +886,15 @@ int VM::dojit(){ pc = text + 1; je = jitmem; line = 0; while (pc <= e) { i = *pc; - /* kprintf("// %x: ",pc); - kprintf(" %.4s", + //if (debug) { + //dprintf("// %x: ",pc); + dprintf(" %.4s", &"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LS ,LC ,SI ,SS ,SC ,PSH ," "OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,THIS," - "PRTF,ABS ,SMP ,SMN ,APM ,VMS ,VMI ,VMX ,MXP ,MXA ,MXS ,GCR ,BUF ,BUFR,MALC,MSET,MCMP,MCPY,STRE,SQUA,ILOG,H2 ,H3 ,H4 ,H5 ,EXIT,"[i * 5]); - if (i < JMP) kprintf(" %d\n",*(pc+1)); //? +1 - else if (i <= ADJ) kprintf(" %x\n",(int *)*pc); else kprintf("\n");*/ + "PRTF,ABS ,SMP ,SMN ,APM ,VMS ,VMI ,VMX ,MXP ,MXC ,MXA ,MXS ,GCR ,BUF ,BUFR,MALC,MSET,MCMP,MCPY,STRE,SQUA,ILOG,H2 ,H3 ,H4 ,H5 ,EXIT,"[i * 5]); + if (i < JMP) dprintf(" 0x%x\n",*(pc+1)); //? +1 + else if (i <= ADJ) dprintf(" 0x%x\n",(int *)*pc); else dprintf("\n"); + // } *pc++ = ((int)je << 8) | i; // for later relocation of JMP/JSR/BZ/BNZ if (i == LEA) { @@ -906,10 +909,58 @@ int VM::dojit(){ dprintf("\tpush ebp\n\tmov ebp, esp\n",i); if (i > 0) { *(int *)je = 0xec83; je = je + 2; *(int*)je++ = i; dprintf("\tsub esp,BYTE %x\n",i); *(int *)je++ = 0x56;dprintf("\tpush esi\n"); } } - else if (i == IMM) { *je++ = 0xb8; *(int *)je = i=*pc++; je = je + 4; dprintf("\tmov eax,DWORD %x\n",i);} + else if (i == IMM) { + if (*(pc+1)==LI){ + dprintf("// %x: LI\n",pc); + *je++ = 0xa1; *(int *)je = i=*pc++; je = je + 4; dprintf("\tmov eax,DWORD [0x%x]\n",i); + i = *pc;*pc++ = ((int)je << 8) | i; + } + else { + *je++ = 0xb8; *(int *)je = i=*pc++; je = je + 4; dprintf("\tmov eax,DWORD 0x%x\n",i);} + } else if (i == ADJ) { i = 4 * *pc++; *(int *)je = 0xc483; je = je + 2; *(int *)je = i; je++; } // add esp,BYTE (n * 4) - else if (i == PSH) { *(int *)je++ = 0x50;dprintf("\tpush eax\n"); } + else if (i == PSH && *(pc)==IMM && *(pc+1)==4 && *(pc+2)==MUL && *(pc+3)==ADD){ //array index*int + *(int*)je = 0x59 ;je = je + 1; //pop ecx + dprintf(" IMM 0x4\n"); + dprintf(" MUL\n"); + dprintf(" ADD\n"); + dprintf("\tpop ecx\n"); + dprintf("\tlea eax,[ecx+eax*4]\n"); + i = *pc;//IMM + *pc++ = ((int)je << 8) | i; *pc++; + i = *pc;//mul + *pc++ = ((int)je << 8) | i; + i = *pc;//add + *pc++ = ((int)je << 8) | i; + *(int *)je = 0x81048d; je = je + 3; // lea eax,[ecx+eax*4] + } + else if (i == PSH) { *(int *)je++ = 0x50;dprintf("\tpush eax\n"); } else if (i == LEV) { *(int *)je++ = 0x5e;dprintf("\tpop esi\n"); *(int *)je = 0xc35dec89; je = je + 4; dprintf("\tmov esp, ebp\n\tpop ebp\n\tret\n"); } + else if ((i == LI ||i == LC ||i == LS )&& *(pc)==PSH && *(pc+1)==IMM && + (*(pc+3)==SHR || *(pc+3)==SHL || *(pc+3)==SUB|| *(pc+3)==ADD|| + (*(pc+3)==MUL && *(pc+4)!=ADD) || + *(pc+3)==OR || *(pc+3)==XOR || *(pc+3)==AND )){ + + if (i == LI )*(int *)je = 0x008b, je = je + 2; //LI + else if (i == LC )*(int *)je = 0x00b60f, je = je + 3; //LC + else if (i == LS )*(int *)je = 0x00B70F, je = je + 3; //LS + i = *pc;//PSH + *pc++ = ((int)je << 8) | i; + i = *pc;//IMM + *pc++ = ((int)je << 8) | i; + *je++ = 0xb9; *(int *)je = i=*pc++; je = je + 4; + dprintf(" PSH\n"); + dprintf(" IMM 0x%x\n",i); + dprintf(" XXX\n"); + dprintf("\tmov eax,DWORD PTR [eax]\n"); + dprintf("\tmov ecx,DWORD 0x%x\n",i); + i = *pc;//XXX + *pc++ = ((int)je << 8) | i; + + *(int*)je = i==SHR?0xe8d3:i==SHL?0xe0d3:i==SUB?0xc829:i==ADD?0xc801:i==MUL?0xc1af0f:i==OR?0xc809:i==XOR?0xc831:0xc821; + je = je + 2;dprintf("\tXXX ;optimized\n"); + if (i==MUL) je=je+1; + } else if (i == LI) { *(int *)je = 0x008b; je = je + 2; dprintf("\tmov eax,DWORD PTR [eax]\n");} else if (i == LC) { *(int *)je = 0x00b60f; je = je + 3; dprintf("\tmovzx eax,BYTE PTR [eax]\n"); } else if (i == LS) { *(int *)je = 0x00B70F; je = je + 3; dprintf("\tmovzx eax,WORD PTR [eax]\n"); } @@ -920,24 +971,23 @@ int VM::dojit(){ else if (i == XOR) { *(int *)je = 0xc83159; je = je + 3; dprintf("\tpop ecx\n\txor eax, ecx\n"); } else if (i == AND) { *(int *)je = 0xc82159; je = je + 3; dprintf("\tpop ecx\n\tand eax, ecx\n"); } else if (EQ <= i && i <= GE) { - *(int*)je=0x0fc13959; je+=4; *(int*)je=0xB60Fc094; - dprintf("\tpop ecx\n\tcmp ecx, eax"); + *(int*)je=0x0fc13959; je+=4; *(int*)je=0x9866c094; dprintf("\tpop ecx\n\tcmp ecx, eax"); if (i == NE) { *je = 0x95; dprintf("\n\tsetne al");} // setne al - else if (i == LT) { *je = 0x92; dprintf("\n\tsetb al");} // setb al - else if (i == GT) { *je = 0x97; dprintf("\n\tseta al");} // seta al - else if (i == LE) { *je = 0x96; dprintf("\n\tsetbe al");} // setbe al - else if (i == GE) { *je = 0x93; dprintf("\n\tsetae al");} // setae al + else if (i == LT) { *je = 0x9c; dprintf("\n\tsetb al");} // setb al + else if (i == GT) { *je = 0x9f; dprintf("\n\tseta al");} // seta al + else if (i == LE) { *je = 0x9e; dprintf("\n\tsetbe al");} // setbe al + else if (i == GE) { *je = 0x9d; dprintf("\n\tsetae al");} // setae al else dprintf("\n\tsete al"); - dprintf("\n\tmovzx eax,al\n"); - je+=4; *je++=0xC0; + dprintf("\n\tcwde\n"); + je+=4; *je++=0x98; } else if (i == SHL) { *(int*)je = 0xe0d39159; je = je + 4;dprintf("\tpop ecx\n\txchg ecx, eax\n\tshl eax, cl\n"); } // pop ecx; xchg ecx, eax; shl eax, cl else if (i == SHR) { *(int*)je = 0xe8d39159; je = je + 4;dprintf("\tpop ecx\n\txchg ecx, eax\n\tshr eax, cl\n"); } // pop ecx; xchg ecx, eax; shr eax, cl else if (i == ADD) { *(int*)je = 0xc80159; je = je + 3;dprintf("\tpop ecx\n\tadd eax, ecx\n"); } // pop ecx; add eax, ecx else if (i == SUB) { *(int*)je = 0xc8299159; je = je + 4;dprintf("\tpop ecx\n\txchg ecx, eax\n\tsub eax, ecx\n"); } // pop ecx; xchg ecx,eax; sub eax,ecx else if (i == MUL) { *(int*)je = 0xc1af0f59; je = je + 4;dprintf("\tpop ecx\n\txchg ecx, eax\n\t imul eax, ecx\n"); } // pop ecx; imul eax,ecx - else if (i == DIV) {*je = 0x31; je = je + 1;*je = 0xd2; je = je + 1; *(int*)je = 0xf1f79159; je = je + 4;dprintf("\tpop ecx\n\txchg ecx, eax\n\tdiv eax, ecx\n"); } // pop ecx; xchg ecx,eax; idiv eax,ecx - else if (i == MOD) { *(int*)je = 0xd2319159; je += 4; *(int *)je = 0x92f1f7; je += 3; dprintf("\txor edx,edx\n\tpop ecx\n\txchg ecx,eax\n\tdiv ecx\n\txchg edx,eax" ); } + else if (i == DIV) { *je++=0x59; *(int*)je = 0xF9F79991; je = je + 4;dprintf("\txor edx,edx\tpop ecx\n\txchg ecx, eax\n\tdiv eax, ecx\n"); } // pop ecx; xchg ecx,eax; idiv eax,ecx + else if (i == MOD) { *(int*)je = 0x999159; je += 3; *(int *)je = 0x92f9f7; je += 3; dprintf("\txor edx,edx\n\tpop ecx\n\txchg ecx,eax\n\tdiv ecx\n\txchg edx,eax" ); } else if (i == JMP) { ++pc; *je = 0xe9; je = je + 5; dprintf("\tjmp %x\n", *(pc-1) ); } // jmp else if (i == JSR) { ++pc; *je = 0xe8; je = je + 5; dprintf("\tcall %x\n", *(pc-1) ); } // call else if (i == BZ) { ++pc; *(int*)je = 0x840fc085; je = je + 8;dprintf("\ttest eax, eax\n\tjz %x\n", *(pc-1) ); } // test %eax, %eax; jz @@ -946,56 +996,61 @@ int VM::dojit(){ *je++ = 0xb8; *(int*)je =i=(unsigned int)(size_t(this));je += 4; *(int *)je++ = 0x50;dprintf("\tmov eax,DWORD %x\n\tpush eax ;this\n",i); } //mov ecx,this b9 else if (i >= PRTF) { - /* if (i == OPEN) { tmp = (int)open; dprintf("\topen\n"); } else if (i == READ) { tmp = (int)read;dprintf("\tread\n"); } - else if (i == CLOS) { tmp = (int)close;dprintf("\tclose\n"); } else + /* if (i == OPEN) { tmp = (int)open; dprintf("\topen\n"); } else if (i == READ) { tmp = (int)read;dprintf("\tread\n"); } + else if (i == CLOS) { tmp = (int)close;dprintf("\tclose\n"); } else */ - if (i == PRTF) { tmp = (int)printf; } - else if (i == MALC) { tmp = (int)vmmalloc; } //else if (i == MSET) { tmp = (int)memset; } - else if (i == SMP) { tmp = (int)smp; } else if (i == SMN) { tmp = (int)smn; } - else if (i == MCMP) { tmp = (int)memcmp; } else if (i == MCPY) { tmp = (int)memcpy; } - else if (i == EXIT) { tmp = (int)exit; }else if (i == APM) { tmp = (int)ap; } - else if (i == VMS) { tmp = (int)components; }else if (i == VMI) { tmp = (int)initcomponent; } - else if (i == VMX) { tmp = (int)setcomponent; }else if (i == MXP) { tmp = (int)mxp; } - else if (i == STRE) { tmp = (int)stre; }else if (i == SQUA) { tmp = (int)squa; } - else if (i == BUF) { tmp = (int)bf; }else if (i == BUFR) { tmp = (int)bfr; } - else if (i == ILOG) { tmp = (int)il; }else if (i == MXC) { tmp = (int)mxc; } - else if (i == MXA) { tmp = (int)mxa; }else if (i == MXS) { tmp = (int)mxs; } - else if (i == GCR) { tmp = (int)gcr; }else if (i == ABS) { tmp = (int)absolute; } - else if (i == H2) { tmp = (int)h2; }else if (i == H3) { tmp = (int)h3; }else if (i == H4) { tmp = (int)h4; } - else if (i == H5) { tmp = (int)h5; } - u=i; - if (*pc++ == ADJ) { i = *pc++; } else { kprintf("no ADJ after native proc!\n"); exit(2); } - *je++ = 0xb9; *(int*)je = i << 2; je += 4; dprintf("\tmov ecx, %x\n", i << 2 ); // movl $(4 * n), %ecx; - *(int*)je = 0xce29e689; je += 4; dprintf("\tmov esi,esp\n\tsub esi,ecx\n"); // mov %esp, %esi; sub %ecx, %esi; -- %esi will adjust the stack - *(int*)je = 0x8302e9c1; je += 4; dprintf("\tshr ecx,2\n");// shr $2, %ecx; and -- alignment of %esp for OS X - *(int*)je = 0x895af0e6; je += 4; // $0xfffffff0, %esi; pop %edx; mov.. - *(int*)je = 0xe2fc8e54; je += 4; // ..%edx, -4(%esi,%ecx,4); loop.. -- reversing args order - - *(int*)je = 0xe8f487f9; je += 4; // ..<'pop' offset>; xchg %esi, %esp; call -- saving old stack in %esi - dprintf("\tand esi,0xfffffff0\n"); - dprintf("\tpop edx\n\tmov DWORD PTR [esi+ecx*4-0x4],edx\n"); - dprintf("\tloop 0x00000006\n\tcall "); - if (u == PRTF) { dprintf("printf\n"); } - else if (u == MALC) { dprintf("malloc\n"); }// else if (u == MSET) { dprintf("memset\n"); } - else if (u == MCMP) { dprintf("memcmp\n"); } else if (u == MCPY) { dprintf("memcpy\n"); } - else if (u == EXIT) { dprintf("exit\n"); }else if (u == SMP) { dprintf("smp\n"); } - else if (u == SMN) { dprintf("smn\n"); }else if (u == APM) { dprintf("apm\n"); } - else if (u == VMS) { dprintf("vms\n"); }else if (u == VMI) { dprintf("vmi\n"); } - else if (u == VMX) { dprintf("vmx\n"); }else if (u == MXP) { dprintf("mxp\n"); } - else if (u == STRE) { dprintf("stretch\n"); }else if (u == SQUA) { dprintf("squash\n"); } - else if (u == BUF) { dprintf("buf\n"); } else if (u == BUFR) { dprintf("bufr\n"); } - else if (u == ILOG) { dprintf("ilog\n"); } - else if (u == MXA) { dprintf("mxa\n"); } else if (u == MXS) { dprintf("mxs\n"); } - else if (u == MXC) { dprintf("mxc\n"); } else if (u == GCR) { dprintf("gcr\n"); } - else if (u == H2) { dprintf("h1\n"); } else if (u == H3) { dprintf("h2\n"); } - else if (u == H4) { dprintf("h3\n"); } else if (u == ABS) { dprintf("abs\n"); } - else if (u == H5) { dprintf("h3\n"); } - *(int*)je = tmp - (int)(je + 4); je = je + 4; // <*tmp offset>; - *(int*)je = 0xf487; je += 2; // xchg %esi, %esp -- ADJ, back to old stack without arguments - dprintf("\txchg esp,esi\n"); + if (i == PRTF) { tmp = (int)printf; } + else if (i == MALC) { tmp = (int)vmmalloc; } //else if (i == MSET) { tmp = (int)memset; } + else if (i == SMP) { tmp = (int)smp; } else if (i == SMN) { tmp = (int)smn; } + else if (i == MCMP) { tmp = (int)memcmp; } else if (i == MCPY) { tmp = (int)memcpy; } + else if (i == EXIT) { tmp = (int)exit; }else if (i == APM) { tmp = (int)ap; } + else if (i == VMS) { tmp = (int)components; }else if (i == VMI) { tmp = (int)initcomponent; } + else if (i == VMX) { tmp = (int)setcomponent; }else if (i == MXP) { tmp = (int)mxp; } + else if (i == STRE) { tmp = (int)stre; }else if (i == SQUA) { tmp = (int)squa; } + else if (i == BUF) { tmp = (int)bf; }else if (i == BUFR) { tmp = (int)bfr; } + else if (i == ILOG) { tmp = (int)il; }else if (i == MXC) { tmp = (int)mxc; } + else if (i == MXA) { tmp = (int)mxa; }else if (i == MXS) { tmp = (int)mxs; } + else if (i == GCR) { tmp = (int)gcr; }else if (i == ABS) { tmp = (int)absolute; } + else if (i == H2) { tmp = (int)h2; }else if (i == H3) { tmp = (int)h3; }else if (i == H4) { tmp = (int)h4; } + else if (i == H5) { tmp = (int)h5; } + u=i; + if (*pc++ == ADJ) { i = *pc++; } else { kprintf("no ADJ after native proc!\n"); exit(2); } + *je++ = 0xb9; *(int*)je = i << 2; je += 4; dprintf("\tmov ecx, 0x%x\n", i << 2 ); // movl $(4 * n), %ecx; + *(int*)je = 0xce29e689; je += 4; dprintf("\tmov esi,esp\n\tsub esi,ecx\n"); // mov %esp, %esi; sub %ecx, %esi; -- %esi will adjust the stack + *(int*)je = 0x8302e9c1; je += 4; dprintf("\tshr ecx,2\n");// shr $2, %ecx; and -- alignment of %esp for OS X + *(int*)je = 0x895af0e6; je += 4; // $0xfffffff0, %esi; pop %edx; mov.. + *(int*)je = 0xe2fc8e54; je += 4; // ..%edx, -4(%esi,%ecx,4); loop.. -- reversing args order + + *(int*)je = 0xe8f487f9; je += 4; // ..<'pop' offset>; xchg %esi, %esp; call -- saving old stack in %esi + dprintf("\tand esi,0xfffffff0\n"); + dprintf("\tpop edx\n\tmov DWORD PTR [esi+ecx*4-0x4],edx\n"); + dprintf("\tloop 0x00000006\n\tcall "); + if (u == PRTF) { dprintf("printf"); } + else if (u == MALC) { dprintf("malloc"); }// else if (u == MSET) { dprintf("memset\n"); } + else if (u == MCMP) { dprintf("memcmp"); } else if (u == MCPY) { dprintf("memcpy"); } + else if (u == EXIT) { dprintf("exit"); }else if (u == SMP) { dprintf("smp"); } + else if (u == SMN) { dprintf("smn"); }else if (u == APM) { dprintf("apm"); } + else if (u == VMS) { dprintf("vms"); }else if (u == VMI) { dprintf("vmi"); } + else if (u == VMX) { dprintf("vmx"); }else if (u == MXP) { dprintf("mxp"); } + else if (u == STRE) { dprintf("stretch"); }else if (u == SQUA) { dprintf("squash"); } + else if (u == BUF) { dprintf("buf"); } else if (u == BUFR) { dprintf("bufr"); } + else if (u == ILOG) { dprintf("ilog"); } + else if (u == MXA) { dprintf("mxa"); } else if (u == MXS) { dprintf("mxs"); } + else if (u == MXC) { dprintf("mxc"); } else if (u == GCR) { dprintf("gcr"); } + else if (u == H2) { dprintf("h2"); } else if (u == H3) { dprintf("h3"); } + else if (u == H4) { dprintf("h4"); } else if (u == ABS) { dprintf("abs"); } + else if (u == H5) { dprintf("h5"); } + + *(int*)je = tmp - (int)(je + 4); je = je + 4; // <*tmp offset>; + dprintf(" // %x\n", *(int*)(je-4) ); //print running memory address + dprintf("// %x: ",pc-2); dprintf("ADJ 0x%x\n",i<<2); + *(int*)je = 0xf487; je += 2; // xchg %esi, %esp -- ADJ, back to old stack without arguments + dprintf("\txchg esp,esi\n"); } else { kprintf("code generation failed for %d!\n", i); return -1; } } + dprintf(" Code size %d \n",je -jitmem); + // second pass, relocation pc = text + 1; while (pc <= e) { @@ -1007,11 +1062,29 @@ int VM::dojit(){ else if (i == BZ || i == BNZ) { je += 4; *(int*)je = tmp - (int)(je + 4); } } else if (i < LEV) { ++pc; } + else if (i>EXIT) {kprintf("code generation failed. relocation error\n", i); return -1; } } return 0; } #endif +int VM::detect(int c4,int pos){ +#ifdef VMJIT + int (*jitmain)(int,int); // c4 vm pushes first argument first, unlike cdecl + jitmain = reinterpret_cast< int(*)( int,int) >(*(unsigned*)( iddetect[Val]) >> 8 | ((unsigned)jitmem & 0xff000000)); + return jitmain(pos,c4); +#else + // setup stack + data =data0; + bp=sp = (int *)((int)sp0 + poolsz); + *--sp = EXIT; // call exit if main returns + *--sp = PSH; t = sp; + *--sp = c4; + *--sp = pos; + *--sp = (int)t; + return dovm((int *)iddetect[Val]); +#endif +} int VM::block(int info1,int info2){ #ifdef VMJIT int (*jitmain)(int,int); // c4 vm pushes first argument first, unlike cdecl @@ -1065,13 +1138,16 @@ int VM::initvm() { memset(e, 0, poolsz); memset(data, 0, poolsz); - p = "char else enum if int short return for sizeof while printf abs smp smn apm vms vmi vmx mxp mxc mxa mxs gcr buf bufr malloc memset memcmp memcpy stretch squash ilog h2 h3 h4 h5 exit void block update main"; + p = "char else enum if int short return for sizeof while printf abs smp smn apm vms vmi vmx mxp mxc mxa mxs gcr buf bufr malloc memset memcmp memcpy stretch squash ilog h2 h3 h4 h5 exit void block update main detect decode encode"; i = Char; while (i <= While) { next(); id[Tk] = i++; } // add keywords to symbol table i = PRTF; while (i <= EXIT) { next(); id[Class] = Sys; id[Type] = iINT; id[Val] = i++; } // add library to symbol table next(); id[Tk] = Char; // handle void type next(); idp = id; // keep track of block next(); idupdate = id; // keep track of updater next(); idmain = id; // keep track of main + next(); iddetect = id; + next(); iddecode = id; + next(); idencode = id; p=mod; //contains model // parse declarations line = 1;