Hi,
I am seaching for pTAL TNS instructuctions can be used to replace CODE
statement in TAL.
Thanks
|
|
0
|
|
|
|
Reply
|
shirishc81 (3)
|
2/28/2011 11:22:53 AM |
|
In article <ae49bf89-a5fc-40c0-bc8b-bddb810eff48@w6g2000vbo.googlegroups.com>, Shirish <shirishc81@gmail.com> wrote:
>Hi,
>
>I am seaching for pTAL TNS instructuctions can be used to replace CODE
>statement in TAL.
That depends entirely on what the CODE statement is. CODE allows the
programmer to insert assembly language instructions in a TAL program; without
knowing what those assembly language instructions are, it's impossible to tell
you how to replace them in pTAL.
|
|
0
|
|
|
|
Reply
|
spambait
|
2/28/2011 12:08:52 PM
|
|
Doug Miller wrote:
> In article <ae49bf89-a5fc-40c0-bc8b-bddb810eff48@w6g2000vbo.googlegroups.com>, Shirish <shirishc81@gmail.com> wrote:
>
>>Hi,
>>
>>I am seaching for pTAL TNS instructuctions can be used to replace CODE
>>statement in TAL.
>
>
> That depends entirely on what the CODE statement is. CODE allows the
> programmer to insert assembly language instructions in a TAL program; without
> knowing what those assembly language instructions are, it's impossible to tell
> you how to replace them in pTAL.
To amplify on what Doug said a little, the usual things that CODE statements were used for were identified and pTAL built-in routines were implemented for them, and most or all of them were then implemented in TAL, to make it easier to maintain a single source file for TAL or pTAL compilation.
You can find the list of those built-in routines in the pTAL Reference Manual, chapter 15. Look through that list of routines, and if you do not find a function that does what you need to do, post here again explaining more specifically what you are trying to do, and we will try to find a way to solve the problem.
|
|
0
|
|
|
|
Reply
|
Keith
|
2/28/2011 1:03:41 PM
|
|
On Feb 28, 1:03=A0pm, Keith Dick <kd...@acm.org> wrote:
> Doug Miller wrote:
> > In article <ae49bf89-a5fc-40c0-bc8b-bddb810ef...@w6g2000vbo.googlegroup=
s.com>, Shirish <shirish...@gmail.com> wrote:
>
> >>Hi,
>
> >>I am seaching for pTAL TNS instructuctions can be used to replace CODE
> >>statement in TAL.
>
> > That depends entirely on what the CODE statement is. CODE allows the
> > programmer to insert assembly language instructions in a TAL program; w=
ithout
> > knowing what those assembly language instructions are, it's impossible =
to tell
> > you how to replace them in pTAL.
>
> To amplify on what Doug said a little, the usual things that CODE stateme=
nts were used for were identified and pTAL built-in routines were implement=
ed for them, and most or all of them were then implemented in TAL, to make =
it easier to maintain a single source file for TAL or pTAL compilation.
>
> You can find the list of those built-in routines in the pTAL Reference Ma=
nual, chapter 15. =A0Look through that list of routines, and if you do not =
find a function that does what you need to do, post here again explaining m=
ore specifically what you are trying to do, and we will try to find a way t=
o solve the problem.
Thanks Keith/Dough,
I found the pTAL buid in routines in manual. Where can i get machine-
level instructions manual for CODE. Below are the CODE statment i am
looking to replace.
CODE (EXCH);
CODE (LADD; EXCH);
CODE (LADD);
CODE (LDIV; EXCH);
CODE(RDE; ANRI -%201; SETE);
CODE(RDE; ORRI %200);
CODE(ANRI -%41; SETE);
CODE (EXCH; LSUB);
CODE (LADD; EXCH);
CODE (LSUB);
CODE (CCL)
CODE (CCE);
CODE(QADD;QDWN 1);
CODE(QADD;QDWN 2;QUP 1);
CODE(QADD;QDWN 3;QUP 2);
CODE(QADD;QDWN 4;QUP 3);
CODE(QADD;QDWN 4;QDWN 1;QUP 4);
CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
CODE(CQA);
|
|
0
|
|
|
|
Reply
|
Shirish
|
3/1/2011 6:03:37 AM
|
|
On Mar 1, 5:03=A0pm, Shirish <shirish...@gmail.com> wrote:
> On Feb 28, 1:03=A0pm, Keith Dick <kd...@acm.org> wrote:
>
>
>
>
>
> > Doug Miller wrote:
> > > In article <ae49bf89-a5fc-40c0-bc8b-bddb810ef...@w6g2000vbo.googlegro=
ups.com>, Shirish <shirish...@gmail.com> wrote:
>
> > >>Hi,
>
> > >>I am seaching for pTAL TNS instructuctions can be used to replace COD=
E
> > >>statement in TAL.
>
> > > That depends entirely on what the CODE statement is. CODE allows the
> > > programmer to insert assembly language instructions in a TAL program;=
without
> > > knowing what those assembly language instructions are, it's impossibl=
e to tell
> > > you how to replace them in pTAL.
>
> > To amplify on what Doug said a little, the usual things that CODE state=
ments were used for were identified and pTAL built-in routines were impleme=
nted for them, and most or all of them were then implemented in TAL, to mak=
e it easier to maintain a single source file for TAL or pTAL compilation.
>
> > You can find the list of those built-in routines in the pTAL Reference =
Manual, chapter 15. =A0Look through that list of routines, and if you do no=
t find a function that does what you need to do, post here again explaining=
more specifically what you are trying to do, and we will try to find a way=
to solve the problem.
>
> Thanks Keith/Dough,
>
> I found the pTAL buid in routines in manual. Where can i get machine-
> level instructions manual for CODE. Below are the CODE statment i am
> looking to replace.
> CODE (EXCH);
> CODE (LADD; EXCH);
> CODE (LADD);
> CODE (LDIV; EXCH);
> CODE(RDE; ANRI -%201; SETE);
> CODE(RDE; ORRI %200);
> CODE(ANRI -%41; SETE);
> CODE (EXCH; LSUB);
> CODE (LADD; EXCH);
> CODE (LSUB);
> CODE (CCL)
> CODE (CCE);
> CODE(QADD;QDWN 1);
> CODE(QADD;QDWN 2;QUP 1);
> CODE(QADD;QDWN 3;QUP 2);
> CODE(QADD;QDWN 4;QUP 3);
> CODE(QADD;QDWN 4;QDWN 1;QUP 4);
> CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
> CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
> CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
> CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
> CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
> CODE(CQA);
Is there any documentation? What is the name of the procedure? Any
idea what it is trying to do? Any comments? Anything to help
understand? Is it in a program or a TCP (pathway) library module?
|
|
0
|
|
|
|
Reply
|
ghr
|
3/1/2011 9:05:56 AM
|
|
On Mar 1, 9:05=A0am, ghr <ghr1...@gmail.com> wrote:
> On Mar 1, 5:03=A0pm, Shirish <shirish...@gmail.com> wrote:
>
>
>
>
>
> > On Feb 28, 1:03=A0pm, Keith Dick <kd...@acm.org> wrote:
>
> > > Doug Miller wrote:
> > > > In article <ae49bf89-a5fc-40c0-bc8b-bddb810ef...@w6g2000vbo.googleg=
roups.com>, Shirish <shirish...@gmail.com> wrote:
>
> > > >>Hi,
>
> > > >>I am seaching for pTAL TNS instructuctions can be used to replace C=
ODE
> > > >>statement in TAL.
>
> > > > That depends entirely on what the CODE statement is. CODE allows th=
e
> > > > programmer to insert assembly language instructions in a TAL progra=
m; without
> > > > knowing what those assembly language instructions are, it's impossi=
ble to tell
> > > > you how to replace them in pTAL.
>
> > > To amplify on what Doug said a little, the usual things that CODE sta=
tements were used for were identified and pTAL built-in routines were imple=
mented for them, and most or all of them were then implemented in TAL, to m=
ake it easier to maintain a single source file for TAL or pTAL compilation.
>
> > > You can find the list of those built-in routines in the pTAL Referenc=
e Manual, chapter 15. =A0Look through that list of routines, and if you do =
not find a function that does what you need to do, post here again explaini=
ng more specifically what you are trying to do, and we will try to find a w=
ay to solve the problem.
>
> > Thanks Keith/Dough,
>
> > I found the pTAL buid in routines in manual. Where can i get machine-
> > level instructions manual for CODE. Below are the CODE statment i am
> > looking to replace.
> > CODE (EXCH);
> > CODE (LADD; EXCH);
> > CODE (LADD);
> > CODE (LDIV; EXCH);
> > CODE(RDE; ANRI -%201; SETE);
> > CODE(RDE; ORRI %200);
> > CODE(ANRI -%41; SETE);
> > CODE (EXCH; LSUB);
> > CODE (LADD; EXCH);
> > CODE (LSUB);
> > CODE (CCL)
> > CODE (CCE);
> > CODE(QADD;QDWN 1);
> > CODE(QADD;QDWN 2;QUP 1);
> > CODE(QADD;QDWN 3;QUP 2);
> > CODE(QADD;QDWN 4;QUP 3);
> > CODE(QADD;QDWN 4;QDWN 1;QUP 4);
> > CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
> > CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
> > CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
> > CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
> > CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
> > CODE(CQA);
>
> Is there any documentation? What is the name of the procedure? Any
> idea what it is trying to do? Any comments? Anything to help
> understand? Is it in a program or a TCP (pathway) library module?- Hide q=
uoted text -
>
> - Show quoted text -
Below ia some example code
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
?SECTION L^MUL
!----------------------------------------------------------------------!
! !
! MPMUL1 -- MULTIPLE PRECISION MULTIPLY BY ONE DIGIT
(WORD) !
! !
! COMPUTES: W :=3D U *
V !
! WHERE: N IS THE NUMBER OF DIGITS (WORDS) OF
PRECISION !
! OF W AND
U. !
! !
!----------------------------------------------------------------------!
PROC MPMUL1 (W, U, V, N);
INT .W; ! PRODUCT
INT .U; ! MULTIPLICAND
INT V; ! MULTIPLIER
INT N; ! NUMBER OF DIGITS OF W & U
BEGIN
ENTRY MPMUL1^V^C4^07^MAR^83;
MPMUL1^V^C4^07^MAR^83:
USE KARRY, I, FAST^V;
KARRY :=3D 0;
FAST^V :=3D V;
FOR I :=3D N DOWNTO 1 DO
BEGIN
STACK U[I] '*' FAST^V;
STACK KARRY;
DROP KARRY;
USE I^PLUS^1;
I^PLUS^1 :=3D I + 1;
CODE (LADD);
STORE W[I^PLUS^1];
DROP I^PLUS^1;
! The next bit of code does not check for overflow after adding
! 1, this can never happen as the following analogous example
! shows (using 'decimal digits' instead of 'word digits').
! If KARRY =3D 9 (maximum possible) and we multiply the 2 biggest
! digits together (9*9) the max possible value is 81+9 =3D 90
! which does not overflow above 99 and hence does not carry into
! the next position (is not >=3D 100).
IF $CARRY THEN
BEGIN
STACK 1;
CODE (LADD);
END;
USE KARRY;
STORE KARRY;
END;
DROP FAST^V, I;
W[1] :=3D KARRY;
DROP KARRY;
END; ! OF PROC MPMUL1 !
?PAGE
!----------------------------------------------------------------------!
! !
! MPMUL -- MULTIPLE PRECISION MULTIPLICATION
ROUTINE. !
! !
! COMPUTES: W :=3D U *
V; !
! WHERE: N IS THE NUMBER OF DIGITS (WORDS) OF PRECISION OF
U !
! M IS THE NUMBER OF DIGITS (WORDS) OF PRECISION OF
V !
! NOTE: W MUST HAVE N+M DIGITS OF
PRECISION. !
! !
!----------------------------------------------------------------------!
PROC MPMUL (W, U, V, N, M);
INT .W; ! PRODUCT
INT .U; ! MULTIPLICAND
INT .V; ! MULTIPLIER
INT N; ! NUMBER OF DIGITS IN U
INT M; ! NUMBER OF DIGITS IN V
BEGIN
INT J :=3D 0 , V^J :=3D 0 ;
ENTRY MPMULSUM;
ENTRY MPMUL^V^C4^07^MAR^83;
MPMUL^V^C4^07^MAR^83:
!MPMUL:!
W ':=3D' [0] & W FOR N+M-1;
MPMULSUM:
FOR J :=3D M DOWNTO 1 DO
BEGIN
V^J :=3D V[J];
USE KARRY, I^PLUS^J, I;
KARRY :=3D 0;
I^PLUS^J :=3D J + N;
FOR I :=3D N DOWNTO 1 DO
BEGIN
STACK U[I] '*' V^J;
STACK W[I^PLUS^J];
CODE (LADD);
IF $CARRY THEN
BEGIN
CODE (EXCH);
STACK 1; ! Similar argument for no carry
CODE (LADD; EXCH); ! after adding 1 as MPMUL1
routine.
END;
STACK KARRY;
CODE (LADD);
IF $CARRY THEN
BEGIN
CODE (EXCH);
STACK 1; ! Similar argument here but a bit
more
CODE (LADD; EXCH); ! complicated as effective max
here is
END; ! now 9*9+9+9 =3D 99.
STORE W[I^PLUS^J];
STORE KARRY;
I^PLUS^J :=3D I^PLUS^J - 1;
END; ! FOR LOOP ON I !
DROP I;
W[I^PLUS^J] :=3D KARRY;
DROP I^PLUS^J, KARRY;
END; ! FOR LOOP ON J !
END; ! PROC MPMUL !
?PAGE
PROC MPDIVI (Q, R, EU, EV, M, N);
INT .Q; ! QUOTIENT
INT .R; ! REMAINDER
INT .EU; ! DIVIDEND (EXTERNAL COPY)
INT .EV; ! DIVISOR (EXTERNAL COPY)
INT M; ! NUMBER OF DIGITS IN QUOTIENT
INT N; ! NUMBER OF DIGITS IN DIVISOR.
BEGIN
INT V1 :=3D 0, V2 :=3D 0; ! FIRST TWO WORDS OF V FOR QUICK
REFERENCE
INT Q^ :=3D 0, R^ :=3D 0; ! TRIAL QUOTIENT DIGIT, FIRST
REMAINDER DIGIT
INT(32) Q^X^V2 :=3D 0D; ! Q^ * V2
INT SHIFT :=3D 0; ! N, FOR 2**N =3D D (D =3D NORMALIZER)
INT .U[-1:31] :=3D [33*[0]]; ! LOCAL COPY OF DIVIDEND
(NORMALIZED)
INT .V[-1:31] :=3D [33*[0]]; ! LOCAL COPY OF DIVISOR
(NORMALIZED)
INT .U^J; ! U[J]
INT(32) .UD^J =3D U^J; ! U[J], U[J+1]
INT J :=3D 0; ! QUOTIENT DIGIT INDEX !
INT DUMMY :=3D 0;
ENTRY MPDIVI^V^C6^01^SEP^83;
MPDIVI^V^C6^01^SEP^83:
! START OF PROC CODE. !
! DETERMINE NORMALIZATION !
USE D, V^ONE, SHIFT^COUNT;
SHIFT^COUNT :=3D 0;
D :=3D 1;
V^ONE :=3D EV[D];
! Shift first word of divisor left until Most Sig Bit =3D 1.
! Double D each time to form D =3D 2**P where P is number of
! leading zero bits of first word of divisor.
WHILE NOT V^ONE.<0> DO
BEGIN
D :=3D D '+' D;
V^ONE :=3D V^ONE '<<' 1;
SHIFT^COUNT :=3D SHIFT^COUNT + 1;
END; ! OF WHILE !
SHIFT :=3D SHIFT^COUNT;
DROP SHIFT^COUNT, V^ONE;
! NORMALIZE - Multiply Top and Bottom by 2**P =3D D !
CALL MPMUL1 (U[-1], EU, D, N+M);
CALL MPMUL1 (V[-1], EV, D, N);
DROP D;
! GET V1 & V2 FOR SPEED !
V1 :=3D V[1];
V2 :=3D V[2];
! LOOP DEVELOPING QUOTIENT DIGITS !
Q :=3D 0;
FOR J :=3D 0 TO M DO
BEGIN
@U^J :=3D @U '+' J;
! GET Q^ - a first guess at the Quotient !
IF U^J =3D V1 THEN
BEGIN
STACK %177777;
END
ELSE
BEGIN
STACK UD^J, V1;
CODE (LDIV; EXCH);
STORE Q^;
END;
STORE Q^;
CODE(RDE; ANRI -%201; SETE); !TURN OFF TRAPS ( Bit 8 off )
TESTQ^: !This can overflow sometimes
when
STACK UD^J - Q^ '*' V1; !scale increase > 17
CODE (EXCH); ! This exchange of A and B sets CC depending
STORE DUMMY; ! on value of A after exchange (viz. DUMMY)
IF =3D THEN
BEGIN ! FURTHER TESTING NEEDED !
STORE R^;
Q^X^V2 :=3D Q^ '*' V2;
IF ($HIGH(Q^X^V2) '=3D' R^ AND $INT(Q^X^V2) '>' U[J+2]) OR
$HIGH(Q^X^V2) '>' R^ THEN
BEGIN ! Q^ TOO LARGE !
Q^ :=3D Q^ '-' 1;
GOTO TESTQ^;
END;
END
ELSE
STORE DUMMY;
!C6! CODE(RDE; ORRI %200); !TRAPS ON ( Bit 8 on - Trap )
!C6! CODE(ANRI -%41; SETE); ! ( Bit 10 off -
overflow )
! MULTIPLY & SUBTRACT !
USE I;
USE BORROW;
BORROW :=3D 0;
FOR I :=3D N DOWNTO 0 DO
BEGIN
USE I^PLUS^J;
I^PLUS^J :=3D I + J;
STACK V[I] '*' Q^, U[I^PLUS^J];
CODE (EXCH; LSUB);
IF NOT $CARRY THEN
BEGIN ! INCREMENT B !
CODE (EXCH);
STACK 1;
CODE (LADD; EXCH);
END;
STACK BORROW;
CODE (LSUB);
STORE U[I^PLUS^J];
DROP I^PLUS^J;
IF NOT $CARRY THEN
BEGIN
STACK 1;
CODE (LADD);
END;
STORE BORROW;
END;
IF BORROW THEN
BEGIN ! Q^ STILL TOO LARGE !
DROP BORROW;
USE KARRY;
KARRY :=3D 0;
FOR I :=3D N DOWNTO 1 DO
BEGIN
STACK V[I] '+' KARRY;
KARRY :=3D IF $CARRY THEN 1 ELSE 0;
USE I^PLUS^J;
I^PLUS^J :=3D I + J;
STACK U[I^PLUS^J];
CODE (LADD);
STORE U[I^PLUS^J];
DROP I^PLUS^J;
IF $CARRY THEN KARRY :=3D 1;
END;
U[J] :=3D U[J] + KARRY;
DROP KARRY;
Q^ :=3D Q^ '-' 1;
END; ! OF Q^ STILL TOO LARGE !
DROP I;
Q[J+1] :=3D Q^;
END; ! OF FOR LOOP ON QUOTIENT DIGITS !
! UNNORMALIZE REMAINDER !
U[M] :=3D 0;
@UD^J :=3D @U[M+N-1];
USE I;
FOR I :=3D N DOWNTO 1 DO
BEGIN
R[I] :=3D $INT(UD^J '>>' SHIFT);
@UD^J :=3D @UD^J - 1;
END; ! OF UNNORMALIZATION LOOP !
DROP I;
END; ! OF PROC MPDIVI !
?PAGE
PROC MPDIV (Q, R, U, V, N, M);
INT .Q;
INT .R;
INT .U;
INT .V;
INT N;
INT M;
BEGIN
ENTRY MPDIV^V^C4^07^MAR^83;
MPDIV^V^C4^07^MAR^83:
IF NOT V[1] THEN
CODE (CCL)
ELSE
BEGIN
CALL MPDIVI (Q, R, U, V, N, M);
CODE (CCE);
END;
END;
?page
INT PROC L^MUL(AM1,AM2,AMR,DP1,DP2,DPR,ROPT,AMRINT ) VARIABLE;
INT .AM1,.AM2,.AMR,DP1,DP2,DPR,ROPT,AMRINT;
BEGIN
!
***********************************************************************
!*
*
!* This procedure forms the application interface the the arithmetic
*
!* routines for long multiplication and long division. In addition
*
!* to validating the parameters passed by the application, this proc
*
!* has to scale the values passed so that the correct precision is
*
!* retained in the answer.
*
!*
*
!* For long division, the arithmetic routines exhibit the following
*
!* behaviour. If a number with n decimal places is divided by a
*
!* number with m decimal places, the result will contain n-m places.
*
!* If the application has requested p decimal places in the result,
*
!* and n-m is less than p, we must scale the dividend up before
*
!* dividing so as to retain the number p in the result. A Subproc
*
!* 'SCALEUP' is used for this purpose.
*
!*
*
!
***********************************************************************
INT I :=3D 0, ! WORK INDEX
L1 :=3D 5, ! NUMBER OF WORDS
PRECISION LAM1
L2 :=3D 5, ! NUMBER OF WORDS
PRECISION LAM2
L3 :=3D 0, ! NUBMER OF WORDS
PRECISION WA2
L4 :=3D 0, ! NUMBER OF WORDS
PRECISION WA1
L5 :=3D 0, ! NUMBER OF WORDS
PRECISION WA3
L6 :=3D 0, ! NUMBER OF WORDS
PRECISION WA4
IDP :=3D 0, ! DECIMAL PLACES
REQUIRED IN RES
MORD :=3D 0, ! NULTIPLY OR DIVIDE
TO GET RES
MULDIV, ! MULTIPLY OR DIVIDE
REQUIRED BY
! CALLER.
.LPROD[0:31],
N^LPROD,
.LAM1[0:4], ! LOCAL COPY OF AM1
.LAM2[0:4], ! LOCAL COPY OF AM2
.WA2[0:7] :=3D [8*[0]], ! RESULT LAM1 * LAM2
.WA3[0:31] :=3D [8*[0]], ! RESULT OF WA2 * WA1
.WA4[0:7] :=3D [8*[0]], ! RESULT OF WA2 / WA1
.WREM[0:3] :=3D [4*[0]]; ! REMAINDER OF WA2 /
WA1
INT PREFIX^WA1 :=3D 0; ! DO NOT SEPERATE THIS
INT
FIXED WA1 :=3D 0F; ! OR THIS FIXED.
FIXED .FRES :=3D @AMR;
STRING .START^INT,
.AMR^ASCII[0:19];
INT SUBPROC WA1^CALC ( X );
INT X;
BEGIN
CASE X OF
BEGIN
WA1 :=3D 1F; ! 0
WA1 :=3D 10F; ! 1
WA1 :=3D 100F; ! 2
WA1 :=3D 1000F; ! 3
WA1 :=3D 10000F; ! 4
WA1 :=3D 100000F; ! 5
WA1 :=3D 1000000F; ! 6
WA1 :=3D 10000000F; ! 7
WA1 :=3D 100000000F; ! 8
WA1 :=3D 1000000000F; ! 9
WA1 :=3D 10000000000F; ! 10
WA1 :=3D 100000000000F; ! 11
WA1 :=3D 1000000000000F; ! 12
WA1 :=3D 10000000000000F; ! 13
WA1 :=3D 100000000000000F; ! 14
WA1 :=3D 1000000000000000F; ! 15
WA1 :=3D 10000000000000000F; ! 16
WA1 :=3D 100000000000000000F; ! 17
OTHERWISE ;
END;
RETURN X;
END;
INT SUBPROC SCALEUP( SCUP , CAND , N^CAND , PROD , N^PROD);
INT SCUP; ! Amount to scale up by
INT .CAND; ! Number to be scaled up ( Multiplicand ).
INT N^CAND; ! Number of digits in CAND ( max 4 )
INT .PROD; ! Product of scaling
INT .N^PROD; ! Number of digits in PROD ( max 32 )
! The subproc uses three local ( to the calling proc ) variables
! LPROD ( a work copy of the product ), N^LPROD ( # of digits in
LPROD )
! PREFIX^WA1 ( a 4 word array used by subproc WA1^CALC )
BEGIN
INT A , B;
INT LSCUP :=3D SCUP; ! Local copy of SCUP
LPROD ':=3D' [5*[0]];
LPROD ':=3D' CAND[4-N^CAND] FOR N^CAND + 1;
N^LPROD :=3D N^CAND;
DO ! Until LSCUP =3D 0 or number of digits in PROD overflows 31
! ( Scaling is done in mutiples of 17 if SCUP > 17 )
BEGIN
A :=3D 5;
B :=3D 0;
CALL WA1^CALC($MIN(17,LSCUP));
DO
BEGIN
IF NOT PREFIX^WA1[B] THEN A :=3D A - 1;
B :=3D B + 1;
END
UNTIL PREFIX^WA1[B] OR B > 4;
CALL MPMUL(PROD,LPROD,PREFIX^WA1[4-A],N^LPROD,A);
LPROD :=3D 0;
N^LPROD :=3D N^LPROD + A + 1;
LPROD[1] ':=3D' PROD FOR N^LPROD;
LSCUP :=3D LSCUP - $MIN(17,LSCUP);
END
UNTIL NOT LSCUP OR N^LPROD > 31;
IF (N^PROD :=3D N^LPROD) > 31 THEN
RETURN 1
ELSE
RETURN 0;
END; ! SCALEUP PROC
ENTRY L^DIV;
ENTRY L^MUL^V^C6^01^SEP^83;
L^MUL^V^C6^01^SEP^83:
! Procedure code proper starts here
IF NOT $PARAM(AM1) OR !
NOT $PARAM(AM2) OR !
NOT $PARAM(AMR) OR !
NOT $PARAM(DP1) OR ! ENSURE REQUIRED
PARAMETERS
NOT $PARAM(DP2) OR ! ARE PRESENT
NOT $PARAM(DPR) OR ! IF NOT - RETURN
ERROR.
NOT $PARAM(ROPT) THEN RETURN 3; !
MULDIV :=3D 1; ! A multiply request so
IF DP1 + DP2 > DPR + 1 THEN ! decide on the amount
to
IDP :=3D (DP1 + DP2) - (DPR + 1) ! scale the internal
ELSE ! calculation by. ( If
IF DP1 + DP2 < DPR + 1 THEN ! scale up then set MORD
BEGIN ! to true.
IDP :=3D (DPR + 1) - (DP1 + DP2);
MORD :=3D 1;
END
ELSE IDP :=3D 0;
GOTO MUL;
L^DIV:
MULDIV :=3D 0; ! A divide request so
! decide on the amount
to
IF DP1 > DPR THEN ! scale the internal
calc.
IDP :=3D DP1 - DPR ! If scale up then set
MORD
ELSE ! to true.
IF DP1 < DPR THEN
BEGIN
IDP :=3D DPR - DP1;
MORD :=3D 1;
END
ELSE
IDP :=3D 0;
MUL: ! Start work here
after
! deciding scale
factor.
AMR ':=3D' [4*[0]]; ! CLEAR RESULT FIELD.
LAM1 :=3D 0; ! ZEROISE FIRST WORD
OF ARRAY
LAM2 :=3D 0; ! ZEROISE FIRST WORD
OF ARRAY
LAM1[1] ':=3D' AM1 FOR 4; ! SAVE LOCAL COPY AM1
(IST NUM)
LAM2[1] ':=3D' AM2 FOR 4; ! SAVE LOCAL COPY AM2
(2ND NUM)
I :=3D 0; ! FIND THE
DO ! NUMBER OF
SIGNIFICANT
BEGIN ! WORDS IN LAM1.
IF NOT LAM1[I] THEN L1 :=3D L1 - 1; ! SHOULD NOT BE SET
I :=3D I + 1; ! TO < 1 OR > 4.
END ! A VALUE IN I OF 0
INDICATES
UNTIL LAM1[I] OR I > 4; ! THAT THE CALLER HAS
A VALUE 0.
IF I > 4 THEN RETURN 1; ! IF NUMBER IS ZERO
THEN RETURN.
I :=3D 0; ! CHECK SECOND NUMBER
DO !
BEGIN ! FIND NUMBER OF
SIGNIFICANT
IF NOT LAM2[I] THEN L2 :=3D L2 - 1; ! WORDS OF LAM2.
I :=3D I + 1; ! SHOULD NOT BE < 1 OR
> 4.
END ! IF VALUE IN I IS 0
UNTIL LAM2[I] OR I > 4; ! THEN THE SECOND
NUMBER
IF I > 4 THEN RETURN 2; ! SUPPLIED IS ZERO SO
RETURN.
IF MULDIV THEN ! L^MUL called so
BEGIN ! do a multiply.
L3 :=3D L1 + L2 +1;
CALL MPMUL(WA2,LAM1[4-L1],LAM2[4-L2],L1,L2);
END
ELSE
BEGIN ! L^DIV called so
scale up
IF MORD THEN ! and the do the
divide.
BEGIN
IF SCALEUP(DP2+IDP+1,LAM1,L1,WA3,L5 ) THEN
RETURN 4;
! If DP1 < DPR we must
! scale up enough
before we
END ! divide so as to
retain the
ELSE ! required amount of
precision
! in the answer
( DPR ).
IF SCALEUP(DP2+1,LAM1,L1,WA3,L5) THEN
RETURN 4;
L3 :=3D L5 - L2 +1 ;
CALL MPDIV(WA2,WREM,WA3,LAM2[4-L2],L5-L2-1,L2);
END;
IF NOT IDP THEN
BEGIN ! NO FURTHER
CALCULATIONS
IF L3 > 4 THEN ! TO BE DONE. CHECK TO
SEE
FOR I :=3D 1 TO L3 - 4 DO ! IF RESULT OVERFLOWS
REPLY
IF WA2[I-1] THEN RETURN 5; ! FIELD. BAD RETURN IF
SO.
AMR[3] '=3D:' WA2[L3-1] FOR (IF L3 > 4 THEN 4 ELSE L3); !
RETURN RESULT
END ! SCALE FACTOR (*
OR /) BY
ELSE
IF WA1^CALC(IDP) > 17 THEN
IF NOT MORD OR MULDIV THEN
RETURN 4;
IF IDP THEN
BEGIN
L4 :=3D 5; ! CHECK TO SEE HOW
MANY
I :=3D 0; ! WORDS WE HAVE
USED
DO ! IN OUR SCALE WORK
FIELD.
BEGIN ! THERE IS AN
ADDITIONAL
IF NOT PREFIX^WA1[I] THEN L4 :=3D L4 -1; ! WORD OF NULLS AT
THE
I :=3D I + 1; ! START OF WA1.
THIS IS
END ! CALLED PREFIX^WA1
AND
UNTIL PREFIX^WA1[I] OR I > 4; ! SHOULD NOT BE
MOVED.
IF MORD THEN ! We do not need to
multiply
BEGIN ! by scale factor
since DP1
IF NOT MULDIV THEN ! is > DPR and hence
we have
BEGIN ! already done this
earlier.
IF L3 > 4 THEN ! Check for possible
overflow
FOR I :=3D 1 TO L3 - 4 DO ! of callers Fixed
reply field
IF WA2[I-1] THEN RETURN 5; ! Must not exceed 4
non zero
AMR[3] '=3D:' WA2[L3-1] FOR (IF L3 > 4 ! words.
THEN 4 ELSE L3); ! The above is for
division
END ! only. The next
para applies
ELSE ! if we are doing
mult.
BEGIN
CALL MPMUL(WA3,WA2,PREFIX^WA1[4-L4],L3,L4);
L5 :=3D L3 + L4;
IF L5 > 4 THEN
FOR I :=3D 1 TO L5 - 4 DO
IF WA3[I-1] THEN RETURN 5;
AMR[3] '=3D:' WA3[L5-1] FOR (IF L5 > 4
THEN 4 ELSE L5);
END;
END !
ELSE ! ELSE DIVIDE - I.E.
Dec
BEGIN ! places < than num
1 & num 2.
CALL MPDIV(WA4,WREM,WA2,PREFIX^WA1[4-L4],L3-L4-1,L4); !
Divide by scale
L6 :=3D $MAX(0, L3 - L4 ); !version C6! ! Check for overflow
of
IF L6 > 4 THEN ! callers Fixed
reply field.
FOR I :=3D 0 TO L6 -4 DO ! This ensures that
the field
IF WA4[I] THEN RETURN 5; ! WA4 has no more
than 4 non
! zero words.
AMR[3] '=3D:' WA4[L6] FOR (IF L6 > 4 THEN 4 ELSE L6); ! If all
ok we can
END; ! move the result
from WA4
END; ! into the callers
field.
IF AMR.<0> THEN RETURN 5; ! If the MSB is on, the 4 word
number has
! gone -ve hence overflow
CASE ROPT OF
BEGIN
!0! BEGIN
STACK FRES,5F;
CODE(QADD;QDWN 1);
STORE FRES;
END;
!1! BEGIN
STACK FRES,50F;
CODE(QADD;QDWN 2;QUP 1);
STORE FRES;
END;
!2! BEGIN
STACK FRES,500F;
CODE(QADD;QDWN 3;QUP 2);
STORE FRES;
END;
!3! BEGIN
STACK FRES,5000F;
CODE(QADD;QDWN 4;QUP 3);
STORE FRES;
END;
!4! BEGIN
STACK FRES,50000F;
CODE(QADD;QDWN 4;QDWN 1;QUP 4);
STORE FRES;
END;
!5! BEGIN
STACK FRES,500000F;
CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
STORE FRES;
END;
!6! BEGIN
STACK FRES,5000000F;
CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
STORE FRES;
END;
!7! BEGIN
STACK FRES,50000000F;
CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
STORE FRES;
END;
!8! BEGIN
STACK FRES,500000000F;
CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
STORE FRES;
END;
!9! BEGIN
STACK FRES,5000000000F;
CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
STORE FRES;
END;
OTHERWISE
RETURN 7; ! ROPT > 9 or < 0 so invalid
END; ! END OF CASE ROPT.
IF $PARAM(AMRINT) THEN
BEGIN
AMR^ASCII[19] :=3D 0;
STACK FRES,@AMR^ASCII,19;
CODE(CQA);
SCAN AMR^ASCII WHILE "0" -> @START^INT;
IF ((@AMR^ASCII '+' 19) '-' @START^INT) > (AMRINT + DPR) THEN
RETURN 6;
END;
END;
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
|
|
0
|
|
|
|
Reply
|
Shirish
|
3/1/2011 10:45:37 AM
|
|
Shirish wrote:
> On Feb 28, 1:03 pm, Keith Dick <kd...@acm.org> wrote:
>
>>Doug Miller wrote:
>>
>>>In article <ae49bf89-a5fc-40c0-bc8b-bddb810ef...@w6g2000vbo.googlegroups.com>, Shirish <shirish...@gmail.com> wrote:
>>
>>>>Hi,
>>
>>>>I am seaching for pTAL TNS instructuctions can be used to replace CODE
>>>>statement in TAL.
>>
>>>That depends entirely on what the CODE statement is. CODE allows the
>>>programmer to insert assembly language instructions in a TAL program; without
>>>knowing what those assembly language instructions are, it's impossible to tell
>>>you how to replace them in pTAL.
>>
>>To amplify on what Doug said a little, the usual things that CODE statements were used for were identified and pTAL built-in routines were implemented for them, and most or all of them were then implemented in TAL, to make it easier to maintain a single source file for TAL or pTAL compilation.
>>
>>You can find the list of those built-in routines in the pTAL Reference Manual, chapter 15. Look through that list of routines, and if you do not find a function that does what you need to do, post here again explaining more specifically what you are trying to do, and we will try to find a way to solve the problem.
>
>
> Thanks Keith/Dough,
>
> I found the pTAL buid in routines in manual. Where can i get machine-
> level instructions manual for CODE. Below are the CODE statment i am
> looking to replace.
> CODE (EXCH);
> CODE (LADD; EXCH);
> CODE (LADD);
> CODE (LDIV; EXCH);
> CODE(RDE; ANRI -%201; SETE);
> CODE(RDE; ORRI %200);
> CODE(ANRI -%41; SETE);
> CODE (EXCH; LSUB);
> CODE (LADD; EXCH);
> CODE (LSUB);
> CODE (CCL)
> CODE (CCE);
> CODE(QADD;QDWN 1);
> CODE(QADD;QDWN 2;QUP 1);
> CODE(QADD;QDWN 3;QUP 2);
> CODE(QADD;QDWN 4;QUP 3);
> CODE(QADD;QDWN 4;QDWN 1;QUP 4);
> CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
> CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
> CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
> CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
> CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
> CODE(CQA);
The TNS instructions are described in manuals titled something similar to "NonStop Cyclone System Description Manual". There were several manuals, one for each of the models of CISC system that Tandem designed. To understand a particular CODE statement requires varying amounts of knowledge of the TNS architecture, which can also be found in the system description manuals, but if you do not already know most of the information, finding it in one of those manuals will not be easy. But at least you could look up the instructions to see what the description seems to be telling you about it.
For the particular ones you asked about, here are some explanations and possible translations to pTAL.
CODE (EXCH);
EXCH exchanges the top two 16-bit values on the stack. This has to be preceded by some statement that puts values onto the stack. That could be a STACK statement, other CODE statements, or other things. Note that it leaves the items on the stack in the opposite order from what they were, so something after this must use those values in some way. Perhaps a STORE statement to put them into some variables. The pTAL function for this is $EXCHANGE.
CODE (LADD; EXCH);
LADD does unsigned add of the top two 16-bit items on the stack. With the EXCH, that means there have to be three or more items on the stack before this CODE statement is executed. It will first do and unsigned add of the top two items, then exchange the result of the add with the remaining item on the stack. Something preceding this CODE statement had to put those three items onto the stack, and something following must use the resulting two items left on the stack.
An unsigned add can be done with '+', so normally there is no need to use a CODE statement to do an unsigned add. I would have to see the code around this CODE statement to tell how the equivalent pTAL code would be written.
CODE (LADD);
LADD again. It does an unsigned add of the top two items on the stack, leaving the sum on the stack. Something must follow to use the sum. Again, I don't know why '+' is not used.
CODE (LDIV; EXCH);
LDIV divides the 32-bit value formed by the second and third item on the stack by the top item on the stack, leaving the remainder and quotient on the stack. The EXCH reverses the order of the quotient and remainder. Statements before this one have to put the three items onto the stack, and statements following have to use the quotient and remainder.
$UDIVREM16(dividend,divisor,quotient,remainder) is the replacement for this and some preceding and following statements.
CODE(RDE; ANRI -%201; SETE);
RDE pushes the environment register onto the stack. ANRI is AND Right Immediate. In this instruction, the immediate value is -%201, which I think would be %177177. This would clear the Trap bit. The SETE removes the top value from the stack and puts it into the environment register. This instruction sequence turns off traps.
In pTAL, you do not control traps this way. You use ENABLE_OVERFLOW_TRAPS and DISABLE_OVERFLOW_TRAPS on BEGIN statements to control whether traps occur within the block. This applies to the two CODE statements below, too.
CODE(RDE; ORRI %200);
ORRI is OR Right Immediate. This would read the environment register and turn on the Trap bit, but leaves it on the stack. Perhaps it is followed by the next CODE statement, below.
CODE(ANRI -%41; SETE);
This ANDs the top of stack with %177737, which turns off the Overflow bit. The SETE would remove the top item from the stack and put it into the environment register. If this CODE statement immediately follows the one just above, the combined effect is to clear the overflow bit and enable interrupts. I imagine that overflow is cleared before turning on the interrupts so that any overflow that had occurred would not cause an immediate trap.
CODE (EXCH; LSUB);
EXCH is the exchange instruction, described above. LSUB does an unsigned subtraction of the top two items on the stack, leaving the result on the top of the stack. I do not know why '-' would not be used. I would have to see the surrounding statements to understand how to convert to pTAL.
CODE (LADD; EXCH);
This is the same as the second CODE statement, above.
CODE (LSUB);
LSUB was described above.
CODE (CCL)
CCL sets the condition codes so that "IF < THEN" is true. If this is being used to set the condition code to be returned from a procedure to its caller, you do that in pTAL by specifying the RETURNSCC attribute on the procedure declaration, and specifying the condition code as the second arguemnt to the RETURN statement.
CODE (CCE);
CCE sets the condition codes so that "IF = THEN" is true. See previous explanation.
CODE(QADD;QDWN 1);
QADD adds two quadword (64-bit) values that are on the stack, leaving the sum as one quadword value on the stack. QDWN 1 scales down the quadword value on the top of the stack one decimal place (divides by 10).
CODE(QADD;QDWN 2;QUP 1);
QADD adds two quadwords, as above. QDWN 2 scales down by two decimal places (divides by 100). QUP 1 scales up by one decimal place (multiplies by 10). I imagine the purpose is to divide the original value by 10, and also round down to an even multiple of 10, but I might be viewing it incorrectly. In any case, I imagine the following expression would do the same:
$SCALE($SCALE(v1+v2,-2),1)
where v1 and v2 are the two values that had somehow been placed on the stack before the CODE statement was executed.
CODE(QADD;QDWN 3;QUP 2);
$SCALE($SCALE(v1+v2,-3),2)
and similarly for the other QDWN/QUP combinations.
CODE(QADD;QDWN 4;QUP 3);
CODE(QADD;QDWN 4;QDWN 1;QUP 4);
CODE(QADD;QDWN 4;QDWN 2;QUP 4;QUP 1);
$SCALE($SCALE(v1+v2,-6),5)
Multiple QDWN and QUP instructions were needed since 4 is the largest number of decimal digits one QUP or QDWN can scale, but the $SCALE built-in is not so limited.
CODE(QADD;QDWN 4;QDWN 3;QUP 4;QUP 2);
CODE(QADD;QDWN 4;QDWN 4;QUP 4;QUP 3);
CODE(QADD;QDWN 4;QDWN 4;QDWN 1;QUP 4;QUP 4);
CODE(QADD;QDWN 4;QDWN 4;QDWN 2;QUP 4;QUP 4;QUP 1);
CODE(CQA);
CQA is Convert quad to ASCII. Use $FIXEDTOASCII to replace it, and some of the preceding statements.
|
|
0
|
|
|
|
Reply
|
Keith
|
3/1/2011 12:23:00 PM
|
|
On Mar 1, 9:45=A0pm, Shirish <shirish...@gmail.com> wrote:
> On Mar 1, 9:05=A0am, ghr <ghr1...@gmail.com> wrote:
>
>
>
>
> > Is there any documentation? What is the name of the procedure? Any
> > idea what it is trying to do? Any comments? Anything to help
> > understand? Is it in a program or a TCP (pathway) library module?- Hide=
quoted text -
>
> > - Show quoted text -
>
> Below ia some example code
It seems to me that these algorithms are dealing with 'big numbers' -
http://en.wikipedia.org/wiki/Bignum
The code looks to date from 1983 so it's nearly 30 years old.
It may be worth replacing this code completely rather than trying to
figure out what the algorithms are actually trying to do and then
translating back into a programming language (pTal), and then trying
to prove no bugs have been introduced. Perhaps look at
http://www.di-mgt.com.au/bigdigits.html for a version in C.
|
|
0
|
|
|
|
Reply
|
ghr
|
3/1/2011 11:13:32 PM
|
|
ghr wrote:
> On Mar 1, 9:45 pm, Shirish <shirish...@gmail.com> wrote:
>
>>On Mar 1, 9:05 am, ghr <ghr1...@gmail.com> wrote:
>>
>>
>>
>
>
>>>Is there any documentation? What is the name of the procedure? Any
>>>idea what it is trying to do? Any comments? Anything to help
>>>understand? Is it in a program or a TCP (pathway) library module?- Hide quoted text -
>>
>>>- Show quoted text -
>>
>>Below ia some example code
>
>
> It seems to me that these algorithms are dealing with 'big numbers' -
> http://en.wikipedia.org/wiki/Bignum
> The code looks to date from 1983 so it's nearly 30 years old.
>
> It may be worth replacing this code completely rather than trying to
> figure out what the algorithms are actually trying to do and then
> translating back into a programming language (pTal), and then trying
> to prove no bugs have been introduced. Perhaps look at
> http://www.di-mgt.com.au/bigdigits.html for a version in C.
>
If someone were writing a new application, I would agree that using some existing library that does arithmetic on extended-size values probably would be the best approach. However, that seems not to be the situation here. It seems that an existing application is to be converted from TAL to pTAL. Substituting a different library during the conversion has risks that the new library does not work quite the same as the old library does. You have to compare that risk to the risk that converting the current library will introduce errors that will make the converted library not work exactly the same as the original library did.
If this were my job to do, and if the size of the extended-size arithmetic library is not much larger than the example we were shown, I would feel quite confident that I could convert it to pTAL with extremely little chance of introducing an error in the conversion. I would use the ?ICODE directive to make sure I understood exactly what each code sequence that has to be converted is doing, then I am sure I could write the correct pTAL code for it.
But not everyone has my experience. I understand TAL and the T/16 instruction set rather well. Someone who does not understand the T/16 instruction set very well would have a higher chance of making an error, thus making the approach of converting to pTAL have a similar risk of introducing a change in how the applicaiton works as does the approach of switching to a library from somewhere else.
The best approach, from the point of view of reducing the chance of introducing a changing in the application's behaviour, would be to give the job of converting the TAL code that deals with the extended-size arithmetic to someone who has experience roughly equivalent to mine and have that person convert the TAL to pTAL. That might not be compatible with other constraints on the project (cost, confidentiality matters, etc.).
So without knowing more about the overall project goals and constraints, I cannot say whether converting the existing code or substituting a library from somewhere else would be the better choice. I'm writing this post to point out this issue so that Shirish, or whoever makes decisions about such things for his project, knows they should think about this point carefully.
|
|
0
|
|
|
|
Reply
|
Keith
|
3/2/2011 6:16:43 AM
|
|
|
8 Replies
188 Views
(page loaded in 0.325 seconds)
|