Fixed 36-bit multiplication results in cases of overflow

This commit is contained in:
Jeff 2017-04-01 15:14:27 -07:00 committed by Jeff Parsons
commit 1a8c1306d4
4 changed files with 19 additions and 6 deletions

View file

@ -7,7 +7,7 @@ machines:
type: pdp10
config: /devices/pdp10/machine/ka10/test/debugger/machine.xml
debugger: true
commands: a dakal.mac; g 31134
commands: a dakal.mac; g 33726
---
PDP-10 KA10 Basic Instruction Diagnostic #12
@ -192,6 +192,10 @@ Here's that output:
MUL(252525252525,004000000000) PDP-10: 124000000000 JavaScript: 524000000000 @032765
MUL(252525252525,020000000000) PDP-10: 120000000000 JavaScript: 520000000000 @033013
MUL(252525252525,100000000000) PDP-10: 100000000000 JavaScript: 500000000000 @033041
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(777777777776,777777777776) PDP-10: 000000000004 JavaScript: 000000000000 @033726
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033726
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033726

View file

@ -6531,12 +6531,21 @@ PDP10.split72 = function(res, ext, fExternal)
var sign = ext - (ext % PDP10.INT_LIMIT);
ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT);
res = sign + (res % PDP10.INT_LIMIT);
if (fExternal) return res;
var signNew = ext - (ext % PDP10.INT_LIMIT);
if (sign != signNew) {
ext = sign + (ext - signNew);
this.regPS |= PDP10.PSFLAG.AROV;
/*
* I used to restore ext's original sign (ext = sign + (ext - signNew)), but the PDP-10's defined
* behavior for multiplication overflow (ie, whenever both operands are 0o400000000000) is to set both
* res and ext to 0o400000000000.
*
* To quote the original spec for the MUL instruction:
*
* If both operands are -2^35 set Overflow; the double length result stored is -2^70.
*/
res = ext;
if (!fExternal) this.regPS |= PDP10.PSFLAG.AROV;
}
if (fExternal) return res;
this.regEX = res;
return ext;
};

View file

@ -111,7 +111,7 @@ function ie(a,b){var c=this.f(this.b),d=c;if(a&=384)switch(d&=x,a){case 256:d+=x
function oe(){}function pe(){}function L(a){this.u("undefined opcode: "+va(a));sd(this,-1);this.Y()}function qe(a){a>z&&(a!=B?a=Xb-a:this.j|=163840);return a}function Q(a,b){var c=(a+b)%D;re.call(this,a,b,c);return c}
function se(a,b,c){var d=!1,e=!1,f=b-b%B;a=a%B+b*B%D;b=this.F=f+Math.trunc(b/2);c>z&&(c=D-c,d=!d);b>z&&(a?(b=C-b,a=D-a):b&&(b=D-b),e=!0,d=!d);if(b>=c)return this.j|=131104,-1;f=this.kb;f[0]=0;f[1]=0;f=this.wa;f[0]=1;f[1]=0;f=this.oa;f[0]=c;f[1]=0;c=this.xa;c[0]=a;for(c[1]=b;0<te(this.xa,this.oa);)ue(this.oa,this.oa),ue(this.wa,this.wa);do{if(0<=te(this.xa,this.oa)&&(b=this.xa,a=this.oa,b[0]-=a[0],b[1]-=a[1],0>b[0]&&(b[0]+=D,b[1]--),ue(this.kb,this.wa),ve(this.xa)))break;we(this.oa);we(this.wa)}while(!ve(this.wa));
a=this.kb[0];this.F=this.xa[0];d&&a&&(a=D-a);e&&this.F&&(this.F=D-this.F);return a}
function xe(a,b,c,d){var e=a,f=b;b=!1;var g;e>z&&(d||1001!=this.nb||e!=B)&&(e=D-e,b=!b);f>z&&(f=D-f,b=!b);if(e<y&&f<y)a=e*f,g=0;else{a=e&x;e=Math.trunc(e/y);g=f&x;var f=Math.trunc(f/y),h=a*g,k=e*g+Math.trunc(h/y);g=Math.trunc(k/y);k=(k&x)+a*f;a=(k*y+(h&x))%D;g+=Math.trunc(k/y)+e*f}b&&(a?(g=C-g,a=D-a):g&&(g=D-g));if(c)return!d&&(g||a>z)&&(g!=C||a<=z)&&(this.j|=131072),a;c=a;b=g;a=b-b%B;b=2*b%D+Math.trunc(c/B);c=a+c%B;d?d=c:(d=b-b%B,a!=d&&(b=a+(b-d),this.j|=131072),this.F=c,d=b);return d}
function xe(a,b,c,d){var e=a,f=b;b=!1;var g;e>z&&(d||1001!=this.nb||e!=B)&&(e=D-e,b=!b);f>z&&(f=D-f,b=!b);if(e<y&&f<y)a=e*f,g=0;else{a=e&x;e=Math.trunc(e/y);g=f&x;var f=Math.trunc(f/y),h=a*g,k=e*g+Math.trunc(h/y);g=Math.trunc(k/y);k=(k&x)+a*f;a=(k*y+(h&x))%D;g+=Math.trunc(k/y)+e*f}b&&(a?(g=C-g,a=D-a):g&&(g=D-g));if(c)return!d&&(g||a>z)&&(g!=C||a<=z)&&(this.j|=131072),a;c=a;b=g;a=b-b%B;b=2*b%D+Math.trunc(c/B);c=a+c%B;a!=b-b%B&&(c=b,d||(this.j|=131072));d?d=c:(this.F=c,d=b);return d}
function ye(a){a?a==B?this.j|=163840:a=Xb-a:this.j|=98304;return a}function ze(a,b){var c=a-b;0>c&&(c+=D);re.call(this,c,b,a);return c}function re(a,b,c){a=Math.trunc(a/Wb);b=Math.trunc(b/Wb);c=Math.trunc(c/Wb);var d=a^(a^b)&(b^c);this.j=this.j|(d&2?65536:0)|(d&1?32768:0)|((a^c)&(b^c)&2?131072:0)}function R(a,b){return((a/E|0)&(b/E|0))*E+((a&b)>>>0)}function S(a,b){return R(a,(~(b/E|0)&15)*E+(~b>>>0))}function T(a,b){return(a<B?a:a-D)-(b<B?b:b-D)}
function Ae(a,b){return(~((a/E|0)^(b/E|0))&15)*E+(~(a^b)>>>0)}function U(a,b){return(a/E|0|b/E|0)*E+((a|b)>>>0)}function V(a){return a<B?a:a-D}function W(a,b){return((a/E|0)^(b/E|0))*E+((a^b)>>>0)}function X(a){return(a/y|0)+(a&x)*y}function fe(a,b,c){switch(a&384){case 0:b-=b&x;break;case 128:b=0;break;case 256:b=x*y;break;case 384:b=c>Ub?x*y:0}return b}function Gd(a,b,c){switch(a&384){case 0:b&=x;break;case 128:b=0;break;case 256:b=x;break;case 384:b=c>z?x:0}return b}
function ue(a,b){a[0]+=b[0];a[1]+=b[1];a[0]>=D&&(a[0]%=D,a[1]++)}function te(a,b){var c=a[1]-b[1];c||(c=a[0]-b[0]);return c}function we(a){a[1]%2&&(a[0]+=D);a[0]=Math.trunc(a[0]/2);a[1]=Math.trunc(a[1]/2)}function ve(a){return!a[0]&&!a[1]}

View file

@ -103,7 +103,7 @@ function Dc(a,b){var c=this.b(this.a)&C,d=this.b(b);this.c(b,Ec(a,d,c)+c)}functi
function Kc(a,b){b=this.b(b)/E|0;var c=this.b(this.a);this.c(this.a,Ec(a,c,b)+b)}function Lc(a,b){var c=this.b(this.a),d=c/E|0,c=Ec(a,c,d)+d;this.c(this.a,c);b&&this.c(b,c)}function Q(a){Mc[a&7].call(this,a,a>>3&127)}function Nc(){}function Oc(){}function O(a){this.M("undefined opcode: "+ka(a));this.f=(this.f+-1)%$a;N(this)}function Pc(a){a>F&&(a!=G?a=db-a:this.g|=163840);return a}function R(a,b){var c=(a+b)%J;Qc.call(this,a,b,c);return c}
function S(a,b,c){var d=!1,e=!1,f=b-b%G;a=a%G+b*G%J;b=this.o=f+Math.trunc(b/2);c>F&&(c=J-c,d=!d);b>F&&(a?(b=I-b,a=J-a):b&&(b=J-b),e=!0,d=!d);if(b>=c)return this.g|=131104,-1;f=this.Na;f[0]=0;f[1]=0;f=this.da;f[0]=1;f[1]=0;f=this.X;f[0]=c;f[1]=0;c=this.ea;c[0]=a;for(c[1]=b;0<Rc(this.ea,this.X);)Sc(this.X,this.X),Sc(this.da,this.da);do{if(0<=Rc(this.ea,this.X)&&(b=this.ea,a=this.X,b[0]-=a[0],b[1]-=a[1],0>b[0]&&(b[0]+=J,b[1]--),Sc(this.Na,this.da),Tc(this.ea)))break;Uc(this.X);Uc(this.da)}while(!Tc(this.da));
a=this.Na[0];this.o=this.ea[0];d&&a&&(a=J-a);e&&this.o&&(this.o=J-this.o);return a}
function Vc(a,b,c,d){var e=a,f=b;b=!1;var g;e>F&&(d||1001!=this.Wa||e!=G)&&(e=J-e,b=!b);f>F&&(f=J-f,b=!b);if(e<E&&f<E)a=e*f,g=0;else{a=e&C;e=Math.trunc(e/E);g=f&C;var f=Math.trunc(f/E),h=a*g,m=e*g+Math.trunc(h/E);g=Math.trunc(m/E);m=(m&C)+a*f;a=(m*E+(h&C))%J;g+=Math.trunc(m/E)+e*f}b&&(a?(g=I-g,a=J-a):g&&(g=J-g));if(c)return!d&&(g||a>F)&&(g!=I||a<=F)&&(this.g|=131072),a;c=a;b=g;a=b-b%G;b=2*b%J+Math.trunc(c/G);c=a+c%G;d?d=c:(d=b-b%G,a!=d&&(b=a+(b-d),this.g|=131072),this.o=c,d=b);return d}
function Vc(a,b,c,d){var e=a,f=b;b=!1;var g;e>F&&(d||1001!=this.Wa||e!=G)&&(e=J-e,b=!b);f>F&&(f=J-f,b=!b);if(e<E&&f<E)a=e*f,g=0;else{a=e&C;e=Math.trunc(e/E);g=f&C;var f=Math.trunc(f/E),h=a*g,m=e*g+Math.trunc(h/E);g=Math.trunc(m/E);m=(m&C)+a*f;a=(m*E+(h&C))%J;g+=Math.trunc(m/E)+e*f}b&&(a?(g=I-g,a=J-a):g&&(g=J-g));if(c)return!d&&(g||a>F)&&(g!=I||a<=F)&&(this.g|=131072),a;c=a;b=g;a=b-b%G;b=2*b%J+Math.trunc(c/G);c=a+c%G;a!=b-b%G&&(c=b,d||(this.g|=131072));d?d=c:(this.o=c,d=b);return d}
function Wc(a){a?a==G?this.g|=163840:a=db-a:this.g|=98304;return a}function Xc(a,b){var c=a-b;0>c&&(c+=J);Qc.call(this,c,b,a);return c}function Qc(a,b,c){a=Math.trunc(a/cb);b=Math.trunc(b/cb);c=Math.trunc(c/cb);var d=a^(a^b)&(b^c);this.g=this.g|(d&2?65536:0)|(d&1?32768:0)|((a^c)&(b^c)&2?131072:0)}function T(a,b){return((a/K|0)&(b/K|0))*K+((a&b)>>>0)}function U(a,b){return T(a,(~(b/K|0)&15)*K+(~b>>>0))}function V(a,b){return(a<G?a:a-J)-(b<G?b:b-J)}
function Yc(a,b){return(~((a/K|0)^(b/K|0))&15)*K+(~(a^b)>>>0)}function W(a,b){return(a/K|0|b/K|0)*K+((a|b)>>>0)}function X(a){return a<G?a:a-J}function Y(a,b){return((a/K|0)^(b/K|0))*K+((a^b)>>>0)}function Z(a){return(a/E|0)+(a&C)*E}function Ec(a,b,c){switch(a&384){case 0:b-=b&C;break;case 128:b=0;break;case 256:b=C*E;break;case 384:b=c>ab?C*E:0}return b}function vc(a,b,c){switch(a&384){case 0:b&=C;break;case 128:b=0;break;case 256:b=C;break;case 384:b=c>F?C:0}return b}
function Sc(a,b){a[0]+=b[0];a[1]+=b[1];a[0]>=J&&(a[0]%=J,a[1]++)}function Rc(a,b){var c=a[1]-b[1];c||(c=a[0]-b[0]);return c}function Uc(a){a[1]%2&&(a[0]+=J);a[0]=Math.trunc(a[0]/2);a[1]=Math.trunc(a[1]/2)}function Tc(a){return!a[0]&&!a[1]}