Monday, May 19, 2008

Trig in PropellerForth

Among many other nice features, the Parallax Propeller microcontroller has a single-quadrant sine table in ROM. This makes implementing sine and cosine fast and simple, for medium-precision (13-bit) work.

Here's a simple port of Parallax's routines to PropellerForth.

hex

\ Address of table in ROME000 constant sin-base

\ Computes the sign of an angle.\ The angle is a 13-bit number (0x1FFF = almost 360 degrees).\ The result is a 16.16 fixed-point signed integer.: sin ( angle13 -- n16_16 ) dup 1000 and >R \ Stash a flag for Quadr.3/4 onto the rstack dup 0800 and if negate then \ Invert angle for Quadr.2/4 2* sin-base or H@ \ Compute word address and fetch R> if negate then ; \ Negate result for Quadr.3/4

: cos ( angle13 -- n16_16 ) 0800 + sin ;

With PropellerForth v8.05 this gives a runtime of 1088-1152 cycles for sin, and an additional 240 cycles for cos -- 31x slower than a native implementation. (v8.02 will be slower.)

It can be made slightly faster by (1) replacing the numbers with CONSTANTs and (2) inlining 2*, which is not a primitive, as "1 lshift", for a runtime of 993-1056 cycles -- 28x slower than native, at the cost of a 22 more bytes of space.

Update: Huh. Through some optimizations to the kernel, I can shave off another 100 cycles -- for a runtime of 896-926 cycles. However, it costs 248 bytes in the kernel, and eliminates a hook I was hoping to use for single-step and breakpoints. I'll have to weigh this.

About

A blog for my tech rants. My rants, suggestions, ideas, and general pedantry here are representative solely of this geek-at-arms, and not my employer, affiliated civic service organizations, deceased ancestors, or people whose names rhyme with my own.

About Me

Name:Cliff Biffle

Location:Mountain View, California, United States

I'm a Java developer for a large unspecified company, aficionado of programming languages, and general Mac bigot.
Contrary to what you may have read on the intarweb, I am not, in fact, a "Linux stalwart."