Home » Archimedes archive » Zipped Apps » BCPL » BCPL/b/cgi

BCPL/b/cgi

This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.

Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.

Tape/disk: Home » Archimedes archive » Zipped Apps » BCPL
Filename: BCPL/b/cgi
Read OK:
File size: 299D bytes
Load address: 0000
Exec address: 0000
File contents
SECTION "CGI"

GET "b.CGheader"

STATIC {
 /* Version of 11 Sep 87 13:41:44
 */
   dummy = VersionMark;
   version = 1*256+7 };

STATIC {
   deferredShift = 0;
   secondOp = 0;
   secondMultiplier = 0;
   thirdMultiplier = 0;
   registerForMultiply = 0 }

LET LowBit(n) = n & (-n)

AND DivByPowerOf2Minus1(n) = VALOF
{  LET t = TABLE	 #x7fffff, #x3fffff, #x1fffff,
		#xfffff,  #x7ffff,  #x3ffff,  #x1ffff,
		 #xffff,   #x7fff,   #x3fff,   #x1fff,
		  #xfff,    #x7ff,    #x3ff,	#x1ff,
		   #xff,     #x7f,     #x3f,	 #x1f,
		    #xf,      #x7,	#x3,	    0;
   LET i = 0;
   LET x = ?;
   {  x := t!i;
      IF x=0 THEN RESULTIS Null;
      IF (n REM x)=0 THEN RESULTIS x
      i := i+1
   } REPEAT
}

AND DivByPowerOf2Plus1(n) = VALOF
{  LET t = TABLE	 #x400001, #x200001, #x100001,
		#x80001,  #x40001,  #x20001,  #x10001,
		 #x8001,   #x4001,   #x2001,   #x1001,
		  #x801,    #x401,    #x201,	#x101,
		   #x81,     #x41,     #x21,	 #x11,
		    #x9,      #x5,	  0;
   LET i = 0;
   LET x = ?
   {  x := t!i;
      IF x=0 THEN RESULTIS Null;
      IF (n REM x)=0 THEN RESULTIS x
      i := i+1
   } REPEAT
}

AND IsPowerOf2(n) = n>0 & LowBit(n)=n

AND IsSimpleMultiply(k) = IsPowerOf2(k) |
			  IsPowerOf2(k+1) |
			  IsPowerOf2(k-1)

AND FindSourceAndDestinationRegisters(lvs, x, mustBeDistinct) = VALOF
{  LET s = IsInARegister(x);
   LET nextop = PeekN();
   LET r = nextop=s.res | nextop=s.fnrn -> 1,
		   1<=argumentNumber<=4 -> ArgumentRegister(argumentNumber),
					  -1;
   argumentNumber := Null;
   TEST s=Null | (h1!x=k.loc & h3!x>=ssp-2) | h1!x=k.reg THEN {
      IF r>0 & mustBeDistinct THEN Lock(r, k.reg);
      s := MoveToAnyR(x); Lock(s, k.reg);
      IF r<0 THEN
	 TEST mustBeDistinct THEN
	    r := NextR()
	 ELSE
	    r := s }
   ELSE {
      TEST r=s & mustBeDistinct THEN {
	 Lock(r, k.reg); s := MoveToAnyR(x) }
      ELSE
	 MoveToR(s, x);
      IF r<0 THEN r := NextR() };
   FlushPendingUsesOfReg(r);
   !lvs := s;
   RESULTIS r
}

AND DoTwoSimpleMultiplies(x, m, n) BE
{  LET s = ?;
   LET r = FindSourceAndDestinationRegisters(@s, x, FALSE);
   registerForMultiply := r;
   SimpleMultiply(r, n, s, FALSE);
   SimpleMultiply(r, m, r, TRUE)
}

AND FRandShiftedR(f, r, s, t, k) BE
   F1Inst(f, r, s, t, 0, sh.asl, LogBase2(k), m.always)

AND MultiplyBySumOrDifferenceOfPowers(f, x, n, k) BE
{  LET s = ?;
   LET r = FindSourceAndDestinationRegisters(@s, x, TRUE);
   registerForMultiply := r;
   SimpleMultiply(r, n, s, FALSE);
   FRandShiftedR(f, r, r, s, k);
   Unlock(s, k.reg)
}


AND TwoInstructionMultiply(k, x) = VALOF
{  LET bottombit = LowBit(k);
   LET n = ?;

   IF bottombit~=1 THEN {
      n := k/bottombit;
      IF IsSimpleMultiply(n) THEN {  // multiplier is 2^n * (2^m+-1)
	 DoTwoSimpleMultiplies(x, bottombit, n);
	 RESULTIS TRUE } };

   n := DivByPowerOf2Minus1(k);
   IF n~=Null THEN
   {  LET m = k/n;
      IF IsSimpleMultiply(m) THEN {  // multiplier is (2^n-1)(2^m+-1)
	 DoTwoSimpleMultiplies(x, n, m);
	 RESULTIS TRUE } };

   n := DivByPowerOf2Plus1(k);
   IF n~=Null THEN {
      LET m = k/n;
      IF IsSimpleMultiply(m) THEN {  // multiplier is (2^n+1)(2^m+1)
	 DoTwoSimpleMultiplies(x, n, m)
	 RESULTIS TRUE } };

   n := IsSumOfPowers(k, 2);
   IF n~=Null THEN {  // multiplier is 2^n+2^m+-1
      // 2^n+2^m is of course detected earlier
      MultiplyBySumOrDifferenceOfPowers(f.add, x, n, k-n);
      RESULTIS TRUE };

   n := IsDifferenceOfPowers(k, 2);
   IF n~=Null THEN {  // multiplier is 2^n-2^m+-1
      MultiplyBySumOrDifferenceOfPowers(f.rsb, x, n, k+n);
      RESULTIS TRUE };

   RESULTIS FALSE
}


AND IsSumOrDifferenceOfPowersOf2(k) = VALOF
{  LET bottombit = LowBit(k);
   LET n = k-bottombit;

   IF IsPowerOf2(n) THEN {
      secondOp := f.add;
      secondMultiplier := bottombit;
      thirdMultiplier := n;
      RESULTIS TRUE };

   n := k+bottombit;
   IF IsPowerOf2(n) THEN {
      secondOp := f.rsb;
      secondMultiplier := bottombit;
      thirdMultiplier := n;
      RESULTIS TRUE };

   RESULTIS FALSE
}

AND IsSumOfPowers(k, p) = VALOF
{  LET n = LowBit(k-1)+1;
   LET m = LowBit(k+1)-1;

   RESULTIS	  IsPowerOf2(k-n) -> n,
		  IsPowerOf2(k-m) -> m,
			      p=2 -> Null,
IsSumOrDifferenceOfPowersOf2(k-n) -> n,
IsSumOrDifferenceOfPowersOf2(k-m) -> m,
				     Null
}

AND IsDifferenceOfPowers(k, p) = VALOF
{  LET n = LowBit(k+1)+1;
   LET m = LowBit(k-1)-1;

   RESULTIS	  IsPowerOf2(k+n) -> n,
		  IsPowerOf2(k+m) -> m,
			      p=2 -> Null,
IsSumOrDifferenceOfPowersOf2(k+n) -> n,
IsSumOrDifferenceOfPowersOf2(k+m) -> m,
				     Null
}

AND SimpleMultiply(res, k, r, deferShift) BE
   TEST IsPowerOf2(k) THEN
      TEST res=r & deferShift THEN
	 deferredShift := sh.asl*32+LogBase2(k)
      ELSE
	 ShiftRegisterDS(res, r, sh.asl, LogBase2(k))
   ELSE TEST IsPowerOf2(k+1)
      THEN FRandShiftedR(f.rsb, res, r, r, k+1)
   ELSE TEST IsPowerOf2(k-1)
      THEN FRandShiftedR(f.add, res, r, r, k-1)
      ELSE CGError(FALSE, "SimpleMultiply wrongly called (k=%n)", k)


AND CGMult() BE
{  LET a, b = arg1, arg2;
   IF Class(arg1, TRUE) < Class(arg2, TRUE) THEN
      a, b := arg2, arg1;
   deferredShift := Null;
   IF IsConst(a) THEN {
      LET k = h3!a;
      LET r = Null;
      TEST k=0 | IsConst(b) THEN {
	 LET k2 = h3!b;
	 Stack(ssp-2);
	 Load(k.number, k*k2);
	 RETURN }

      ELSE TEST k=1 THEN
      {  LET t, ind, n, k = h1!b, h2!b, h3!b, h4!b;
	 Stack(ssp-1);
	 h1!arg1, h2!arg1, h3!arg1, h4!arg1 := t, ind, n, k;
	 RETURN }

      ELSE TEST IsSimpleMultiply(k) THEN {  // multipler is 2^n[+-1]
	 LET s = ?;
	 r := FindSourceAndDestinationRegisters(@s, b, FALSE);
	 SimpleMultiply(r, k, s, TRUE);
	 UnLock(s, k.reg) }

      ELSE TEST TwoInstructionMultiply(k, b) THEN
	 r := registerForMultiply

      ELSE TEST (k&1)=0 & TwoInstructionMultiply(k/LowBit(k), b) THEN {
	 r := registerForMultiply;
	 SimpleMultiply(r, LowBit(k), r, TRUE) }

      ELSE {
	 LET n = DivByPowerOf2minus1(k);
	 IF n~=Null & TwoInstructionMultiply(k/n, b) THEN {
	    r := registerForMultiply;
	    SimpleMultiply(r, n, r, FALSE);
	    GOTO done };

	 n := DivByPowerOf2plus1(k);
	 IF n~=Null & TwoInstructionMultiply(k/n, b) THEN {
	    r := registerForMultiply;
	    SimpleMultiply(r, n, r, FALSE);
	    GOTO done };

	 n := IsSumOfPowers(k, 3);
	 IF n~=Null THEN {
	    LET s = ?;
	    LET r = FindSourceAndDestinationRegisters(@s, b, TRUE);
	    SimpleMultiply(r, n, s, FALSE);
	    FRandShiftedR(secondOp, r, r, s, secondMultiplier)
	    FRandShiftedR(secondOp, r, r, s, thirdMultiplier)
	    Unlock(r, k.reg); Unlock(s, k.reg);
	    GOTO done };

	 n := IsDifferenceOfPowers(k, 3);
	 IF n~=Null THEN {
	    LET s = ?;
	    LET r = FindSourceAndDestinationRegisters(@s, b, TRUE);
	    SimpleMultiply(r, n, s, FALSE);
	    FRandShiftedR((secondOp=f.rsb -> f.add, f.rsb),
			  r, r, s, secondMultiplier)
	    FRandShiftedR(secondOp, r, r, s, thirdMultiplier)
	    Unlock(r, k.reg); Unlock(s, k.reg) } };

done:
      IF r~=Null THEN
      {  LoseR(r, deferredShift);
	 RETURN } };

   {  LET s = ?;
      LET r = FindSourceAndDestinationRegisters(@s, b, FALSE);
      LET r2 = ?;
      FlushPendingUsesOfReg(r);
      Lock(s, k.reg);
      r2 := MoveToAnyCR(a);
      IF r = r2 = s THEN {
	 r2 := NextR();
	 MoveToR(r2, a) };
      IF r=s THEN { LET temp = s; s := r2; r2 := temp };
      MultiplyInst(f.mul, r, s, r2, 0);
      Lose(r, k.reg);
      UnLock(s, k.reg) }
}

AND CallArithmeticRoutine(offset, a1, a2, res) BE
{  MoveToR(ArgumentRegister(1), a1);
   MoveToR(ArgumentRegister(2), a2);
   FlushPendingUsesOfReg(ArgumentRegister(1));
   FlushPendingUsesOfReg(ArgumentRegister(2));
   FlushPendingUsesOfReg(r.14);
   TEST CompactCode THEN
      F5InstL(m.always, (offset=sr.multiply -> MultLab, QuotLab), f.bl)
   ELSE
      CallSub(offset);
   DiscardReg(ArgumentRegister(1), k.reg);
   DiscardReg(ArgumentRegister(2), k.reg);
   DiscardReg(r.14, k.reg);
   Lose(ArgumentRegister(res), k.reg)
}

AND CGMinus() BE
   TEST IsConst(arg1) THEN {
      h3!arg1 := -h3!arg1;
      CGPlus() }
   ELSE {
      LET f, x, y = f.sub, arg1, arg2;
      LET r, s = ?, ?;
      IF Class(x, TRUE) < Class(y, TRUE) THEN
	 f, x, y := f.rsb, arg2, arg1;
      r := FindSourceAndDestinationRegisters(@s, y, FALSE);
      GenFDS(f, r, s, x);
      Lose(r, k.reg);
      UnLock(s, k.reg) }

AND CGPlus() BE
{  IF Isconst(arg2) THEN
      SwapSS(arg1, arg2);

   IF IsConst(arg1) & h1!arg2~=k.shreg THEN
   {  LET k = h3!arg1;
      IF k~=0 THEN
      {  IF h2!arg2>=0 THEN MoveToAnyR(arg2);
	 h4!arg2 := h4!arg2+k };
      IsConst(arg2);
      Stack(ssp-1);
      RETURN };

   {  LET NextOp = PeekN();
      TEST NextOp=s.rv THEN {
	 CGVecap(); RETURN }
      ELSE IF NextOp=s.stind THEN {
	 CGVecSt(); RETURN } };

   {  LET x, y = arg1, arg2;
      LET r, s = ?, ?;
      LET k = 0;
      IF h2!arg1<0 & h1!arg1~=k.shreg THEN {  k := h4!arg1; h4!arg1 := 0 };
      IF h2!arg2<0 & h1!arg2~=k.shreg THEN {  k := k+h4!arg2; h4!arg2 := 0 };
      IF Class(x, TRUE)<Class(y, TRUE)
	 THEN x, y := arg2, arg1;
      r := FindSourceAndDestinationRegisters(@s, y, FALSE);
      GenFDS(f.add, r, s, x);
      Lose(r, k.reg);
      h4!arg1 := k;
      UnLock(s, k.reg) }
}

AND CGDiv() BE
{  IF IsConst(arg1) THEN
   {  LET n = h3!arg1;
      IF n=1 THEN {
	 Stack(ssp-1);
	 RETURN };

      IF n=0 THEN {
	 CGError(FALSE, "Compiling division by zero");
	 Stack(ssp-2);
	 Load(k.number, 0);
	 RETURN };

      IF IsConst(arg2) THEN
      {  LET k = h3!arg2;
	 Stack(ssp-2);
	 Load(k.number, k/n);
	 RETURN };

      IF [n&(-n)]=n THEN
      {  LET s = ?;
	 LET r = FindSourceAndDestinationRegisters(@s, arg2, FALSE);
	 GenRR(f.movs, r, 0, s);
	 TEST n=2 THEN {
	    F1Inst(f.sub, r, s, s, 0, sh.asr, 1, m.mi)
	    F1Inst(f.mov, r, 0, s, 0, sh.asr, 1, m.pl) }
	 ELSE {
	    F1Inst(f.rsb, r, r, Null, 0, Null, 0, m.mi);
	    ShiftRegisterDS(r, r, sh.asr, LogBase2(n));
	    F1Inst(f.rsb, r, r, Null, 0, Null, 0, m.mi) };
	 LoseR(r, Null);
	 UnLock(s, k.reg);
	 RETURN } };

   CallArithmeticRoutine(sr.quotrem, arg2, arg1, 1)
}

AND CGRem() BE
{  IF IsConst(arg1) THEN
   {  LET n = h3!arg1;
      LET lowbit = n & (-n);

      IF n=1 | IsConst(arg2) THEN {
	 LET k = h3!arg2;
	 Stack(ssp-2);
	 Load(k.number, k REM n);
	 RETURN };

      IF n=0 THEN {
	 CGError(FALSE, "Compiling division by zero");
	 Stack(ssp-2);
	 Load(k.number, 0);
	 RETURN };

      IF lowbit=n THEN
      {  LET s = ?;
	 LET r = FindSourceAndDestinationRegisters(@s, arg2, FALSE);
	 h3!arg1 := n-1;
	 CompareAgainstK(s, 0, m.lt);
	 GenFDS(f.and, r, s, arg1);
	 F1Inst(f.sub, r, r, Null, n, Null, 0, m.lt);
	 Lose(r, k.reg);
	 UnLock(s, k.reg);
	 RETURN } };

   CallArithmeticRoutine(sr.quotrem, arg2, arg1, 2)
}
00000000  53 45 43 54 49 4f 4e 20  22 43 47 49 22 0a 0a 47  |SECTION "CGI"..G|
00000010  45 54 20 22 62 2e 43 47  68 65 61 64 65 72 22 0a  |ET "b.CGheader".|
00000020  0a 53 54 41 54 49 43 20  7b 0a 20 2f 2a 20 56 65  |.STATIC {. /* Ve|
00000030  72 73 69 6f 6e 20 6f 66  20 31 31 20 53 65 70 20  |rsion of 11 Sep |
00000040  38 37 20 31 33 3a 34 31  3a 34 34 0a 20 2a 2f 0a  |87 13:41:44. */.|
00000050  20 20 20 64 75 6d 6d 79  20 3d 20 56 65 72 73 69  |   dummy = Versi|
00000060  6f 6e 4d 61 72 6b 3b 0a  20 20 20 76 65 72 73 69  |onMark;.   versi|
00000070  6f 6e 20 3d 20 31 2a 32  35 36 2b 37 20 7d 3b 0a  |on = 1*256+7 };.|
00000080  0a 53 54 41 54 49 43 20  7b 0a 20 20 20 64 65 66  |.STATIC {.   def|
00000090  65 72 72 65 64 53 68 69  66 74 20 3d 20 30 3b 0a  |erredShift = 0;.|
000000a0  20 20 20 73 65 63 6f 6e  64 4f 70 20 3d 20 30 3b  |   secondOp = 0;|
000000b0  0a 20 20 20 73 65 63 6f  6e 64 4d 75 6c 74 69 70  |.   secondMultip|
000000c0  6c 69 65 72 20 3d 20 30  3b 0a 20 20 20 74 68 69  |lier = 0;.   thi|
000000d0  72 64 4d 75 6c 74 69 70  6c 69 65 72 20 3d 20 30  |rdMultiplier = 0|
000000e0  3b 0a 20 20 20 72 65 67  69 73 74 65 72 46 6f 72  |;.   registerFor|
000000f0  4d 75 6c 74 69 70 6c 79  20 3d 20 30 20 7d 0a 0a  |Multiply = 0 }..|
00000100  4c 45 54 20 4c 6f 77 42  69 74 28 6e 29 20 3d 20  |LET LowBit(n) = |
00000110  6e 20 26 20 28 2d 6e 29  0a 0a 41 4e 44 20 44 69  |n & (-n)..AND Di|
00000120  76 42 79 50 6f 77 65 72  4f 66 32 4d 69 6e 75 73  |vByPowerOf2Minus|
00000130  31 28 6e 29 20 3d 20 56  41 4c 4f 46 0a 7b 20 20  |1(n) = VALOF.{  |
00000140  4c 45 54 20 74 20 3d 20  54 41 42 4c 45 09 20 23  |LET t = TABLE. #|
00000150  78 37 66 66 66 66 66 2c  20 23 78 33 66 66 66 66  |x7fffff, #x3ffff|
00000160  66 2c 20 23 78 31 66 66  66 66 66 2c 0a 09 09 23  |f, #x1fffff,...#|
00000170  78 66 66 66 66 66 2c 20  20 23 78 37 66 66 66 66  |xfffff,  #x7ffff|
00000180  2c 20 20 23 78 33 66 66  66 66 2c 20 20 23 78 31  |,  #x3ffff,  #x1|
00000190  66 66 66 66 2c 0a 09 09  20 23 78 66 66 66 66 2c  |ffff,... #xffff,|
000001a0  20 20 20 23 78 37 66 66  66 2c 20 20 20 23 78 33  |   #x7fff,   #x3|
000001b0  66 66 66 2c 20 20 20 23  78 31 66 66 66 2c 0a 09  |fff,   #x1fff,..|
000001c0  09 20 20 23 78 66 66 66  2c 20 20 20 20 23 78 37  |.  #xfff,    #x7|
000001d0  66 66 2c 20 20 20 20 23  78 33 66 66 2c 09 23 78  |ff,    #x3ff,.#x|
000001e0  31 66 66 2c 0a 09 09 20  20 20 23 78 66 66 2c 20  |1ff,...   #xff, |
000001f0  20 20 20 20 23 78 37 66  2c 20 20 20 20 20 23 78  |    #x7f,     #x|
00000200  33 66 2c 09 20 23 78 31  66 2c 0a 09 09 20 20 20  |3f,. #x1f,...   |
00000210  20 23 78 66 2c 20 20 20  20 20 20 23 78 37 2c 09  | #xf,      #x7,.|
00000220  23 78 33 2c 09 20 20 20  20 30 3b 0a 20 20 20 4c  |#x3,.    0;.   L|
00000230  45 54 20 69 20 3d 20 30  3b 0a 20 20 20 4c 45 54  |ET i = 0;.   LET|
00000240  20 78 20 3d 20 3f 3b 0a  20 20 20 7b 20 20 78 20  | x = ?;.   {  x |
00000250  3a 3d 20 74 21 69 3b 0a  20 20 20 20 20 20 49 46  |:= t!i;.      IF|
00000260  20 78 3d 30 20 54 48 45  4e 20 52 45 53 55 4c 54  | x=0 THEN RESULT|
00000270  49 53 20 4e 75 6c 6c 3b  0a 20 20 20 20 20 20 49  |IS Null;.      I|
00000280  46 20 28 6e 20 52 45 4d  20 78 29 3d 30 20 54 48  |F (n REM x)=0 TH|
00000290  45 4e 20 52 45 53 55 4c  54 49 53 20 78 0a 20 20  |EN RESULTIS x.  |
000002a0  20 20 20 20 69 20 3a 3d  20 69 2b 31 0a 20 20 20  |    i := i+1.   |
000002b0  7d 20 52 45 50 45 41 54  0a 7d 0a 0a 41 4e 44 20  |} REPEAT.}..AND |
000002c0  44 69 76 42 79 50 6f 77  65 72 4f 66 32 50 6c 75  |DivByPowerOf2Plu|
000002d0  73 31 28 6e 29 20 3d 20  56 41 4c 4f 46 0a 7b 20  |s1(n) = VALOF.{ |
000002e0  20 4c 45 54 20 74 20 3d  20 54 41 42 4c 45 09 20  | LET t = TABLE. |
000002f0  23 78 34 30 30 30 30 31  2c 20 23 78 32 30 30 30  |#x400001, #x2000|
00000300  30 31 2c 20 23 78 31 30  30 30 30 31 2c 0a 09 09  |01, #x100001,...|
00000310  23 78 38 30 30 30 31 2c  20 20 23 78 34 30 30 30  |#x80001,  #x4000|
00000320  31 2c 20 20 23 78 32 30  30 30 31 2c 20 20 23 78  |1,  #x20001,  #x|
00000330  31 30 30 30 31 2c 0a 09  09 20 23 78 38 30 30 31  |10001,... #x8001|
00000340  2c 20 20 20 23 78 34 30  30 31 2c 20 20 20 23 78  |,   #x4001,   #x|
00000350  32 30 30 31 2c 20 20 20  23 78 31 30 30 31 2c 0a  |2001,   #x1001,.|
00000360  09 09 20 20 23 78 38 30  31 2c 20 20 20 20 23 78  |..  #x801,    #x|
00000370  34 30 31 2c 20 20 20 20  23 78 32 30 31 2c 09 23  |401,    #x201,.#|
00000380  78 31 30 31 2c 0a 09 09  20 20 20 23 78 38 31 2c  |x101,...   #x81,|
00000390  20 20 20 20 20 23 78 34  31 2c 20 20 20 20 20 23  |     #x41,     #|
000003a0  78 32 31 2c 09 20 23 78  31 31 2c 0a 09 09 20 20  |x21,. #x11,...  |
000003b0  20 20 23 78 39 2c 20 20  20 20 20 20 23 78 35 2c  |  #x9,      #x5,|
000003c0  09 20 20 30 3b 0a 20 20  20 4c 45 54 20 69 20 3d  |.  0;.   LET i =|
000003d0  20 30 3b 0a 20 20 20 4c  45 54 20 78 20 3d 20 3f  | 0;.   LET x = ?|
000003e0  0a 20 20 20 7b 20 20 78  20 3a 3d 20 74 21 69 3b  |.   {  x := t!i;|
000003f0  0a 20 20 20 20 20 20 49  46 20 78 3d 30 20 54 48  |.      IF x=0 TH|
00000400  45 4e 20 52 45 53 55 4c  54 49 53 20 4e 75 6c 6c  |EN RESULTIS Null|
00000410  3b 0a 20 20 20 20 20 20  49 46 20 28 6e 20 52 45  |;.      IF (n RE|
00000420  4d 20 78 29 3d 30 20 54  48 45 4e 20 52 45 53 55  |M x)=0 THEN RESU|
00000430  4c 54 49 53 20 78 0a 20  20 20 20 20 20 69 20 3a  |LTIS x.      i :|
00000440  3d 20 69 2b 31 0a 20 20  20 7d 20 52 45 50 45 41  |= i+1.   } REPEA|
00000450  54 0a 7d 0a 0a 41 4e 44  20 49 73 50 6f 77 65 72  |T.}..AND IsPower|
00000460  4f 66 32 28 6e 29 20 3d  20 6e 3e 30 20 26 20 4c  |Of2(n) = n>0 & L|
00000470  6f 77 42 69 74 28 6e 29  3d 6e 0a 0a 41 4e 44 20  |owBit(n)=n..AND |
00000480  49 73 53 69 6d 70 6c 65  4d 75 6c 74 69 70 6c 79  |IsSimpleMultiply|
00000490  28 6b 29 20 3d 20 49 73  50 6f 77 65 72 4f 66 32  |(k) = IsPowerOf2|
000004a0  28 6b 29 20 7c 0a 09 09  09 20 20 49 73 50 6f 77  |(k) |....  IsPow|
000004b0  65 72 4f 66 32 28 6b 2b  31 29 20 7c 0a 09 09 09  |erOf2(k+1) |....|
000004c0  20 20 49 73 50 6f 77 65  72 4f 66 32 28 6b 2d 31  |  IsPowerOf2(k-1|
000004d0  29 0a 0a 41 4e 44 20 46  69 6e 64 53 6f 75 72 63  |)..AND FindSourc|
000004e0  65 41 6e 64 44 65 73 74  69 6e 61 74 69 6f 6e 52  |eAndDestinationR|
000004f0  65 67 69 73 74 65 72 73  28 6c 76 73 2c 20 78 2c  |egisters(lvs, x,|
00000500  20 6d 75 73 74 42 65 44  69 73 74 69 6e 63 74 29  | mustBeDistinct)|
00000510  20 3d 20 56 41 4c 4f 46  0a 7b 20 20 4c 45 54 20  | = VALOF.{  LET |
00000520  73 20 3d 20 49 73 49 6e  41 52 65 67 69 73 74 65  |s = IsInARegiste|
00000530  72 28 78 29 3b 0a 20 20  20 4c 45 54 20 6e 65 78  |r(x);.   LET nex|
00000540  74 6f 70 20 3d 20 50 65  65 6b 4e 28 29 3b 0a 20  |top = PeekN();. |
00000550  20 20 4c 45 54 20 72 20  3d 20 6e 65 78 74 6f 70  |  LET r = nextop|
00000560  3d 73 2e 72 65 73 20 7c  20 6e 65 78 74 6f 70 3d  |=s.res | nextop=|
00000570  73 2e 66 6e 72 6e 20 2d  3e 20 31 2c 0a 09 09 20  |s.fnrn -> 1,... |
00000580  20 20 31 3c 3d 61 72 67  75 6d 65 6e 74 4e 75 6d  |  1<=argumentNum|
00000590  62 65 72 3c 3d 34 20 2d  3e 20 41 72 67 75 6d 65  |ber<=4 -> Argume|
000005a0  6e 74 52 65 67 69 73 74  65 72 28 61 72 67 75 6d  |ntRegister(argum|
000005b0  65 6e 74 4e 75 6d 62 65  72 29 2c 0a 09 09 09 09  |entNumber),.....|
000005c0  09 20 20 2d 31 3b 0a 20  20 20 61 72 67 75 6d 65  |.  -1;.   argume|
000005d0  6e 74 4e 75 6d 62 65 72  20 3a 3d 20 4e 75 6c 6c  |ntNumber := Null|
000005e0  3b 0a 20 20 20 54 45 53  54 20 73 3d 4e 75 6c 6c  |;.   TEST s=Null|
000005f0  20 7c 20 28 68 31 21 78  3d 6b 2e 6c 6f 63 20 26  | | (h1!x=k.loc &|
00000600  20 68 33 21 78 3e 3d 73  73 70 2d 32 29 20 7c 20  | h3!x>=ssp-2) | |
00000610  68 31 21 78 3d 6b 2e 72  65 67 20 54 48 45 4e 20  |h1!x=k.reg THEN |
00000620  7b 0a 20 20 20 20 20 20  49 46 20 72 3e 30 20 26  |{.      IF r>0 &|
00000630  20 6d 75 73 74 42 65 44  69 73 74 69 6e 63 74 20  | mustBeDistinct |
00000640  54 48 45 4e 20 4c 6f 63  6b 28 72 2c 20 6b 2e 72  |THEN Lock(r, k.r|
00000650  65 67 29 3b 0a 20 20 20  20 20 20 73 20 3a 3d 20  |eg);.      s := |
00000660  4d 6f 76 65 54 6f 41 6e  79 52 28 78 29 3b 20 4c  |MoveToAnyR(x); L|
00000670  6f 63 6b 28 73 2c 20 6b  2e 72 65 67 29 3b 0a 20  |ock(s, k.reg);. |
00000680  20 20 20 20 20 49 46 20  72 3c 30 20 54 48 45 4e  |     IF r<0 THEN|
00000690  0a 09 20 54 45 53 54 20  6d 75 73 74 42 65 44 69  |.. TEST mustBeDi|
000006a0  73 74 69 6e 63 74 20 54  48 45 4e 0a 09 20 20 20  |stinct THEN..   |
000006b0  20 72 20 3a 3d 20 4e 65  78 74 52 28 29 0a 09 20  | r := NextR().. |
000006c0  45 4c 53 45 0a 09 20 20  20 20 72 20 3a 3d 20 73  |ELSE..    r := s|
000006d0  20 7d 0a 20 20 20 45 4c  53 45 20 7b 0a 20 20 20  | }.   ELSE {.   |
000006e0  20 20 20 54 45 53 54 20  72 3d 73 20 26 20 6d 75  |   TEST r=s & mu|
000006f0  73 74 42 65 44 69 73 74  69 6e 63 74 20 54 48 45  |stBeDistinct THE|
00000700  4e 20 7b 0a 09 20 4c 6f  63 6b 28 72 2c 20 6b 2e  |N {.. Lock(r, k.|
00000710  72 65 67 29 3b 20 73 20  3a 3d 20 4d 6f 76 65 54  |reg); s := MoveT|
00000720  6f 41 6e 79 52 28 78 29  20 7d 0a 20 20 20 20 20  |oAnyR(x) }.     |
00000730  20 45 4c 53 45 0a 09 20  4d 6f 76 65 54 6f 52 28  | ELSE.. MoveToR(|
00000740  73 2c 20 78 29 3b 0a 20  20 20 20 20 20 49 46 20  |s, x);.      IF |
00000750  72 3c 30 20 54 48 45 4e  20 72 20 3a 3d 20 4e 65  |r<0 THEN r := Ne|
00000760  78 74 52 28 29 20 7d 3b  0a 20 20 20 46 6c 75 73  |xtR() };.   Flus|
00000770  68 50 65 6e 64 69 6e 67  55 73 65 73 4f 66 52 65  |hPendingUsesOfRe|
00000780  67 28 72 29 3b 0a 20 20  20 21 6c 76 73 20 3a 3d  |g(r);.   !lvs :=|
00000790  20 73 3b 0a 20 20 20 52  45 53 55 4c 54 49 53 20  | s;.   RESULTIS |
000007a0  72 0a 7d 0a 0a 41 4e 44  20 44 6f 54 77 6f 53 69  |r.}..AND DoTwoSi|
000007b0  6d 70 6c 65 4d 75 6c 74  69 70 6c 69 65 73 28 78  |mpleMultiplies(x|
000007c0  2c 20 6d 2c 20 6e 29 20  42 45 0a 7b 20 20 4c 45  |, m, n) BE.{  LE|
000007d0  54 20 73 20 3d 20 3f 3b  0a 20 20 20 4c 45 54 20  |T s = ?;.   LET |
000007e0  72 20 3d 20 46 69 6e 64  53 6f 75 72 63 65 41 6e  |r = FindSourceAn|
000007f0  64 44 65 73 74 69 6e 61  74 69 6f 6e 52 65 67 69  |dDestinationRegi|
00000800  73 74 65 72 73 28 40 73  2c 20 78 2c 20 46 41 4c  |sters(@s, x, FAL|
00000810  53 45 29 3b 0a 20 20 20  72 65 67 69 73 74 65 72  |SE);.   register|
00000820  46 6f 72 4d 75 6c 74 69  70 6c 79 20 3a 3d 20 72  |ForMultiply := r|
00000830  3b 0a 20 20 20 53 69 6d  70 6c 65 4d 75 6c 74 69  |;.   SimpleMulti|
00000840  70 6c 79 28 72 2c 20 6e  2c 20 73 2c 20 46 41 4c  |ply(r, n, s, FAL|
00000850  53 45 29 3b 0a 20 20 20  53 69 6d 70 6c 65 4d 75  |SE);.   SimpleMu|
00000860  6c 74 69 70 6c 79 28 72  2c 20 6d 2c 20 72 2c 20  |ltiply(r, m, r, |
00000870  54 52 55 45 29 0a 7d 0a  0a 41 4e 44 20 46 52 61  |TRUE).}..AND FRa|
00000880  6e 64 53 68 69 66 74 65  64 52 28 66 2c 20 72 2c  |ndShiftedR(f, r,|
00000890  20 73 2c 20 74 2c 20 6b  29 20 42 45 0a 20 20 20  | s, t, k) BE.   |
000008a0  46 31 49 6e 73 74 28 66  2c 20 72 2c 20 73 2c 20  |F1Inst(f, r, s, |
000008b0  74 2c 20 30 2c 20 73 68  2e 61 73 6c 2c 20 4c 6f  |t, 0, sh.asl, Lo|
000008c0  67 42 61 73 65 32 28 6b  29 2c 20 6d 2e 61 6c 77  |gBase2(k), m.alw|
000008d0  61 79 73 29 0a 0a 41 4e  44 20 4d 75 6c 74 69 70  |ays)..AND Multip|
000008e0  6c 79 42 79 53 75 6d 4f  72 44 69 66 66 65 72 65  |lyBySumOrDiffere|
000008f0  6e 63 65 4f 66 50 6f 77  65 72 73 28 66 2c 20 78  |nceOfPowers(f, x|
00000900  2c 20 6e 2c 20 6b 29 20  42 45 0a 7b 20 20 4c 45  |, n, k) BE.{  LE|
00000910  54 20 73 20 3d 20 3f 3b  0a 20 20 20 4c 45 54 20  |T s = ?;.   LET |
00000920  72 20 3d 20 46 69 6e 64  53 6f 75 72 63 65 41 6e  |r = FindSourceAn|
00000930  64 44 65 73 74 69 6e 61  74 69 6f 6e 52 65 67 69  |dDestinationRegi|
00000940  73 74 65 72 73 28 40 73  2c 20 78 2c 20 54 52 55  |sters(@s, x, TRU|
00000950  45 29 3b 0a 20 20 20 72  65 67 69 73 74 65 72 46  |E);.   registerF|
00000960  6f 72 4d 75 6c 74 69 70  6c 79 20 3a 3d 20 72 3b  |orMultiply := r;|
00000970  0a 20 20 20 53 69 6d 70  6c 65 4d 75 6c 74 69 70  |.   SimpleMultip|
00000980  6c 79 28 72 2c 20 6e 2c  20 73 2c 20 46 41 4c 53  |ly(r, n, s, FALS|
00000990  45 29 3b 0a 20 20 20 46  52 61 6e 64 53 68 69 66  |E);.   FRandShif|
000009a0  74 65 64 52 28 66 2c 20  72 2c 20 72 2c 20 73 2c  |tedR(f, r, r, s,|
000009b0  20 6b 29 3b 0a 20 20 20  55 6e 6c 6f 63 6b 28 73  | k);.   Unlock(s|
000009c0  2c 20 6b 2e 72 65 67 29  0a 7d 0a 0a 0a 41 4e 44  |, k.reg).}...AND|
000009d0  20 54 77 6f 49 6e 73 74  72 75 63 74 69 6f 6e 4d  | TwoInstructionM|
000009e0  75 6c 74 69 70 6c 79 28  6b 2c 20 78 29 20 3d 20  |ultiply(k, x) = |
000009f0  56 41 4c 4f 46 0a 7b 20  20 4c 45 54 20 62 6f 74  |VALOF.{  LET bot|
00000a00  74 6f 6d 62 69 74 20 3d  20 4c 6f 77 42 69 74 28  |tombit = LowBit(|
00000a10  6b 29 3b 0a 20 20 20 4c  45 54 20 6e 20 3d 20 3f  |k);.   LET n = ?|
00000a20  3b 0a 0a 20 20 20 49 46  20 62 6f 74 74 6f 6d 62  |;..   IF bottomb|
00000a30  69 74 7e 3d 31 20 54 48  45 4e 20 7b 0a 20 20 20  |it~=1 THEN {.   |
00000a40  20 20 20 6e 20 3a 3d 20  6b 2f 62 6f 74 74 6f 6d  |   n := k/bottom|
00000a50  62 69 74 3b 0a 20 20 20  20 20 20 49 46 20 49 73  |bit;.      IF Is|
00000a60  53 69 6d 70 6c 65 4d 75  6c 74 69 70 6c 79 28 6e  |SimpleMultiply(n|
00000a70  29 20 54 48 45 4e 20 7b  20 20 2f 2f 20 6d 75 6c  |) THEN {  // mul|
00000a80  74 69 70 6c 69 65 72 20  69 73 20 32 5e 6e 20 2a  |tiplier is 2^n *|
00000a90  20 28 32 5e 6d 2b 2d 31  29 0a 09 20 44 6f 54 77  | (2^m+-1).. DoTw|
00000aa0  6f 53 69 6d 70 6c 65 4d  75 6c 74 69 70 6c 69 65  |oSimpleMultiplie|
00000ab0  73 28 78 2c 20 62 6f 74  74 6f 6d 62 69 74 2c 20  |s(x, bottombit, |
00000ac0  6e 29 3b 0a 09 20 52 45  53 55 4c 54 49 53 20 54  |n);.. RESULTIS T|
00000ad0  52 55 45 20 7d 20 7d 3b  0a 0a 20 20 20 6e 20 3a  |RUE } };..   n :|
00000ae0  3d 20 44 69 76 42 79 50  6f 77 65 72 4f 66 32 4d  |= DivByPowerOf2M|
00000af0  69 6e 75 73 31 28 6b 29  3b 0a 20 20 20 49 46 20  |inus1(k);.   IF |
00000b00  6e 7e 3d 4e 75 6c 6c 20  54 48 45 4e 0a 20 20 20  |n~=Null THEN.   |
00000b10  7b 20 20 4c 45 54 20 6d  20 3d 20 6b 2f 6e 3b 0a  |{  LET m = k/n;.|
00000b20  20 20 20 20 20 20 49 46  20 49 73 53 69 6d 70 6c  |      IF IsSimpl|
00000b30  65 4d 75 6c 74 69 70 6c  79 28 6d 29 20 54 48 45  |eMultiply(m) THE|
00000b40  4e 20 7b 20 20 2f 2f 20  6d 75 6c 74 69 70 6c 69  |N {  // multipli|
00000b50  65 72 20 69 73 20 28 32  5e 6e 2d 31 29 28 32 5e  |er is (2^n-1)(2^|
00000b60  6d 2b 2d 31 29 0a 09 20  44 6f 54 77 6f 53 69 6d  |m+-1).. DoTwoSim|
00000b70  70 6c 65 4d 75 6c 74 69  70 6c 69 65 73 28 78 2c  |pleMultiplies(x,|
00000b80  20 6e 2c 20 6d 29 3b 0a  09 20 52 45 53 55 4c 54  | n, m);.. RESULT|
00000b90  49 53 20 54 52 55 45 20  7d 20 7d 3b 0a 0a 20 20  |IS TRUE } };..  |
00000ba0  20 6e 20 3a 3d 20 44 69  76 42 79 50 6f 77 65 72  | n := DivByPower|
00000bb0  4f 66 32 50 6c 75 73 31  28 6b 29 3b 0a 20 20 20  |Of2Plus1(k);.   |
00000bc0  49 46 20 6e 7e 3d 4e 75  6c 6c 20 54 48 45 4e 20  |IF n~=Null THEN |
00000bd0  7b 0a 20 20 20 20 20 20  4c 45 54 20 6d 20 3d 20  |{.      LET m = |
00000be0  6b 2f 6e 3b 0a 20 20 20  20 20 20 49 46 20 49 73  |k/n;.      IF Is|
00000bf0  53 69 6d 70 6c 65 4d 75  6c 74 69 70 6c 79 28 6d  |SimpleMultiply(m|
00000c00  29 20 54 48 45 4e 20 7b  20 20 2f 2f 20 6d 75 6c  |) THEN {  // mul|
00000c10  74 69 70 6c 69 65 72 20  69 73 20 28 32 5e 6e 2b  |tiplier is (2^n+|
00000c20  31 29 28 32 5e 6d 2b 31  29 0a 09 20 44 6f 54 77  |1)(2^m+1).. DoTw|
00000c30  6f 53 69 6d 70 6c 65 4d  75 6c 74 69 70 6c 69 65  |oSimpleMultiplie|
00000c40  73 28 78 2c 20 6e 2c 20  6d 29 0a 09 20 52 45 53  |s(x, n, m).. RES|
00000c50  55 4c 54 49 53 20 54 52  55 45 20 7d 20 7d 3b 0a  |ULTIS TRUE } };.|
00000c60  0a 20 20 20 6e 20 3a 3d  20 49 73 53 75 6d 4f 66  |.   n := IsSumOf|
00000c70  50 6f 77 65 72 73 28 6b  2c 20 32 29 3b 0a 20 20  |Powers(k, 2);.  |
00000c80  20 49 46 20 6e 7e 3d 4e  75 6c 6c 20 54 48 45 4e  | IF n~=Null THEN|
00000c90  20 7b 20 20 2f 2f 20 6d  75 6c 74 69 70 6c 69 65  | {  // multiplie|
00000ca0  72 20 69 73 20 32 5e 6e  2b 32 5e 6d 2b 2d 31 0a  |r is 2^n+2^m+-1.|
00000cb0  20 20 20 20 20 20 2f 2f  20 32 5e 6e 2b 32 5e 6d  |      // 2^n+2^m|
00000cc0  20 69 73 20 6f 66 20 63  6f 75 72 73 65 20 64 65  | is of course de|
00000cd0  74 65 63 74 65 64 20 65  61 72 6c 69 65 72 0a 20  |tected earlier. |
00000ce0  20 20 20 20 20 4d 75 6c  74 69 70 6c 79 42 79 53  |     MultiplyByS|
00000cf0  75 6d 4f 72 44 69 66 66  65 72 65 6e 63 65 4f 66  |umOrDifferenceOf|
00000d00  50 6f 77 65 72 73 28 66  2e 61 64 64 2c 20 78 2c  |Powers(f.add, x,|
00000d10  20 6e 2c 20 6b 2d 6e 29  3b 0a 20 20 20 20 20 20  | n, k-n);.      |
00000d20  52 45 53 55 4c 54 49 53  20 54 52 55 45 20 7d 3b  |RESULTIS TRUE };|
00000d30  0a 0a 20 20 20 6e 20 3a  3d 20 49 73 44 69 66 66  |..   n := IsDiff|
00000d40  65 72 65 6e 63 65 4f 66  50 6f 77 65 72 73 28 6b  |erenceOfPowers(k|
00000d50  2c 20 32 29 3b 0a 20 20  20 49 46 20 6e 7e 3d 4e  |, 2);.   IF n~=N|
00000d60  75 6c 6c 20 54 48 45 4e  20 7b 20 20 2f 2f 20 6d  |ull THEN {  // m|
00000d70  75 6c 74 69 70 6c 69 65  72 20 69 73 20 32 5e 6e  |ultiplier is 2^n|
00000d80  2d 32 5e 6d 2b 2d 31 0a  20 20 20 20 20 20 4d 75  |-2^m+-1.      Mu|
00000d90  6c 74 69 70 6c 79 42 79  53 75 6d 4f 72 44 69 66  |ltiplyBySumOrDif|
00000da0  66 65 72 65 6e 63 65 4f  66 50 6f 77 65 72 73 28  |ferenceOfPowers(|
00000db0  66 2e 72 73 62 2c 20 78  2c 20 6e 2c 20 6b 2b 6e  |f.rsb, x, n, k+n|
00000dc0  29 3b 0a 20 20 20 20 20  20 52 45 53 55 4c 54 49  |);.      RESULTI|
00000dd0  53 20 54 52 55 45 20 7d  3b 0a 0a 20 20 20 52 45  |S TRUE };..   RE|
00000de0  53 55 4c 54 49 53 20 46  41 4c 53 45 0a 7d 0a 0a  |SULTIS FALSE.}..|
00000df0  0a 41 4e 44 20 49 73 53  75 6d 4f 72 44 69 66 66  |.AND IsSumOrDiff|
00000e00  65 72 65 6e 63 65 4f 66  50 6f 77 65 72 73 4f 66  |erenceOfPowersOf|
00000e10  32 28 6b 29 20 3d 20 56  41 4c 4f 46 0a 7b 20 20  |2(k) = VALOF.{  |
00000e20  4c 45 54 20 62 6f 74 74  6f 6d 62 69 74 20 3d 20  |LET bottombit = |
00000e30  4c 6f 77 42 69 74 28 6b  29 3b 0a 20 20 20 4c 45  |LowBit(k);.   LE|
00000e40  54 20 6e 20 3d 20 6b 2d  62 6f 74 74 6f 6d 62 69  |T n = k-bottombi|
00000e50  74 3b 0a 0a 20 20 20 49  46 20 49 73 50 6f 77 65  |t;..   IF IsPowe|
00000e60  72 4f 66 32 28 6e 29 20  54 48 45 4e 20 7b 0a 20  |rOf2(n) THEN {. |
00000e70  20 20 20 20 20 73 65 63  6f 6e 64 4f 70 20 3a 3d  |     secondOp :=|
00000e80  20 66 2e 61 64 64 3b 0a  20 20 20 20 20 20 73 65  | f.add;.      se|
00000e90  63 6f 6e 64 4d 75 6c 74  69 70 6c 69 65 72 20 3a  |condMultiplier :|
00000ea0  3d 20 62 6f 74 74 6f 6d  62 69 74 3b 0a 20 20 20  |= bottombit;.   |
00000eb0  20 20 20 74 68 69 72 64  4d 75 6c 74 69 70 6c 69  |   thirdMultipli|
00000ec0  65 72 20 3a 3d 20 6e 3b  0a 20 20 20 20 20 20 52  |er := n;.      R|
00000ed0  45 53 55 4c 54 49 53 20  54 52 55 45 20 7d 3b 0a  |ESULTIS TRUE };.|
00000ee0  0a 20 20 20 6e 20 3a 3d  20 6b 2b 62 6f 74 74 6f  |.   n := k+botto|
00000ef0  6d 62 69 74 3b 0a 20 20  20 49 46 20 49 73 50 6f  |mbit;.   IF IsPo|
00000f00  77 65 72 4f 66 32 28 6e  29 20 54 48 45 4e 20 7b  |werOf2(n) THEN {|
00000f10  0a 20 20 20 20 20 20 73  65 63 6f 6e 64 4f 70 20  |.      secondOp |
00000f20  3a 3d 20 66 2e 72 73 62  3b 0a 20 20 20 20 20 20  |:= f.rsb;.      |
00000f30  73 65 63 6f 6e 64 4d 75  6c 74 69 70 6c 69 65 72  |secondMultiplier|
00000f40  20 3a 3d 20 62 6f 74 74  6f 6d 62 69 74 3b 0a 20  | := bottombit;. |
00000f50  20 20 20 20 20 74 68 69  72 64 4d 75 6c 74 69 70  |     thirdMultip|
00000f60  6c 69 65 72 20 3a 3d 20  6e 3b 0a 20 20 20 20 20  |lier := n;.     |
00000f70  20 52 45 53 55 4c 54 49  53 20 54 52 55 45 20 7d  | RESULTIS TRUE }|
00000f80  3b 0a 0a 20 20 20 52 45  53 55 4c 54 49 53 20 46  |;..   RESULTIS F|
00000f90  41 4c 53 45 0a 7d 0a 0a  41 4e 44 20 49 73 53 75  |ALSE.}..AND IsSu|
00000fa0  6d 4f 66 50 6f 77 65 72  73 28 6b 2c 20 70 29 20  |mOfPowers(k, p) |
00000fb0  3d 20 56 41 4c 4f 46 0a  7b 20 20 4c 45 54 20 6e  |= VALOF.{  LET n|
00000fc0  20 3d 20 4c 6f 77 42 69  74 28 6b 2d 31 29 2b 31  | = LowBit(k-1)+1|
00000fd0  3b 0a 20 20 20 4c 45 54  20 6d 20 3d 20 4c 6f 77  |;.   LET m = Low|
00000fe0  42 69 74 28 6b 2b 31 29  2d 31 3b 0a 0a 20 20 20  |Bit(k+1)-1;..   |
00000ff0  52 45 53 55 4c 54 49 53  09 20 20 49 73 50 6f 77  |RESULTIS.  IsPow|
00001000  65 72 4f 66 32 28 6b 2d  6e 29 20 2d 3e 20 6e 2c  |erOf2(k-n) -> n,|
00001010  0a 09 09 20 20 49 73 50  6f 77 65 72 4f 66 32 28  |...  IsPowerOf2(|
00001020  6b 2d 6d 29 20 2d 3e 20  6d 2c 0a 09 09 09 20 20  |k-m) -> m,....  |
00001030  20 20 20 20 70 3d 32 20  2d 3e 20 4e 75 6c 6c 2c  |    p=2 -> Null,|
00001040  0a 49 73 53 75 6d 4f 72  44 69 66 66 65 72 65 6e  |.IsSumOrDifferen|
00001050  63 65 4f 66 50 6f 77 65  72 73 4f 66 32 28 6b 2d  |ceOfPowersOf2(k-|
00001060  6e 29 20 2d 3e 20 6e 2c  0a 49 73 53 75 6d 4f 72  |n) -> n,.IsSumOr|
00001070  44 69 66 66 65 72 65 6e  63 65 4f 66 50 6f 77 65  |DifferenceOfPowe|
00001080  72 73 4f 66 32 28 6b 2d  6d 29 20 2d 3e 20 6d 2c  |rsOf2(k-m) -> m,|
00001090  0a 09 09 09 09 20 20 20  20 20 4e 75 6c 6c 0a 7d  |.....     Null.}|
000010a0  0a 0a 41 4e 44 20 49 73  44 69 66 66 65 72 65 6e  |..AND IsDifferen|
000010b0  63 65 4f 66 50 6f 77 65  72 73 28 6b 2c 20 70 29  |ceOfPowers(k, p)|
000010c0  20 3d 20 56 41 4c 4f 46  0a 7b 20 20 4c 45 54 20  | = VALOF.{  LET |
000010d0  6e 20 3d 20 4c 6f 77 42  69 74 28 6b 2b 31 29 2b  |n = LowBit(k+1)+|
000010e0  31 3b 0a 20 20 20 4c 45  54 20 6d 20 3d 20 4c 6f  |1;.   LET m = Lo|
000010f0  77 42 69 74 28 6b 2d 31  29 2d 31 3b 0a 0a 20 20  |wBit(k-1)-1;..  |
00001100  20 52 45 53 55 4c 54 49  53 09 20 20 49 73 50 6f  | RESULTIS.  IsPo|
00001110  77 65 72 4f 66 32 28 6b  2b 6e 29 20 2d 3e 20 6e  |werOf2(k+n) -> n|
00001120  2c 0a 09 09 20 20 49 73  50 6f 77 65 72 4f 66 32  |,...  IsPowerOf2|
00001130  28 6b 2b 6d 29 20 2d 3e  20 6d 2c 0a 09 09 09 20  |(k+m) -> m,.... |
00001140  20 20 20 20 20 70 3d 32  20 2d 3e 20 4e 75 6c 6c  |     p=2 -> Null|
00001150  2c 0a 49 73 53 75 6d 4f  72 44 69 66 66 65 72 65  |,.IsSumOrDiffere|
00001160  6e 63 65 4f 66 50 6f 77  65 72 73 4f 66 32 28 6b  |nceOfPowersOf2(k|
00001170  2b 6e 29 20 2d 3e 20 6e  2c 0a 49 73 53 75 6d 4f  |+n) -> n,.IsSumO|
00001180  72 44 69 66 66 65 72 65  6e 63 65 4f 66 50 6f 77  |rDifferenceOfPow|
00001190  65 72 73 4f 66 32 28 6b  2b 6d 29 20 2d 3e 20 6d  |ersOf2(k+m) -> m|
000011a0  2c 0a 09 09 09 09 20 20  20 20 20 4e 75 6c 6c 0a  |,.....     Null.|
000011b0  7d 0a 0a 41 4e 44 20 53  69 6d 70 6c 65 4d 75 6c  |}..AND SimpleMul|
000011c0  74 69 70 6c 79 28 72 65  73 2c 20 6b 2c 20 72 2c  |tiply(res, k, r,|
000011d0  20 64 65 66 65 72 53 68  69 66 74 29 20 42 45 0a  | deferShift) BE.|
000011e0  20 20 20 54 45 53 54 20  49 73 50 6f 77 65 72 4f  |   TEST IsPowerO|
000011f0  66 32 28 6b 29 20 54 48  45 4e 0a 20 20 20 20 20  |f2(k) THEN.     |
00001200  20 54 45 53 54 20 72 65  73 3d 72 20 26 20 64 65  | TEST res=r & de|
00001210  66 65 72 53 68 69 66 74  20 54 48 45 4e 0a 09 20  |ferShift THEN.. |
00001220  64 65 66 65 72 72 65 64  53 68 69 66 74 20 3a 3d  |deferredShift :=|
00001230  20 73 68 2e 61 73 6c 2a  33 32 2b 4c 6f 67 42 61  | sh.asl*32+LogBa|
00001240  73 65 32 28 6b 29 0a 20  20 20 20 20 20 45 4c 53  |se2(k).      ELS|
00001250  45 0a 09 20 53 68 69 66  74 52 65 67 69 73 74 65  |E.. ShiftRegiste|
00001260  72 44 53 28 72 65 73 2c  20 72 2c 20 73 68 2e 61  |rDS(res, r, sh.a|
00001270  73 6c 2c 20 4c 6f 67 42  61 73 65 32 28 6b 29 29  |sl, LogBase2(k))|
00001280  0a 20 20 20 45 4c 53 45  20 54 45 53 54 20 49 73  |.   ELSE TEST Is|
00001290  50 6f 77 65 72 4f 66 32  28 6b 2b 31 29 0a 20 20  |PowerOf2(k+1).  |
000012a0  20 20 20 20 54 48 45 4e  20 46 52 61 6e 64 53 68  |    THEN FRandSh|
000012b0  69 66 74 65 64 52 28 66  2e 72 73 62 2c 20 72 65  |iftedR(f.rsb, re|
000012c0  73 2c 20 72 2c 20 72 2c  20 6b 2b 31 29 0a 20 20  |s, r, r, k+1).  |
000012d0  20 45 4c 53 45 20 54 45  53 54 20 49 73 50 6f 77  | ELSE TEST IsPow|
000012e0  65 72 4f 66 32 28 6b 2d  31 29 0a 20 20 20 20 20  |erOf2(k-1).     |
000012f0  20 54 48 45 4e 20 46 52  61 6e 64 53 68 69 66 74  | THEN FRandShift|
00001300  65 64 52 28 66 2e 61 64  64 2c 20 72 65 73 2c 20  |edR(f.add, res, |
00001310  72 2c 20 72 2c 20 6b 2d  31 29 0a 20 20 20 20 20  |r, r, k-1).     |
00001320  20 45 4c 53 45 20 43 47  45 72 72 6f 72 28 46 41  | ELSE CGError(FA|
00001330  4c 53 45 2c 20 22 53 69  6d 70 6c 65 4d 75 6c 74  |LSE, "SimpleMult|
00001340  69 70 6c 79 20 77 72 6f  6e 67 6c 79 20 63 61 6c  |iply wrongly cal|
00001350  6c 65 64 20 28 6b 3d 25  6e 29 22 2c 20 6b 29 0a  |led (k=%n)", k).|
00001360  0a 0a 41 4e 44 20 43 47  4d 75 6c 74 28 29 20 42  |..AND CGMult() B|
00001370  45 0a 7b 20 20 4c 45 54  20 61 2c 20 62 20 3d 20  |E.{  LET a, b = |
00001380  61 72 67 31 2c 20 61 72  67 32 3b 0a 20 20 20 49  |arg1, arg2;.   I|
00001390  46 20 43 6c 61 73 73 28  61 72 67 31 2c 20 54 52  |F Class(arg1, TR|
000013a0  55 45 29 20 3c 20 43 6c  61 73 73 28 61 72 67 32  |UE) < Class(arg2|
000013b0  2c 20 54 52 55 45 29 20  54 48 45 4e 0a 20 20 20  |, TRUE) THEN.   |
000013c0  20 20 20 61 2c 20 62 20  3a 3d 20 61 72 67 32 2c  |   a, b := arg2,|
000013d0  20 61 72 67 31 3b 0a 20  20 20 64 65 66 65 72 72  | arg1;.   deferr|
000013e0  65 64 53 68 69 66 74 20  3a 3d 20 4e 75 6c 6c 3b  |edShift := Null;|
000013f0  0a 20 20 20 49 46 20 49  73 43 6f 6e 73 74 28 61  |.   IF IsConst(a|
00001400  29 20 54 48 45 4e 20 7b  0a 20 20 20 20 20 20 4c  |) THEN {.      L|
00001410  45 54 20 6b 20 3d 20 68  33 21 61 3b 0a 20 20 20  |ET k = h3!a;.   |
00001420  20 20 20 4c 45 54 20 72  20 3d 20 4e 75 6c 6c 3b  |   LET r = Null;|
00001430  0a 20 20 20 20 20 20 54  45 53 54 20 6b 3d 30 20  |.      TEST k=0 |
00001440  7c 20 49 73 43 6f 6e 73  74 28 62 29 20 54 48 45  || IsConst(b) THE|
00001450  4e 20 7b 0a 09 20 4c 45  54 20 6b 32 20 3d 20 68  |N {.. LET k2 = h|
00001460  33 21 62 3b 0a 09 20 53  74 61 63 6b 28 73 73 70  |3!b;.. Stack(ssp|
00001470  2d 32 29 3b 0a 09 20 4c  6f 61 64 28 6b 2e 6e 75  |-2);.. Load(k.nu|
00001480  6d 62 65 72 2c 20 6b 2a  6b 32 29 3b 0a 09 20 52  |mber, k*k2);.. R|
00001490  45 54 55 52 4e 20 7d 0a  0a 20 20 20 20 20 20 45  |ETURN }..      E|
000014a0  4c 53 45 20 54 45 53 54  20 6b 3d 31 20 54 48 45  |LSE TEST k=1 THE|
000014b0  4e 0a 20 20 20 20 20 20  7b 20 20 4c 45 54 20 74  |N.      {  LET t|
000014c0  2c 20 69 6e 64 2c 20 6e  2c 20 6b 20 3d 20 68 31  |, ind, n, k = h1|
000014d0  21 62 2c 20 68 32 21 62  2c 20 68 33 21 62 2c 20  |!b, h2!b, h3!b, |
000014e0  68 34 21 62 3b 0a 09 20  53 74 61 63 6b 28 73 73  |h4!b;.. Stack(ss|
000014f0  70 2d 31 29 3b 0a 09 20  68 31 21 61 72 67 31 2c  |p-1);.. h1!arg1,|
00001500  20 68 32 21 61 72 67 31  2c 20 68 33 21 61 72 67  | h2!arg1, h3!arg|
00001510  31 2c 20 68 34 21 61 72  67 31 20 3a 3d 20 74 2c  |1, h4!arg1 := t,|
00001520  20 69 6e 64 2c 20 6e 2c  20 6b 3b 0a 09 20 52 45  | ind, n, k;.. RE|
00001530  54 55 52 4e 20 7d 0a 0a  20 20 20 20 20 20 45 4c  |TURN }..      EL|
00001540  53 45 20 54 45 53 54 20  49 73 53 69 6d 70 6c 65  |SE TEST IsSimple|
00001550  4d 75 6c 74 69 70 6c 79  28 6b 29 20 54 48 45 4e  |Multiply(k) THEN|
00001560  20 7b 20 20 2f 2f 20 6d  75 6c 74 69 70 6c 65 72  | {  // multipler|
00001570  20 69 73 20 32 5e 6e 5b  2b 2d 31 5d 0a 09 20 4c  | is 2^n[+-1].. L|
00001580  45 54 20 73 20 3d 20 3f  3b 0a 09 20 72 20 3a 3d  |ET s = ?;.. r :=|
00001590  20 46 69 6e 64 53 6f 75  72 63 65 41 6e 64 44 65  | FindSourceAndDe|
000015a0  73 74 69 6e 61 74 69 6f  6e 52 65 67 69 73 74 65  |stinationRegiste|
000015b0  72 73 28 40 73 2c 20 62  2c 20 46 41 4c 53 45 29  |rs(@s, b, FALSE)|
000015c0  3b 0a 09 20 53 69 6d 70  6c 65 4d 75 6c 74 69 70  |;.. SimpleMultip|
000015d0  6c 79 28 72 2c 20 6b 2c  20 73 2c 20 54 52 55 45  |ly(r, k, s, TRUE|
000015e0  29 3b 0a 09 20 55 6e 4c  6f 63 6b 28 73 2c 20 6b  |);.. UnLock(s, k|
000015f0  2e 72 65 67 29 20 7d 0a  0a 20 20 20 20 20 20 45  |.reg) }..      E|
00001600  4c 53 45 20 54 45 53 54  20 54 77 6f 49 6e 73 74  |LSE TEST TwoInst|
00001610  72 75 63 74 69 6f 6e 4d  75 6c 74 69 70 6c 79 28  |ructionMultiply(|
00001620  6b 2c 20 62 29 20 54 48  45 4e 0a 09 20 72 20 3a  |k, b) THEN.. r :|
00001630  3d 20 72 65 67 69 73 74  65 72 46 6f 72 4d 75 6c  |= registerForMul|
00001640  74 69 70 6c 79 0a 0a 20  20 20 20 20 20 45 4c 53  |tiply..      ELS|
00001650  45 20 54 45 53 54 20 28  6b 26 31 29 3d 30 20 26  |E TEST (k&1)=0 &|
00001660  20 54 77 6f 49 6e 73 74  72 75 63 74 69 6f 6e 4d  | TwoInstructionM|
00001670  75 6c 74 69 70 6c 79 28  6b 2f 4c 6f 77 42 69 74  |ultiply(k/LowBit|
00001680  28 6b 29 2c 20 62 29 20  54 48 45 4e 20 7b 0a 09  |(k), b) THEN {..|
00001690  20 72 20 3a 3d 20 72 65  67 69 73 74 65 72 46 6f  | r := registerFo|
000016a0  72 4d 75 6c 74 69 70 6c  79 3b 0a 09 20 53 69 6d  |rMultiply;.. Sim|
000016b0  70 6c 65 4d 75 6c 74 69  70 6c 79 28 72 2c 20 4c  |pleMultiply(r, L|
000016c0  6f 77 42 69 74 28 6b 29  2c 20 72 2c 20 54 52 55  |owBit(k), r, TRU|
000016d0  45 29 20 7d 0a 0a 20 20  20 20 20 20 45 4c 53 45  |E) }..      ELSE|
000016e0  20 7b 0a 09 20 4c 45 54  20 6e 20 3d 20 44 69 76  | {.. LET n = Div|
000016f0  42 79 50 6f 77 65 72 4f  66 32 6d 69 6e 75 73 31  |ByPowerOf2minus1|
00001700  28 6b 29 3b 0a 09 20 49  46 20 6e 7e 3d 4e 75 6c  |(k);.. IF n~=Nul|
00001710  6c 20 26 20 54 77 6f 49  6e 73 74 72 75 63 74 69  |l & TwoInstructi|
00001720  6f 6e 4d 75 6c 74 69 70  6c 79 28 6b 2f 6e 2c 20  |onMultiply(k/n, |
00001730  62 29 20 54 48 45 4e 20  7b 0a 09 20 20 20 20 72  |b) THEN {..    r|
00001740  20 3a 3d 20 72 65 67 69  73 74 65 72 46 6f 72 4d  | := registerForM|
00001750  75 6c 74 69 70 6c 79 3b  0a 09 20 20 20 20 53 69  |ultiply;..    Si|
00001760  6d 70 6c 65 4d 75 6c 74  69 70 6c 79 28 72 2c 20  |mpleMultiply(r, |
00001770  6e 2c 20 72 2c 20 46 41  4c 53 45 29 3b 0a 09 20  |n, r, FALSE);.. |
00001780  20 20 20 47 4f 54 4f 20  64 6f 6e 65 20 7d 3b 0a  |   GOTO done };.|
00001790  0a 09 20 6e 20 3a 3d 20  44 69 76 42 79 50 6f 77  |.. n := DivByPow|
000017a0  65 72 4f 66 32 70 6c 75  73 31 28 6b 29 3b 0a 09  |erOf2plus1(k);..|
000017b0  20 49 46 20 6e 7e 3d 4e  75 6c 6c 20 26 20 54 77  | IF n~=Null & Tw|
000017c0  6f 49 6e 73 74 72 75 63  74 69 6f 6e 4d 75 6c 74  |oInstructionMult|
000017d0  69 70 6c 79 28 6b 2f 6e  2c 20 62 29 20 54 48 45  |iply(k/n, b) THE|
000017e0  4e 20 7b 0a 09 20 20 20  20 72 20 3a 3d 20 72 65  |N {..    r := re|
000017f0  67 69 73 74 65 72 46 6f  72 4d 75 6c 74 69 70 6c  |gisterForMultipl|
00001800  79 3b 0a 09 20 20 20 20  53 69 6d 70 6c 65 4d 75  |y;..    SimpleMu|
00001810  6c 74 69 70 6c 79 28 72  2c 20 6e 2c 20 72 2c 20  |ltiply(r, n, r, |
00001820  46 41 4c 53 45 29 3b 0a  09 20 20 20 20 47 4f 54  |FALSE);..    GOT|
00001830  4f 20 64 6f 6e 65 20 7d  3b 0a 0a 09 20 6e 20 3a  |O done };... n :|
00001840  3d 20 49 73 53 75 6d 4f  66 50 6f 77 65 72 73 28  |= IsSumOfPowers(|
00001850  6b 2c 20 33 29 3b 0a 09  20 49 46 20 6e 7e 3d 4e  |k, 3);.. IF n~=N|
00001860  75 6c 6c 20 54 48 45 4e  20 7b 0a 09 20 20 20 20  |ull THEN {..    |
00001870  4c 45 54 20 73 20 3d 20  3f 3b 0a 09 20 20 20 20  |LET s = ?;..    |
00001880  4c 45 54 20 72 20 3d 20  46 69 6e 64 53 6f 75 72  |LET r = FindSour|
00001890  63 65 41 6e 64 44 65 73  74 69 6e 61 74 69 6f 6e  |ceAndDestination|
000018a0  52 65 67 69 73 74 65 72  73 28 40 73 2c 20 62 2c  |Registers(@s, b,|
000018b0  20 54 52 55 45 29 3b 0a  09 20 20 20 20 53 69 6d  | TRUE);..    Sim|
000018c0  70 6c 65 4d 75 6c 74 69  70 6c 79 28 72 2c 20 6e  |pleMultiply(r, n|
000018d0  2c 20 73 2c 20 46 41 4c  53 45 29 3b 0a 09 20 20  |, s, FALSE);..  |
000018e0  20 20 46 52 61 6e 64 53  68 69 66 74 65 64 52 28  |  FRandShiftedR(|
000018f0  73 65 63 6f 6e 64 4f 70  2c 20 72 2c 20 72 2c 20  |secondOp, r, r, |
00001900  73 2c 20 73 65 63 6f 6e  64 4d 75 6c 74 69 70 6c  |s, secondMultipl|
00001910  69 65 72 29 0a 09 20 20  20 20 46 52 61 6e 64 53  |ier)..    FRandS|
00001920  68 69 66 74 65 64 52 28  73 65 63 6f 6e 64 4f 70  |hiftedR(secondOp|
00001930  2c 20 72 2c 20 72 2c 20  73 2c 20 74 68 69 72 64  |, r, r, s, third|
00001940  4d 75 6c 74 69 70 6c 69  65 72 29 0a 09 20 20 20  |Multiplier)..   |
00001950  20 55 6e 6c 6f 63 6b 28  72 2c 20 6b 2e 72 65 67  | Unlock(r, k.reg|
00001960  29 3b 20 55 6e 6c 6f 63  6b 28 73 2c 20 6b 2e 72  |); Unlock(s, k.r|
00001970  65 67 29 3b 0a 09 20 20  20 20 47 4f 54 4f 20 64  |eg);..    GOTO d|
00001980  6f 6e 65 20 7d 3b 0a 0a  09 20 6e 20 3a 3d 20 49  |one };... n := I|
00001990  73 44 69 66 66 65 72 65  6e 63 65 4f 66 50 6f 77  |sDifferenceOfPow|
000019a0  65 72 73 28 6b 2c 20 33  29 3b 0a 09 20 49 46 20  |ers(k, 3);.. IF |
000019b0  6e 7e 3d 4e 75 6c 6c 20  54 48 45 4e 20 7b 0a 09  |n~=Null THEN {..|
000019c0  20 20 20 20 4c 45 54 20  73 20 3d 20 3f 3b 0a 09  |    LET s = ?;..|
000019d0  20 20 20 20 4c 45 54 20  72 20 3d 20 46 69 6e 64  |    LET r = Find|
000019e0  53 6f 75 72 63 65 41 6e  64 44 65 73 74 69 6e 61  |SourceAndDestina|
000019f0  74 69 6f 6e 52 65 67 69  73 74 65 72 73 28 40 73  |tionRegisters(@s|
00001a00  2c 20 62 2c 20 54 52 55  45 29 3b 0a 09 20 20 20  |, b, TRUE);..   |
00001a10  20 53 69 6d 70 6c 65 4d  75 6c 74 69 70 6c 79 28  | SimpleMultiply(|
00001a20  72 2c 20 6e 2c 20 73 2c  20 46 41 4c 53 45 29 3b  |r, n, s, FALSE);|
00001a30  0a 09 20 20 20 20 46 52  61 6e 64 53 68 69 66 74  |..    FRandShift|
00001a40  65 64 52 28 28 73 65 63  6f 6e 64 4f 70 3d 66 2e  |edR((secondOp=f.|
00001a50  72 73 62 20 2d 3e 20 66  2e 61 64 64 2c 20 66 2e  |rsb -> f.add, f.|
00001a60  72 73 62 29 2c 0a 09 09  09 20 20 72 2c 20 72 2c  |rsb),....  r, r,|
00001a70  20 73 2c 20 73 65 63 6f  6e 64 4d 75 6c 74 69 70  | s, secondMultip|
00001a80  6c 69 65 72 29 0a 09 20  20 20 20 46 52 61 6e 64  |lier)..    FRand|
00001a90  53 68 69 66 74 65 64 52  28 73 65 63 6f 6e 64 4f  |ShiftedR(secondO|
00001aa0  70 2c 20 72 2c 20 72 2c  20 73 2c 20 74 68 69 72  |p, r, r, s, thir|
00001ab0  64 4d 75 6c 74 69 70 6c  69 65 72 29 0a 09 20 20  |dMultiplier)..  |
00001ac0  20 20 55 6e 6c 6f 63 6b  28 72 2c 20 6b 2e 72 65  |  Unlock(r, k.re|
00001ad0  67 29 3b 20 55 6e 6c 6f  63 6b 28 73 2c 20 6b 2e  |g); Unlock(s, k.|
00001ae0  72 65 67 29 20 7d 20 7d  3b 0a 0a 64 6f 6e 65 3a  |reg) } };..done:|
00001af0  0a 20 20 20 20 20 20 49  46 20 72 7e 3d 4e 75 6c  |.      IF r~=Nul|
00001b00  6c 20 54 48 45 4e 0a 20  20 20 20 20 20 7b 20 20  |l THEN.      {  |
00001b10  4c 6f 73 65 52 28 72 2c  20 64 65 66 65 72 72 65  |LoseR(r, deferre|
00001b20  64 53 68 69 66 74 29 3b  0a 09 20 52 45 54 55 52  |dShift);.. RETUR|
00001b30  4e 20 7d 20 7d 3b 0a 0a  20 20 20 7b 20 20 4c 45  |N } };..   {  LE|
00001b40  54 20 73 20 3d 20 3f 3b  0a 20 20 20 20 20 20 4c  |T s = ?;.      L|
00001b50  45 54 20 72 20 3d 20 46  69 6e 64 53 6f 75 72 63  |ET r = FindSourc|
00001b60  65 41 6e 64 44 65 73 74  69 6e 61 74 69 6f 6e 52  |eAndDestinationR|
00001b70  65 67 69 73 74 65 72 73  28 40 73 2c 20 62 2c 20  |egisters(@s, b, |
00001b80  46 41 4c 53 45 29 3b 0a  20 20 20 20 20 20 4c 45  |FALSE);.      LE|
00001b90  54 20 72 32 20 3d 20 3f  3b 0a 20 20 20 20 20 20  |T r2 = ?;.      |
00001ba0  46 6c 75 73 68 50 65 6e  64 69 6e 67 55 73 65 73  |FlushPendingUses|
00001bb0  4f 66 52 65 67 28 72 29  3b 0a 20 20 20 20 20 20  |OfReg(r);.      |
00001bc0  4c 6f 63 6b 28 73 2c 20  6b 2e 72 65 67 29 3b 0a  |Lock(s, k.reg);.|
00001bd0  20 20 20 20 20 20 72 32  20 3a 3d 20 4d 6f 76 65  |      r2 := Move|
00001be0  54 6f 41 6e 79 43 52 28  61 29 3b 0a 20 20 20 20  |ToAnyCR(a);.    |
00001bf0  20 20 49 46 20 72 20 3d  20 72 32 20 3d 20 73 20  |  IF r = r2 = s |
00001c00  54 48 45 4e 20 7b 0a 09  20 72 32 20 3a 3d 20 4e  |THEN {.. r2 := N|
00001c10  65 78 74 52 28 29 3b 0a  09 20 4d 6f 76 65 54 6f  |extR();.. MoveTo|
00001c20  52 28 72 32 2c 20 61 29  20 7d 3b 0a 20 20 20 20  |R(r2, a) };.    |
00001c30  20 20 49 46 20 72 3d 73  20 54 48 45 4e 20 7b 20  |  IF r=s THEN { |
00001c40  4c 45 54 20 74 65 6d 70  20 3d 20 73 3b 20 73 20  |LET temp = s; s |
00001c50  3a 3d 20 72 32 3b 20 72  32 20 3a 3d 20 74 65 6d  |:= r2; r2 := tem|
00001c60  70 20 7d 3b 0a 20 20 20  20 20 20 4d 75 6c 74 69  |p };.      Multi|
00001c70  70 6c 79 49 6e 73 74 28  66 2e 6d 75 6c 2c 20 72  |plyInst(f.mul, r|
00001c80  2c 20 73 2c 20 72 32 2c  20 30 29 3b 0a 20 20 20  |, s, r2, 0);.   |
00001c90  20 20 20 4c 6f 73 65 28  72 2c 20 6b 2e 72 65 67  |   Lose(r, k.reg|
00001ca0  29 3b 0a 20 20 20 20 20  20 55 6e 4c 6f 63 6b 28  |);.      UnLock(|
00001cb0  73 2c 20 6b 2e 72 65 67  29 20 7d 0a 7d 0a 0a 41  |s, k.reg) }.}..A|
00001cc0  4e 44 20 43 61 6c 6c 41  72 69 74 68 6d 65 74 69  |ND CallArithmeti|
00001cd0  63 52 6f 75 74 69 6e 65  28 6f 66 66 73 65 74 2c  |cRoutine(offset,|
00001ce0  20 61 31 2c 20 61 32 2c  20 72 65 73 29 20 42 45  | a1, a2, res) BE|
00001cf0  0a 7b 20 20 4d 6f 76 65  54 6f 52 28 41 72 67 75  |.{  MoveToR(Argu|
00001d00  6d 65 6e 74 52 65 67 69  73 74 65 72 28 31 29 2c  |mentRegister(1),|
00001d10  20 61 31 29 3b 0a 20 20  20 4d 6f 76 65 54 6f 52  | a1);.   MoveToR|
00001d20  28 41 72 67 75 6d 65 6e  74 52 65 67 69 73 74 65  |(ArgumentRegiste|
00001d30  72 28 32 29 2c 20 61 32  29 3b 0a 20 20 20 46 6c  |r(2), a2);.   Fl|
00001d40  75 73 68 50 65 6e 64 69  6e 67 55 73 65 73 4f 66  |ushPendingUsesOf|
00001d50  52 65 67 28 41 72 67 75  6d 65 6e 74 52 65 67 69  |Reg(ArgumentRegi|
00001d60  73 74 65 72 28 31 29 29  3b 0a 20 20 20 46 6c 75  |ster(1));.   Flu|
00001d70  73 68 50 65 6e 64 69 6e  67 55 73 65 73 4f 66 52  |shPendingUsesOfR|
00001d80  65 67 28 41 72 67 75 6d  65 6e 74 52 65 67 69 73  |eg(ArgumentRegis|
00001d90  74 65 72 28 32 29 29 3b  0a 20 20 20 46 6c 75 73  |ter(2));.   Flus|
00001da0  68 50 65 6e 64 69 6e 67  55 73 65 73 4f 66 52 65  |hPendingUsesOfRe|
00001db0  67 28 72 2e 31 34 29 3b  0a 20 20 20 54 45 53 54  |g(r.14);.   TEST|
00001dc0  20 43 6f 6d 70 61 63 74  43 6f 64 65 20 54 48 45  | CompactCode THE|
00001dd0  4e 0a 20 20 20 20 20 20  46 35 49 6e 73 74 4c 28  |N.      F5InstL(|
00001de0  6d 2e 61 6c 77 61 79 73  2c 20 28 6f 66 66 73 65  |m.always, (offse|
00001df0  74 3d 73 72 2e 6d 75 6c  74 69 70 6c 79 20 2d 3e  |t=sr.multiply ->|
00001e00  20 4d 75 6c 74 4c 61 62  2c 20 51 75 6f 74 4c 61  | MultLab, QuotLa|
00001e10  62 29 2c 20 66 2e 62 6c  29 0a 20 20 20 45 4c 53  |b), f.bl).   ELS|
00001e20  45 0a 20 20 20 20 20 20  43 61 6c 6c 53 75 62 28  |E.      CallSub(|
00001e30  6f 66 66 73 65 74 29 3b  0a 20 20 20 44 69 73 63  |offset);.   Disc|
00001e40  61 72 64 52 65 67 28 41  72 67 75 6d 65 6e 74 52  |ardReg(ArgumentR|
00001e50  65 67 69 73 74 65 72 28  31 29 2c 20 6b 2e 72 65  |egister(1), k.re|
00001e60  67 29 3b 0a 20 20 20 44  69 73 63 61 72 64 52 65  |g);.   DiscardRe|
00001e70  67 28 41 72 67 75 6d 65  6e 74 52 65 67 69 73 74  |g(ArgumentRegist|
00001e80  65 72 28 32 29 2c 20 6b  2e 72 65 67 29 3b 0a 20  |er(2), k.reg);. |
00001e90  20 20 44 69 73 63 61 72  64 52 65 67 28 72 2e 31  |  DiscardReg(r.1|
00001ea0  34 2c 20 6b 2e 72 65 67  29 3b 0a 20 20 20 4c 6f  |4, k.reg);.   Lo|
00001eb0  73 65 28 41 72 67 75 6d  65 6e 74 52 65 67 69 73  |se(ArgumentRegis|
00001ec0  74 65 72 28 72 65 73 29  2c 20 6b 2e 72 65 67 29  |ter(res), k.reg)|
00001ed0  0a 7d 0a 0a 41 4e 44 20  43 47 4d 69 6e 75 73 28  |.}..AND CGMinus(|
00001ee0  29 20 42 45 0a 20 20 20  54 45 53 54 20 49 73 43  |) BE.   TEST IsC|
00001ef0  6f 6e 73 74 28 61 72 67  31 29 20 54 48 45 4e 20  |onst(arg1) THEN |
00001f00  7b 0a 20 20 20 20 20 20  68 33 21 61 72 67 31 20  |{.      h3!arg1 |
00001f10  3a 3d 20 2d 68 33 21 61  72 67 31 3b 0a 20 20 20  |:= -h3!arg1;.   |
00001f20  20 20 20 43 47 50 6c 75  73 28 29 20 7d 0a 20 20  |   CGPlus() }.  |
00001f30  20 45 4c 53 45 20 7b 0a  20 20 20 20 20 20 4c 45  | ELSE {.      LE|
00001f40  54 20 66 2c 20 78 2c 20  79 20 3d 20 66 2e 73 75  |T f, x, y = f.su|
00001f50  62 2c 20 61 72 67 31 2c  20 61 72 67 32 3b 0a 20  |b, arg1, arg2;. |
00001f60  20 20 20 20 20 4c 45 54  20 72 2c 20 73 20 3d 20  |     LET r, s = |
00001f70  3f 2c 20 3f 3b 0a 20 20  20 20 20 20 49 46 20 43  |?, ?;.      IF C|
00001f80  6c 61 73 73 28 78 2c 20  54 52 55 45 29 20 3c 20  |lass(x, TRUE) < |
00001f90  43 6c 61 73 73 28 79 2c  20 54 52 55 45 29 20 54  |Class(y, TRUE) T|
00001fa0  48 45 4e 0a 09 20 66 2c  20 78 2c 20 79 20 3a 3d  |HEN.. f, x, y :=|
00001fb0  20 66 2e 72 73 62 2c 20  61 72 67 32 2c 20 61 72  | f.rsb, arg2, ar|
00001fc0  67 31 3b 0a 20 20 20 20  20 20 72 20 3a 3d 20 46  |g1;.      r := F|
00001fd0  69 6e 64 53 6f 75 72 63  65 41 6e 64 44 65 73 74  |indSourceAndDest|
00001fe0  69 6e 61 74 69 6f 6e 52  65 67 69 73 74 65 72 73  |inationRegisters|
00001ff0  28 40 73 2c 20 79 2c 20  46 41 4c 53 45 29 3b 0a  |(@s, y, FALSE);.|
00002000  20 20 20 20 20 20 47 65  6e 46 44 53 28 66 2c 20  |      GenFDS(f, |
00002010  72 2c 20 73 2c 20 78 29  3b 0a 20 20 20 20 20 20  |r, s, x);.      |
00002020  4c 6f 73 65 28 72 2c 20  6b 2e 72 65 67 29 3b 0a  |Lose(r, k.reg);.|
00002030  20 20 20 20 20 20 55 6e  4c 6f 63 6b 28 73 2c 20  |      UnLock(s, |
00002040  6b 2e 72 65 67 29 20 7d  0a 0a 41 4e 44 20 43 47  |k.reg) }..AND CG|
00002050  50 6c 75 73 28 29 20 42  45 0a 7b 20 20 49 46 20  |Plus() BE.{  IF |
00002060  49 73 63 6f 6e 73 74 28  61 72 67 32 29 20 54 48  |Isconst(arg2) TH|
00002070  45 4e 0a 20 20 20 20 20  20 53 77 61 70 53 53 28  |EN.      SwapSS(|
00002080  61 72 67 31 2c 20 61 72  67 32 29 3b 0a 0a 20 20  |arg1, arg2);..  |
00002090  20 49 46 20 49 73 43 6f  6e 73 74 28 61 72 67 31  | IF IsConst(arg1|
000020a0  29 20 26 20 68 31 21 61  72 67 32 7e 3d 6b 2e 73  |) & h1!arg2~=k.s|
000020b0  68 72 65 67 20 54 48 45  4e 0a 20 20 20 7b 20 20  |hreg THEN.   {  |
000020c0  4c 45 54 20 6b 20 3d 20  68 33 21 61 72 67 31 3b  |LET k = h3!arg1;|
000020d0  0a 20 20 20 20 20 20 49  46 20 6b 7e 3d 30 20 54  |.      IF k~=0 T|
000020e0  48 45 4e 0a 20 20 20 20  20 20 7b 20 20 49 46 20  |HEN.      {  IF |
000020f0  68 32 21 61 72 67 32 3e  3d 30 20 54 48 45 4e 20  |h2!arg2>=0 THEN |
00002100  4d 6f 76 65 54 6f 41 6e  79 52 28 61 72 67 32 29  |MoveToAnyR(arg2)|
00002110  3b 0a 09 20 68 34 21 61  72 67 32 20 3a 3d 20 68  |;.. h4!arg2 := h|
00002120  34 21 61 72 67 32 2b 6b  20 7d 3b 0a 20 20 20 20  |4!arg2+k };.    |
00002130  20 20 49 73 43 6f 6e 73  74 28 61 72 67 32 29 3b  |  IsConst(arg2);|
00002140  0a 20 20 20 20 20 20 53  74 61 63 6b 28 73 73 70  |.      Stack(ssp|
00002150  2d 31 29 3b 0a 20 20 20  20 20 20 52 45 54 55 52  |-1);.      RETUR|
00002160  4e 20 7d 3b 0a 0a 20 20  20 7b 20 20 4c 45 54 20  |N };..   {  LET |
00002170  4e 65 78 74 4f 70 20 3d  20 50 65 65 6b 4e 28 29  |NextOp = PeekN()|
00002180  3b 0a 20 20 20 20 20 20  54 45 53 54 20 4e 65 78  |;.      TEST Nex|
00002190  74 4f 70 3d 73 2e 72 76  20 54 48 45 4e 20 7b 0a  |tOp=s.rv THEN {.|
000021a0  09 20 43 47 56 65 63 61  70 28 29 3b 20 52 45 54  |. CGVecap(); RET|
000021b0  55 52 4e 20 7d 0a 20 20  20 20 20 20 45 4c 53 45  |URN }.      ELSE|
000021c0  20 49 46 20 4e 65 78 74  4f 70 3d 73 2e 73 74 69  | IF NextOp=s.sti|
000021d0  6e 64 20 54 48 45 4e 20  7b 0a 09 20 43 47 56 65  |nd THEN {.. CGVe|
000021e0  63 53 74 28 29 3b 20 52  45 54 55 52 4e 20 7d 20  |cSt(); RETURN } |
000021f0  7d 3b 0a 0a 20 20 20 7b  20 20 4c 45 54 20 78 2c  |};..   {  LET x,|
00002200  20 79 20 3d 20 61 72 67  31 2c 20 61 72 67 32 3b  | y = arg1, arg2;|
00002210  0a 20 20 20 20 20 20 4c  45 54 20 72 2c 20 73 20  |.      LET r, s |
00002220  3d 20 3f 2c 20 3f 3b 0a  20 20 20 20 20 20 4c 45  |= ?, ?;.      LE|
00002230  54 20 6b 20 3d 20 30 3b  0a 20 20 20 20 20 20 49  |T k = 0;.      I|
00002240  46 20 68 32 21 61 72 67  31 3c 30 20 26 20 68 31  |F h2!arg1<0 & h1|
00002250  21 61 72 67 31 7e 3d 6b  2e 73 68 72 65 67 20 54  |!arg1~=k.shreg T|
00002260  48 45 4e 20 7b 20 20 6b  20 3a 3d 20 68 34 21 61  |HEN {  k := h4!a|
00002270  72 67 31 3b 20 68 34 21  61 72 67 31 20 3a 3d 20  |rg1; h4!arg1 := |
00002280  30 20 7d 3b 0a 20 20 20  20 20 20 49 46 20 68 32  |0 };.      IF h2|
00002290  21 61 72 67 32 3c 30 20  26 20 68 31 21 61 72 67  |!arg2<0 & h1!arg|
000022a0  32 7e 3d 6b 2e 73 68 72  65 67 20 54 48 45 4e 20  |2~=k.shreg THEN |
000022b0  7b 20 20 6b 20 3a 3d 20  6b 2b 68 34 21 61 72 67  |{  k := k+h4!arg|
000022c0  32 3b 20 68 34 21 61 72  67 32 20 3a 3d 20 30 20  |2; h4!arg2 := 0 |
000022d0  7d 3b 0a 20 20 20 20 20  20 49 46 20 43 6c 61 73  |};.      IF Clas|
000022e0  73 28 78 2c 20 54 52 55  45 29 3c 43 6c 61 73 73  |s(x, TRUE)<Class|
000022f0  28 79 2c 20 54 52 55 45  29 0a 09 20 54 48 45 4e  |(y, TRUE).. THEN|
00002300  20 78 2c 20 79 20 3a 3d  20 61 72 67 32 2c 20 61  | x, y := arg2, a|
00002310  72 67 31 3b 0a 20 20 20  20 20 20 72 20 3a 3d 20  |rg1;.      r := |
00002320  46 69 6e 64 53 6f 75 72  63 65 41 6e 64 44 65 73  |FindSourceAndDes|
00002330  74 69 6e 61 74 69 6f 6e  52 65 67 69 73 74 65 72  |tinationRegister|
00002340  73 28 40 73 2c 20 79 2c  20 46 41 4c 53 45 29 3b  |s(@s, y, FALSE);|
00002350  0a 20 20 20 20 20 20 47  65 6e 46 44 53 28 66 2e  |.      GenFDS(f.|
00002360  61 64 64 2c 20 72 2c 20  73 2c 20 78 29 3b 0a 20  |add, r, s, x);. |
00002370  20 20 20 20 20 4c 6f 73  65 28 72 2c 20 6b 2e 72  |     Lose(r, k.r|
00002380  65 67 29 3b 0a 20 20 20  20 20 20 68 34 21 61 72  |eg);.      h4!ar|
00002390  67 31 20 3a 3d 20 6b 3b  0a 20 20 20 20 20 20 55  |g1 := k;.      U|
000023a0  6e 4c 6f 63 6b 28 73 2c  20 6b 2e 72 65 67 29 20  |nLock(s, k.reg) |
000023b0  7d 0a 7d 0a 0a 41 4e 44  20 43 47 44 69 76 28 29  |}.}..AND CGDiv()|
000023c0  20 42 45 0a 7b 20 20 49  46 20 49 73 43 6f 6e 73  | BE.{  IF IsCons|
000023d0  74 28 61 72 67 31 29 20  54 48 45 4e 0a 20 20 20  |t(arg1) THEN.   |
000023e0  7b 20 20 4c 45 54 20 6e  20 3d 20 68 33 21 61 72  |{  LET n = h3!ar|
000023f0  67 31 3b 0a 20 20 20 20  20 20 49 46 20 6e 3d 31  |g1;.      IF n=1|
00002400  20 54 48 45 4e 20 7b 0a  09 20 53 74 61 63 6b 28  | THEN {.. Stack(|
00002410  73 73 70 2d 31 29 3b 0a  09 20 52 45 54 55 52 4e  |ssp-1);.. RETURN|
00002420  20 7d 3b 0a 0a 20 20 20  20 20 20 49 46 20 6e 3d  | };..      IF n=|
00002430  30 20 54 48 45 4e 20 7b  0a 09 20 43 47 45 72 72  |0 THEN {.. CGErr|
00002440  6f 72 28 46 41 4c 53 45  2c 20 22 43 6f 6d 70 69  |or(FALSE, "Compi|
00002450  6c 69 6e 67 20 64 69 76  69 73 69 6f 6e 20 62 79  |ling division by|
00002460  20 7a 65 72 6f 22 29 3b  0a 09 20 53 74 61 63 6b  | zero");.. Stack|
00002470  28 73 73 70 2d 32 29 3b  0a 09 20 4c 6f 61 64 28  |(ssp-2);.. Load(|
00002480  6b 2e 6e 75 6d 62 65 72  2c 20 30 29 3b 0a 09 20  |k.number, 0);.. |
00002490  52 45 54 55 52 4e 20 7d  3b 0a 0a 20 20 20 20 20  |RETURN };..     |
000024a0  20 49 46 20 49 73 43 6f  6e 73 74 28 61 72 67 32  | IF IsConst(arg2|
000024b0  29 20 54 48 45 4e 0a 20  20 20 20 20 20 7b 20 20  |) THEN.      {  |
000024c0  4c 45 54 20 6b 20 3d 20  68 33 21 61 72 67 32 3b  |LET k = h3!arg2;|
000024d0  0a 09 20 53 74 61 63 6b  28 73 73 70 2d 32 29 3b  |.. Stack(ssp-2);|
000024e0  0a 09 20 4c 6f 61 64 28  6b 2e 6e 75 6d 62 65 72  |.. Load(k.number|
000024f0  2c 20 6b 2f 6e 29 3b 0a  09 20 52 45 54 55 52 4e  |, k/n);.. RETURN|
00002500  20 7d 3b 0a 0a 20 20 20  20 20 20 49 46 20 5b 6e  | };..      IF [n|
00002510  26 28 2d 6e 29 5d 3d 6e  20 54 48 45 4e 0a 20 20  |&(-n)]=n THEN.  |
00002520  20 20 20 20 7b 20 20 4c  45 54 20 73 20 3d 20 3f  |    {  LET s = ?|
00002530  3b 0a 09 20 4c 45 54 20  72 20 3d 20 46 69 6e 64  |;.. LET r = Find|
00002540  53 6f 75 72 63 65 41 6e  64 44 65 73 74 69 6e 61  |SourceAndDestina|
00002550  74 69 6f 6e 52 65 67 69  73 74 65 72 73 28 40 73  |tionRegisters(@s|
00002560  2c 20 61 72 67 32 2c 20  46 41 4c 53 45 29 3b 0a  |, arg2, FALSE);.|
00002570  09 20 47 65 6e 52 52 28  66 2e 6d 6f 76 73 2c 20  |. GenRR(f.movs, |
00002580  72 2c 20 30 2c 20 73 29  3b 0a 09 20 54 45 53 54  |r, 0, s);.. TEST|
00002590  20 6e 3d 32 20 54 48 45  4e 20 7b 0a 09 20 20 20  | n=2 THEN {..   |
000025a0  20 46 31 49 6e 73 74 28  66 2e 73 75 62 2c 20 72  | F1Inst(f.sub, r|
000025b0  2c 20 73 2c 20 73 2c 20  30 2c 20 73 68 2e 61 73  |, s, s, 0, sh.as|
000025c0  72 2c 20 31 2c 20 6d 2e  6d 69 29 0a 09 20 20 20  |r, 1, m.mi)..   |
000025d0  20 46 31 49 6e 73 74 28  66 2e 6d 6f 76 2c 20 72  | F1Inst(f.mov, r|
000025e0  2c 20 30 2c 20 73 2c 20  30 2c 20 73 68 2e 61 73  |, 0, s, 0, sh.as|
000025f0  72 2c 20 31 2c 20 6d 2e  70 6c 29 20 7d 0a 09 20  |r, 1, m.pl) }.. |
00002600  45 4c 53 45 20 7b 0a 09  20 20 20 20 46 31 49 6e  |ELSE {..    F1In|
00002610  73 74 28 66 2e 72 73 62  2c 20 72 2c 20 72 2c 20  |st(f.rsb, r, r, |
00002620  4e 75 6c 6c 2c 20 30 2c  20 4e 75 6c 6c 2c 20 30  |Null, 0, Null, 0|
00002630  2c 20 6d 2e 6d 69 29 3b  0a 09 20 20 20 20 53 68  |, m.mi);..    Sh|
00002640  69 66 74 52 65 67 69 73  74 65 72 44 53 28 72 2c  |iftRegisterDS(r,|
00002650  20 72 2c 20 73 68 2e 61  73 72 2c 20 4c 6f 67 42  | r, sh.asr, LogB|
00002660  61 73 65 32 28 6e 29 29  3b 0a 09 20 20 20 20 46  |ase2(n));..    F|
00002670  31 49 6e 73 74 28 66 2e  72 73 62 2c 20 72 2c 20  |1Inst(f.rsb, r, |
00002680  72 2c 20 4e 75 6c 6c 2c  20 30 2c 20 4e 75 6c 6c  |r, Null, 0, Null|
00002690  2c 20 30 2c 20 6d 2e 6d  69 29 20 7d 3b 0a 09 20  |, 0, m.mi) };.. |
000026a0  4c 6f 73 65 52 28 72 2c  20 4e 75 6c 6c 29 3b 0a  |LoseR(r, Null);.|
000026b0  09 20 55 6e 4c 6f 63 6b  28 73 2c 20 6b 2e 72 65  |. UnLock(s, k.re|
000026c0  67 29 3b 0a 09 20 52 45  54 55 52 4e 20 7d 20 7d  |g);.. RETURN } }|
000026d0  3b 0a 0a 20 20 20 43 61  6c 6c 41 72 69 74 68 6d  |;..   CallArithm|
000026e0  65 74 69 63 52 6f 75 74  69 6e 65 28 73 72 2e 71  |eticRoutine(sr.q|
000026f0  75 6f 74 72 65 6d 2c 20  61 72 67 32 2c 20 61 72  |uotrem, arg2, ar|
00002700  67 31 2c 20 31 29 0a 7d  0a 0a 41 4e 44 20 43 47  |g1, 1).}..AND CG|
00002710  52 65 6d 28 29 20 42 45  0a 7b 20 20 49 46 20 49  |Rem() BE.{  IF I|
00002720  73 43 6f 6e 73 74 28 61  72 67 31 29 20 54 48 45  |sConst(arg1) THE|
00002730  4e 0a 20 20 20 7b 20 20  4c 45 54 20 6e 20 3d 20  |N.   {  LET n = |
00002740  68 33 21 61 72 67 31 3b  0a 20 20 20 20 20 20 4c  |h3!arg1;.      L|
00002750  45 54 20 6c 6f 77 62 69  74 20 3d 20 6e 20 26 20  |ET lowbit = n & |
00002760  28 2d 6e 29 3b 0a 0a 20  20 20 20 20 20 49 46 20  |(-n);..      IF |
00002770  6e 3d 31 20 7c 20 49 73  43 6f 6e 73 74 28 61 72  |n=1 | IsConst(ar|
00002780  67 32 29 20 54 48 45 4e  20 7b 0a 09 20 4c 45 54  |g2) THEN {.. LET|
00002790  20 6b 20 3d 20 68 33 21  61 72 67 32 3b 0a 09 20  | k = h3!arg2;.. |
000027a0  53 74 61 63 6b 28 73 73  70 2d 32 29 3b 0a 09 20  |Stack(ssp-2);.. |
000027b0  4c 6f 61 64 28 6b 2e 6e  75 6d 62 65 72 2c 20 6b  |Load(k.number, k|
000027c0  20 52 45 4d 20 6e 29 3b  0a 09 20 52 45 54 55 52  | REM n);.. RETUR|
000027d0  4e 20 7d 3b 0a 0a 20 20  20 20 20 20 49 46 20 6e  |N };..      IF n|
000027e0  3d 30 20 54 48 45 4e 20  7b 0a 09 20 43 47 45 72  |=0 THEN {.. CGEr|
000027f0  72 6f 72 28 46 41 4c 53  45 2c 20 22 43 6f 6d 70  |ror(FALSE, "Comp|
00002800  69 6c 69 6e 67 20 64 69  76 69 73 69 6f 6e 20 62  |iling division b|
00002810  79 20 7a 65 72 6f 22 29  3b 0a 09 20 53 74 61 63  |y zero");.. Stac|
00002820  6b 28 73 73 70 2d 32 29  3b 0a 09 20 4c 6f 61 64  |k(ssp-2);.. Load|
00002830  28 6b 2e 6e 75 6d 62 65  72 2c 20 30 29 3b 0a 09  |(k.number, 0);..|
00002840  20 52 45 54 55 52 4e 20  7d 3b 0a 0a 20 20 20 20  | RETURN };..    |
00002850  20 20 49 46 20 6c 6f 77  62 69 74 3d 6e 20 54 48  |  IF lowbit=n TH|
00002860  45 4e 0a 20 20 20 20 20  20 7b 20 20 4c 45 54 20  |EN.      {  LET |
00002870  73 20 3d 20 3f 3b 0a 09  20 4c 45 54 20 72 20 3d  |s = ?;.. LET r =|
00002880  20 46 69 6e 64 53 6f 75  72 63 65 41 6e 64 44 65  | FindSourceAndDe|
00002890  73 74 69 6e 61 74 69 6f  6e 52 65 67 69 73 74 65  |stinationRegiste|
000028a0  72 73 28 40 73 2c 20 61  72 67 32 2c 20 46 41 4c  |rs(@s, arg2, FAL|
000028b0  53 45 29 3b 0a 09 20 68  33 21 61 72 67 31 20 3a  |SE);.. h3!arg1 :|
000028c0  3d 20 6e 2d 31 3b 0a 09  20 43 6f 6d 70 61 72 65  |= n-1;.. Compare|
000028d0  41 67 61 69 6e 73 74 4b  28 73 2c 20 30 2c 20 6d  |AgainstK(s, 0, m|
000028e0  2e 6c 74 29 3b 0a 09 20  47 65 6e 46 44 53 28 66  |.lt);.. GenFDS(f|
000028f0  2e 61 6e 64 2c 20 72 2c  20 73 2c 20 61 72 67 31  |.and, r, s, arg1|
00002900  29 3b 0a 09 20 46 31 49  6e 73 74 28 66 2e 73 75  |);.. F1Inst(f.su|
00002910  62 2c 20 72 2c 20 72 2c  20 4e 75 6c 6c 2c 20 6e  |b, r, r, Null, n|
00002920  2c 20 4e 75 6c 6c 2c 20  30 2c 20 6d 2e 6c 74 29  |, Null, 0, m.lt)|
00002930  3b 0a 09 20 4c 6f 73 65  28 72 2c 20 6b 2e 72 65  |;.. Lose(r, k.re|
00002940  67 29 3b 0a 09 20 55 6e  4c 6f 63 6b 28 73 2c 20  |g);.. UnLock(s, |
00002950  6b 2e 72 65 67 29 3b 0a  09 20 52 45 54 55 52 4e  |k.reg);.. RETURN|
00002960  20 7d 20 7d 3b 0a 0a 20  20 20 43 61 6c 6c 41 72  | } };..   CallAr|
00002970  69 74 68 6d 65 74 69 63  52 6f 75 74 69 6e 65 28  |ithmeticRoutine(|
00002980  73 72 2e 71 75 6f 74 72  65 6d 2c 20 61 72 67 32  |sr.quotrem, arg2|
00002990  2c 20 61 72 67 31 2c 20  32 29 0a 7d 0a           |, arg1, 2).}.|
0000299d