<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>


Fast Looping Intrinsics

The following words may be used to produce faster loops. They remove the need for explicit comparisons prior to the exit condition (UNTIL). Tests (in short, tight loops) have shown them to be from 25 to 30% faster. Of course, the more complex the code in the loop, the less the payoff.

The words below were written with the Forth 9900 Assembler, available on block 9 of the boot disk, then converted to machine CODE words using the ASM>CODE utility on block 29 of the boot disk. For anyone interested, the Forth assembler source is also given. Note: Using the CODE words means you don't need to load the assembler to use the words.

Name Stack Sig Description
loop=0 -- loops back to preceding BEGIN if TOS=0. TOS is not consumed.
loop<>0 -- loops back to preceding BEGIN if TOS<>0. TOS is not consumed.
loop>0 -- loops back to preceding BEGIN if TOS>0. TOS is not consumed.
loop<0 -- loops back to preceding BEGIN if TOS<0. TOS is not consumed.
loop= a b -- a loops back to preceding BEGIN if a=b. b is consumed.
loop<> a b -- a loops back to preceding BEGIN if a<>b. b is consumed.

Common Code

The following code is common to all the routines below. Since TurboForth checks that all BEGINs have a matching UNTIL, a hack is required to adjust the reference counting:

LOOP=0 ( -- )

Loops back to preceding BEGIN if TOS=0. TOS is not consumed.

Size: 46 bytes.

Test Code

The loop will not execute since TOS is not zero.

Equivalent Forth Assembler Code

ASM: (loop=0) ( -- ) \ loop while TOS=0. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp r1 mov, \ test TOS
eq if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

LOOP<>0 ( -- )

Loops back to preceding BEGIN if TOS<>0. TOS is not consumed.

Size: 50 bytes.

Test Code

The loop will execute since TOS is not zero.

Equivalent Forth Assembler Code

ASM: (loop<>0) ( -- ) \ loop while TOS <>0. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp r1 mov, \ test TOS
ne if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

LOOP>0 ( -- )

Loops back to preceding BEGIN if TOS>0. TOS is not consumed.

Size: 48 bytes.

Test Code

The loop will execute until TOS=0.

Equivalent Forth Assembler Code

ASM: (loop>0) ( -- ) \ loop while TOS>0. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp r1 mov, \ test TOS
gt if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

LOOP<0 ( -- )

Loops back to preceding BEGIN if TOS<0. TOS is not consumed.

Size: 48 bytes.

Test Code

The loop will execute until TOS is no longer negative.

Equivalent Forth Assembler Code

ASM: (loop<0) ( -- ) \ loop while TOS<0. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp r1 mov, \ test TOS
lt if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

LOOP= ( a b -- )

Loops back to preceding BEGIN if a=b. b is consumed.

Size: 48 bytes.

Test Code

The loop will not execute because a and b are not equal.

Equivalent Forth Assembler Code

ASM: (loop=) ( n -- ) \ loop while TOS=n. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp+ r1 mov, \ get n
*sp r1 cmp, \ compare n and TOS
eq if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

LOOP<> ( a b -- )

Loops back to preceding BEGIN if a <>b. b is consumed.

Size: 48 bytes.

Test Code

The loop executes until a and b are equal.

Equivalent Forth Assembler Code

ASM: (loop<>) ( a b -- ) \ loop while TOS<>n. TOS is not consumed.
\ the loop back address is in-line. Can be accessed via PC (R3)
r3 *+ r0 mov, \ get loop-back address and advance PC
*sp+ r1 mov, \ pop b
*sp r1 cmp, \ compare a and b
ne if,
r0 r3 mov, \ load program counter with loop-back address
endif,
;ASM

30th May 2016


<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>