         Edinburgh IMP77 Compiler - Version 8.4
    1 ! This is effectively a fixed-point implementation of CORDIC sin and cos which
				.section	".text"
		.Ltext0:
				.section	.rodata.cst8,"aM",@progbits,8
				.align 8
		.LC23:
				.long	0
				.long	0
				.align 8
		.LC24:
				.long	1071694162
				.long	942502757
				.align 8
		.LC25:
				.long	1072693248
				.long	0
				.align 8
		.LC26:
				.long	1070671380
				.long	1587465558
				.align 8
		.LC27:
				.long	1072131317
				.long	-793732779
				.align 8
		.LC28:
				.long	1073460858
				.long	-396866390
				.align 8
		.LC29:
				.long	1072973873
				.long	-621021886
				.align 8
		.LC30:
				.long	-1078625319
				.long	1643146377
				.align 8
		.LC31:
				.long	1073817407
				.long	-1637941472
				.align 8
		.LC32:
				.long	-1074500268
				.long	2146273853
				.align 8
		.LC33:
				.long	1075460998
				.long	-142406208
				.align 8
		.LC34:
				.long	-1068135444
				.long	-1605429243
				.align 8
		.LC35:
				.long	1077614750
				.long	958621237
				.align 8
		.LC36:
				.long	1076441356
				.long	-24825732
				.align 8
		.LC37:
				.long	1071793142
				.long	-1467459024
				.section	".text"
				.align 4
				.proc	06
		ATAN.6057:
		.LFB186:
    2 ! checks results against the floating-point library used by C. There are a few
    3 ! things we could do to improve accuracy - but this is good enough for a quick
    4 ! hack that does not use any external math library code, other than the afore-
    5 ! mentioned consistency checks.
    6
    7 ! The program is based on Michael Bertrand's CORDIC article which has appeared
    8 ! in multiple places including Dr Dobbs magazine, a copy of which can be found
    9 ! at http://www.pennelynn.com/Documents/CUJ/HTML/92HTML/1992024C.HTM
   10
   11 ! Note that in creating this implementation, we hit a bug that manifested at
   12 ! the the extremes of the sin and cos functions (where the values are close
   13 ! to 0 or 1) and which I have patched with an approximation since the functions
   14 ! are close to linear at those points.  However the hack to correct that error
   15 ! does make this code a little larger than the C version from which it was
   16 ! derived.
   17
   18 ! I have thrown in a local implementation of atan and sqrt for good measure :-)
   19
   20 ! Imp77 does not have unsigned integer data types; however since the CORDIC code
   21 ! effectively uses a 1.14 fixed point implementation to implement angles (with
   22 ! the original C sources being compatible with a 16-bit int environment), and
   23 ! the current Imp77 compiler being a 32 bit implementation, unsigned integers
   24 ! have not required.
   25
   26 %begin
		.LVL152:
				save	%sp, -3552, %sp
		.LVL153:
				ldx	[%g7+40], %g1
				stx	%g1, [%fp+2039]
				mov	0, %g1
				add	%fp, 2047, %g1
				stx	%g1, [%fp-1041]
   27
				mov	%i1, %o1
				call	_imp_initialise, 0
				 mov	%i0, %o0
		.LVL154:
   28 %const %integer debug = 0 { 0 : 4 }
   29
   30 !%external %real %fn %spec atan %alias "atanf" (%real angle)  ;! borrow C's math library for use in demo.
   31 %real %fn atan(%longreal x1)
				.register	%g2, #scratch
				.register	%g3, #scratch
		.LVL0:
   32   %const %long %real r1= 1.2595802263029547 @  1
   33   %const %long %real r2=-8.6186317517509520 @  1
   34   %const %long %real r3=-1.2766919133361079 @  0
   35   %const %long %real r4=-8.3921038065840512 @ -2
   36   %const %long %real s1= 2.7096164294378656 @  1
   37   %const %long %real s2= 6.5581320451487386 @  0
   38   %const %long %real s3= 2.1441643116703661 @  0
   39   %const %long %real s4= 1.2676256708212610 @  0
   40   %const %long %real rt3= 1.7320508075688772 @  0
   41   %const %long %real piby6= 5.2359877559829887 @ -1
   42   %const %long %real piby2m1= 5.7079632679489661 @ -1
   43   %const %long %real rt3m1=7.3205080756887728 @ -1
   44   %const %long %real tanpiby12= 2.6794919243112271 @ -1
   45   %long %real xx1,xsq,constant=0
   46   %integer sign=0,inv=0
   47
   48   %if x1<0 %then sign=1 %and xx1=-x1 %else xx1=x1
				sethi	%hi(.LC23), %g1
				ldd	[%g1+%lo(.LC23)], %f8
				fcmped	%fcc0, %f0, %f8
				fbul,pn	%fcc0, .L11
				 mov	0, %g2
		.L2:
		.LVL1:
		.L3:
				sethi	%hi(.LC23), %g3
				ldd	[%g3+%lo(.LC23)], %f8
   49   %if xx1>1.0 %then xx1=1.0/xx1 %and inv=1
				sethi	%hi(.LC25), %g3
				ldd	[%g3+%lo(.LC25)], %f8
				fcmped	%fcc1, %f0, %f8
				fble,pn	%fcc1, .L4
				 mov	0, %g1
   50   %if xx1>tanpiby12 %then xx1=(rt3m1*xx1-1.0+xx1)/(xx1+rt3) %and constant=piby6
				fdivd	%f8, %f0, %f0
		.LVL2:
				sethi	%hi(.LC26), %g3
				ldd	[%g3+%lo(.LC26)], %f10
				fcmped	%fcc2, %f0, %f10
				fble,a,pt %fcc2, .L13
				 fmuld	%f0, %f0, %f10
				sethi	%hi(.LC27), %g3
				ldd	[%g3+%lo(.LC27)], %f8
				fmuld	%f0, %f8, %f8
				sethi	%hi(.LC25), %g3
				ldd	[%g3+%lo(.LC25)], %f10
				fsubd	%f8, %f10, %f8
				faddd	%f8, %f0, %f8
				sethi	%hi(.LC28), %g3
				ldd	[%g3+%lo(.LC28)], %f10
				faddd	%f0, %f10, %f0
		.LVL4:
				fdivd	%f8, %f0, %f0
		.LVL5:
				fnegd	%f0, %f0
		.LVL13:
   51   xsq=xx1*xx1
				mov	1, %g1
		.LVL3:
		.L4:
				fmuld	%f0, %f0, %f10
		.LVL7:
		.L13:
				sethi	%hi(.LC29), %g3
				ldd	[%g3+%lo(.LC29)], %f12
				faddd	%f10, %f12, %f12
				sethi	%hi(.LC30), %g3
				ldd	[%g3+%lo(.LC30)], %f14
				fdivd	%f14, %f12, %f14
				sethi	%hi(.LC31), %g3
				ldd	[%g3+%lo(.LC31)], %f12
				faddd	%f10, %f12, %f12
				faddd	%f14, %f12, %f14
				sethi	%hi(.LC32), %g3
				ldd	[%g3+%lo(.LC32)], %f12
				fdivd	%f12, %f14, %f12
				sethi	%hi(.LC33), %g3
				ldd	[%g3+%lo(.LC33)], %f14
				faddd	%f10, %f14, %f14
				faddd	%f12, %f14, %f14
				sethi	%hi(.LC34), %g3
				ldd	[%g3+%lo(.LC34)], %f12
				fdivd	%f12, %f14, %f12
				sethi	%hi(.LC35), %g3
				ldd	[%g3+%lo(.LC35)], %f14
				faddd	%f10, %f14, %f10
		.LVL8:
				faddd	%f12, %f10, %f12
				sethi	%hi(.LC36), %g3
				ldd	[%g3+%lo(.LC36)], %f10
				fdivd	%f10, %f12, %f10
				fmuld	%f10, %f0, %f0
		.LVL9:
				ba,pt	%xcc, .L3
				 mov	1, %g2
		.LVL14:
		.L12:
   52   xx1 = xx1*(r1/(xsq+s1+r2/(xsq+s2+r3/(xsq+s3+r4/(xsq+s4)))))
				sethi	%hi(.LC24), %g3
				ldd	[%g3+%lo(.LC24)], %f8
		.LVL6:
		.L5:
   53   xx1 = xx1 + constant
   54   %if inv=1 %then xx1=1.0-xx1+piby2m1
				cmp	%g1, 1
				be,pn	%icc, .L12
				 faddd	%f8, %f0, %f0
		.LVL10:
		.L6:
   55   %if sign=1 %then xx1=-xx1
				sethi	%hi(.LC25), %g1
		.LVL15:
				ldd	[%g1+%lo(.LC25)], %f8
		.LVL16:
				fsubd	%f8, %f0, %f0
		.LVL17:
				sethi	%hi(.LC37), %g1
				ldd	[%g1+%lo(.LC37)], %f8
		.LVL18:
				ba,pt	%xcc, .L6
				 faddd	%f0, %f8, %f0
		.LFE186:
				.align 4
				.proc	020
		PHEX.6104:
		.LFB189:
   56   %result=xx1 { shorten from %long %real down to %real when returning result }
				fnegd	%f0, %f8
				cmp	%g2, 1
				fmovde	%icc, %f8, %f0
		.LVL11:
		.L7:
   57 %end
				jmp	%o7+8
				 fdtos	%f0, %f0
		.LVL12:
		.L11:
   58
   59 !%external %real %fn %spec sqrt %alias "sqrtf" (%real angle)
   60 %real %fn sqrt(%long %real X)
   61   %integer %fn approx integer sqrt(%integer X)
   62     %integer k = 1, result = 1
   63     k = k+1 %and result = k*k %while result <= X
   64     %result = k-1 {note 'off by 1' bug in original C version due to returning k--}
				cmp	%g3, 0
				ble,pn	%icc, .L28
				 mov	1, %g1
		.LVL57:
				cmp	%g3, %g2
				bge,a,pt %icc, .L92
				 add	%g1, 1, %g1
		.LVL60:
		.L28:
		.LBE177:
		.LBE176:
		.LBE180:
		.LBE189:
				add	%g1, -1, %g1
		.LVL61:
		.LBE178:
		.LBE179:
   65   %end
				add	%g1, 1, %g1
		.LVL58:
		.LDL7:
		.L92:
   66   %integer I
				mulx	%g1, %g1, %g2
		.LVL59:
   67   %long %real prev A, A, epsilon = X / 100  {accurate enough due to .14 fixed point}
   68   %if X = 2.0 %then %result = 1.41421356237 %else I = approx integer sqrt(INT PT(X))
				sethi	%hi(.LC43), %g1
				ld	[%g1+%lo(.LC43)], %f8
		.LVL41:
				ld	[%fp+1259], %f9
				fcmps	%fcc3, %f9, %f8
				fbne,pn	%fcc3, .L78
				 nop
		.LVL42:
		.L26:
		.LBE173:
		.LBE172:
				sethi	%hi(.LC38), %g1
				ld	[%g1+%lo(.LC38)], %f8
				fdivs	%f8, %f12, %f12
		.LVL43:
   69   %result = I %if X = I*I { exact root }
				sethi	%hi(.LC39), %g1
		.LVL40:
				ld	[%g1+%lo(.LC39)], %f12
				mulx	%g1, %g1, %g2
				st	%g2, [%fp+1259]
		.LVL62:
				ld	[%fp+1259], %f10
				fitod	%f10, %f10
				fcmpd	%fcc0, %f8, %f10
				fbe,pn	%fcc0, .L79
				 sethi	%hi(.LC44), %g2
		.L30:
   70   ! Newton's method: A{n} = (A{n-1} + X/A{n-1})/2
				ldd	[%g2+%lo(.LC44)], %f16
				fdivd	%f8, %f16, %f16
				st	%g1, [%fp+1259]
				ld	[%fp+1259], %f8
		.LBE182:
		.LBE191:
				ba,pt	%xcc, .L26
				 fitos	%f8, %f12
		.LVL65:
		.L72:
		.L31:
		.L77:
		.L32:
		.LBB192:
		.LBB183:
   71   A = I; prev A = A %and A = (A + X/A)/2.0 %until prev A - epsilon <= A %and A <= prev A + epsilon
				st	%g1, [%fp+1259]
				ld	[%fp+1259], %f10
				fitod	%f10, %f10
		.LVL63:
   72   %result = A
				ba,pt	%xcc, .L26
				 fdtos	%f12, %f12
		.LVL69:
		.L80:
		.LBB193:
   73 %end
   74
				sethi	%hi(.LC40), %g1
		.LBE181:
		.LBE190:
				ba,pt	%xcc, .L77
				 ldd	[%g1+%lo(.LC40)], %f18
		.LVL64:
		.L79:
		.LBB191:
		.LBB182:
				fdivd	%f8, %f10, %f12
				faddd	%f12, %f10, %f12
				fmuld	%f12, %f18, %f12
		.LVL66:
   75 %real PI = atan(1) * 4
				fsubd	%f10, %f16, %f14
				fcmped	%fcc1, %f12, %f14
				fbl,a,pt %fcc1, .L72
				 fmovd	%f12, %f10
   76
				faddd	%f16, %f10, %f14
		.LVL67:
				fcmped	%fcc2, %f12, %f14
				fbug,pt	%fcc2, .L77
				 fmovd	%f12, %f10
		.L34:
		.LVL68:
		.LBE183:
		.LBE192:
				sethi	%hi(.LC52), %g1
				call	ATAN.6057, 0
				 ldd	[%g1+%lo(.LC52)], %f0
		.LVL155:
				sethi	%hi(.LC53), %g1
				ld	[%g1+%lo(.LC53)], %f8
				fmuls	%f0, %f8, %f0
				st	%f0, [%fp-1049]
		.LVL156:
		.LBB234:
   77 %const %integer K64 = 1<<16, K32 = K64>>1, K16 = K32>>1, K8  = K16>>1
   78
   79 %routine phex(%integer x)
				.register	%g7, #ignore
		.LVL19:
				save	%sp, -704, %sp
		.LVL20:
				ldx	[%g7+40], %g1
				stx	%g1, [%fp+2039]
				mov	0, %g1
   80   {%const} %string (16) hex = "0123456789ABCDEF"
   81   %integer i
   82   print symbol(charno(hex, (x >> (i<<2))&15+1)) %for i = 7, -1, 0
   83 %end
				mov	16, %o2
				add	%fp, 1783, %o1
				call	_imp_strncpy, 0
				 add	%fp, 1527, %o0
		.LVL21:
				mov	28, %i5
		.LVL22:
   84
				ldx	[%fp+2039], %g1
				ldx	[%g7+40], %g2
				xor	%g1, %g2, %g1
				mov	0, %g2
				brnz,pn	%g1, .L19
				 nop
				return	%i7+8
				 nop
		.L19:
				call	__stack_chk_fail, 0
				 nop
		.LVL24:
				nop
		.LFE189:
				.section	".rodata"
		.LC20:
				.byte	25
				.asciz	"Oops, missed a case: sin "
				.skip	229
		.LC21:
				.byte	25
				.asciz	"Oops, missed a case: cos "
				.skip	229
				.section	.rodata.cst4,"aM",@progbits,4
				.align 4
		.LC38:
				.long	1065353216
				.align 4
		.LC39:
				.long	1068827891
				.section	.rodata.cst8
				.align 8
		.LC40:
				.long	1071644672
				.long	0
				.align 8
		.LC41:
				.long	1072693248
				.long	0
				.align 8
		.LC42:
				.long	1087373312
				.long	0
				.section	.rodata.cst4
				.align 4
		.LC43:
				.long	1073741824
				.section	.rodata.cst8
				.align 8
		.LC44:
				.long	1079574528
				.long	0
				.section	.rodata.cst4
				.align 4
		.LC45:
				.long	1182793728
				.section	".text"
				.align 4
				.proc	020
		SINCOS.6117:
		.LFB190:
   85 %routine SinCos({unsigned} %integer theta, %integer %name sin, %integer %name cos)
				cmp	%i5, -4
				bne,pt	%icc, .L20
				 srl	%i0, %i5, %g1
		.L16:
		.LVL25:
				save	%sp, -976, %sp
		.LVL26:
				ldx	[%g7+40], %g1
				stx	%g1, [%fp+2039]
				mov	0, %g1
   86   %const %integer QUAD1 = 3, QUAD2 = 2, QUAD3 = 0, QUAD4 = 1   { bit 1 for COS x vs -x,  bit 2 for SIN x vs -x }
   87   %const %integer NBITS = 14                                   { NBITS is number of bits for CORDIC units. }
				srl	%i0, %i5, %g1
		.L20:
				and	%g1, 15, %g1
				add	%fp, 2047, %g2
				add	%g2, %g1, %g1
		.LBB123:
		.LBB124:
				call	_imp_printsymbol, 0
				 ldsb	[%g1-519], %o0
		.LVL23:
		.LDL1:
				add	%i5, -4, %i5
		.LBE124:
		.LBE123:
   88
   89   {unsigned} %const %integer CordicBase = 1 << NBITS                      { base for CORDIC units }
   90   {unsigned} %const %integer HalfBase = CordicBase >> 1                   { CordicBase / 2 }
   91   {unsigned} %const %integer Quad2Boundary = CordicBase << 1              { 2 * CordicBase }
   92   {unsigned} %const %integer Quad3Boundary = CordicBase + Quad2Boundary   { 3 * CordicBase }
   93
   94   ! these owns are initialised on the first call to SinCos:
   95   %own %integer %array ArcTan(0:NBITS-1)                       { angles for rotation }
   96   %own %integer xInit                                          { initial x projection }
   97
   98   %integer xcos,xsin  { used to patch a problem that happens near the zeroes and extremes of the results }
   99
  100   !  USE : Calc sin and cos with integer CORDIC routine.
  101   !  IN  : theta = incoming angle (in CORDIC angle units)
  102   !  OUT : sin (in CORDIC fixed point units)
  103   !        cos (in CORDIC fixed point units)
  104   !  NOTE: The incoming angle theta is in CORDIC angle
  105   !        units, which subdivide the circle into 64K parts,
  106   !        with 0 deg = 0, 90 deg = 16384 (CordicBase), 180 deg
  107   !        = 32768, 270 deg = 49152, etc. The calculated sine
  108   !        and cosine are in CORDIC fixed point units - an int
  109   !        considered as a fraction of 16384 (CordicBase).
  110
  111   %integer quadrant  { quadrant of incoming angle }
  112   %integer z         { incoming angle moved to 1st quad }
  113   %integer i         { to index rotations - one per bit }
  114   %integer x, y      { projections onto axes }
  115   %integer xl, yl    { projections of rotated vector }
  116
  117   %own %integer initialised = 0
  118   %if initialised = 0 %start
				sethi	%hi(INITIALISED.6130), %g1
				lduw	[%g1+%lo(INITIALISED.6130)], %g1
				cmp	%g1, 0
				bne,pt	%icc, .L91
				 sethi	%hi(64512), %g1
		.LBB165:
  119
  120     !   USE : Load globals used by SinCos().
  121     !   OUT : Loads globals used in SinCos() :
  122     !    CordicBase    = base for CORDIC units
  123     !    HalfBase      = Cordicbase / 2
  124     !    Quad2Boundary = 2 * CordicBase
  125     !    Quad3Boundary = 3 * CordicBase
  126     !    ArcTan()      = the arctans of 1/(2^i)
  127     !    xInit         = initial value for x projection
  128     !   NOTE: Must be called once only to initialize before
  129     !    calling SinCos(). xInit is sufficiently less than
  130     !    CordicBase to exactly compensate for the expansion
  131     !    in each rotation.
  132
  133     {%integer i}      { to index ArcTan() }
  134     %real f           { to calc initial x projection }
  135     %integer powr     { powers of 2 up to 2^(2*(NBITS-1)) }
  136
  137     { ArcTans are diminishingly small angles. }
  138     powr = 1
				mov	1, %i4
		.L23:
		.LVL27:
		.LBB170:
				st	%i4, [%fp+1259]
				ld	[%fp+1259], %f8
				fitod	%f8, %f0
				sethi	%hi(.LC41), %g1
				ldd	[%g1+%lo(.LC41)], %f8
				call	ATAN.6057, 0
				 fdivd	%f8, %f0, %f0
		.LVL28:
				fstod	%f0, %f0
		.LVL29:
				ldd	[%fp+1247], %f8
				fdivd	%f0, %f8, %f0
				sethi	%hi(.LC42), %g1
				ldd	[%g1+%lo(.LC42)], %f8
				fmuld	%f0, %f8, %f0
		.LVL30:
		.LBB166:
		.LBB167:
		.LBB168:
		.LBB169:
				sethi	%hi(.LC40), %g1
				ldd	[%g1+%lo(.LC40)], %f8
		.LVL31:
				call	floor, 0
				 faddd	%f0, %f8, %f0
		.LVL32:
				fdtoi	%f0, %f0
				st	%f0, [%i5]
		.LDL2:
		.LVL33:
		.LDL3:
				add	%i5, 4, %i5
		.LBE169:
		.LBE168:
		.LBE167:
		.LBE166:
  139     %for i = 0, 1, NBITS-1 %cycle
  140
  141       ! We could alternatively have created ArcTan as an array of constants at compile time.
  142       ArcTan(i) = INT(atan(1.0/powr)/(PI/2.0)*CordicBase)
				ld	[%g5], %f8
				fstod	%f8, %f8
				sethi	%hi(.LC40), %g1
				ldd	[%g1+%lo(.LC40)], %f10
				fmuld	%f8, %f10, %f8
				std	%f8, [%fp+1247]
				sethi	%hi(ARCTAN.6119), %i5
				or	%i5, %lo(ARCTAN.6119), %i5
				add	%i5, 56, %i3
		.LBE165:
  143       %if debug > 1 %start
  144         print string("Setting ArcTan("); write(i,0); print string(") to "); phex(ArcTan(i)); newline
				cmp	%i5, %i3
				bne,pt	%xcc, .L23
				 add	%i4, %i4, %i4
		.LBE170:
  145       %finish
  146       powr = powr << 1
  147       ! xInit is initial value of x projection to compensate for expansions. f = 1/sqrt(2/1 * 5/4 * ...
  148       ! Normalize as an NBITS binary fraction (multiply by CordicBase) and store in xInit.
  149       ! Get f = 0.607253 and xInit = 9949 = 0x26DD for NBITS = 14.
  150     %repeat
  151     f = 1.0
				sethi	%hi(1065353216), %g1
				st	%g1, [%fp+1259]
				mov	1, %g1
		.LVL34:
		.L24:
		.LBB171:
  152
  153     powr = 1
				mov	14, %g2
  154     %for i = 0, 1, NBITS-1 %cycle
  155       f = (f * (powr + 1)) / powr
				add	%g1, 1, %g3
				st	%g3, [%fp+1247]
				ld	[%fp+1247], %f8
				fitos	%f8, %f8
				ld	[%fp+1259], %f9
				fmuls	%f8, %f9, %f8
				st	%g1, [%fp+1259]
		.LVL35:
				ld	[%fp+1259], %f9
		.LVL36:
				fitos	%f9, %f9
				fdivs	%f8, %f9, %f8
				st	%f8, [%fp+1259]
		.LVL37:
		.LDL4:
		.LDL5:
  156       powr = powr << 2
  157     %repeat
  158
  159     f = 1.0/sqrt(f);              { sqrt is expensive but only done once during initialisation }
				addcc	%g2, -1, %g2
		.LVL38:
				bne,pt	%icc, .L24
				 sll	%g1, 2, %g1
		.L25:
		.LVL39:
		.LBE171:
		.LBB172:
		.LBB173:
				ld	[%fp+1259], %f8
				fstod	%f8, %f8
		.LBB190:
		.LBB181:
		.LBB179:
		.LBB178:
  160                                   { Note could have implemented f = rsqrt(f) instead and been faster }
  161
  162     xInit = INT(CordicBase * f)   { rounding type conversion to fixed point }
				sethi	%hi(.LC45), %g1
				ld	[%g1+%lo(.LC45)], %f8
				fmuls	%f12, %f8, %f8
				fstod	%f8, %f8
		.LVL44:
		.LBB184:
		.LBB185:
		.LBB186:
		.LBB187:
				sethi	%hi(.LC40), %g1
				ldd	[%g1+%lo(.LC40)], %f0
		.LVL45:
				call	floor, 0
				 faddd	%f8, %f0, %f0
		.LVL46:
				fdtoi	%f0, %f0
				sethi	%hi(XINIT.6120), %g1
				st	%f0, [%g1+%lo(XINIT.6120)]
		.LDL6:
		.LBE187:
		.LBE186:
		.LBE185:
		.LBE184:
  163     %if debug # 0 %start
  164       print string("xInit = "); print fl(CordicBase * f, 12)
  165       print string(" = "); write(xInit, 0); newlines(2)
  166     %finish
  167
  168     initialised = 1
				sethi	%hi(INITIALISED.6130), %g1
				mov	1, %g2
				st	%g2, [%g1+%lo(INITIALISED.6130)]
		.L22:
  169   %finish  { initialisation }
  170
  171   ! Determine quadrant of incoming angle, translate to 1st quadrant.
  172   ! Note use of previously calculated values CordicBase, etc. for speed.
  173
  174   theta = theta & (K64-1)  { reduce to a single circle }
				sethi	%hi(64512), %g1
		.L91:
				or	%g1, 1023, %g1
				and	%i0, %g1, %i0
				sra	%i0, 0, %i4
		.LVL47:
  175   %if       theta < CordicBase    %then quadrant = QUAD1 %and z = theta                 %c
				sethi	%hi(15360), %g1
				or	%g1, 1023, %g1
				cmp	%i0, %g1
				ble,pt	%icc, .L35
				 mov	%i0, %g3
		.L36:
  176   %else %if theta < Quad2Boundary %then quadrant = QUAD2 %and z = Quad2Boundary - theta %c
  177   %else %if theta < Quad3Boundary %then quadrant = QUAD3 %and z = theta - Quad2Boundary %c
  178   %else                                 quadrant = QUAD4 %and z = -theta
  179
  180   ! Initialize projections; Negate z, so same rotations taking angle z to 0 will take (x, y) = (xInit, 0) to (cos, sin).
				sethi	%hi(31744), %g1
				or	%g1, 1023, %g1
				cmp	%i0, %g1
				ble,pt	%icc, .L35
				 sub	%g2, %i0, %g3
		.L37:
  181   z = z & (K32-1) { this is a bit dodgy on my part as there *are* cases where z is negative above }
				sethi	%hi(-32768), %g2
				andn	%g3, %g2, %g2
		.LVL50:
  182   x = xInit; y = 0; z = -z
				sethi	%hi(32768), %g2
				sethi	%hi(XINIT.6120), %g1
				lduw	[%g1+%lo(XINIT.6120)], %g5
		.LVL51:
  183
				ba,pt	%xcc, .L39
				 mov	0, %g3
		.LVL53:
		.L78:
		.L27:
		.LBB189:
		.LBB180:
		.LBB174:
		.LBB175:
				call	floorf, 0
				 fmovs	%f9, %f1
		.LVL54:
				fstoi	%f0, %f8
				st	%f8, [%fp+1247]
		.LVL55:
				lduw	[%fp+1247], %g3
		.LVL56:
		.LBE175:
		.LBE174:
		.LBB176:
		.LBB177:
  184   %for i = 0, 1, NBITS-1 %cycle                                                    { Rotate NBITS times. }
				sub	%g0, %g2, %g2
		.LVL52:
				sethi	%hi(ARCTAN.6119), %g4
				or	%g4, %lo(ARCTAN.6119), %g4
		.LBB188:
				mov	-1, %g1
		.LBE188:
  185     %if z < 0 %then z = z+ArcTan(i) %and yl = y + (x >> i) %and xl = x - (y >> i)  { Counter-clockwise rotation. } %c
				sethi	%hi(48128), %g1
				or	%g1, 1023, %g1
				cmp	%i0, %g1
				bg,pt	%icc, .L35
				 sub	%g0, %i0, %g3
		.LVL48:
				cmp	%g2, 0
				bl,pn	%icc, .L80
				 add	%g1, 1, %g1
		.L41:
  186     %else z = z-ArcTan(i) %and yl = y - (x >> i) %and xl = x + (y >> i)            { Clockwise rotation. }
				lduw	[%g4], %i5
				add	%g2, %i5, %g2
		.LVL70:
				mov	%g3, %i5
				srl	%g5, %g1, %i3
				add	%i3, %g3, %g3
		.LVL71:
  187     x = xl; y = yl                                                                 { Put new projections into (x,y) for next go. }
				sethi	%hi(-32768), %g2
				add	%i0, %g2, %g3
		.LVL49:
		.L38:
		.L35:
  188   %repeat
				srl	%i5, %g1, %i5
		.LVL72:
				sub	%g5, %i5, %g5
		.LVL73:
		.L42:
  189
				cmp	%g1, 13
				be,pn	%icc, .L40
				 add	%g4, 4, %g4
		.LVL74:
		.L39:
  190   %if quadrant&1 # 0 %then cos = x %else cos = -x  { Attach signs depending on quadrant. }
  191   %if quadrant&4 # 0 %then sin = y %else sin = -y
				lduw	[%g4], %i5
				sub	%g2, %i5, %g2
		.LVL75:
				st	%g5, [%i2]
		.LDL8:
		.LDL9:
		.LVL79:
  192
				mov	%g3, %i5
				srl	%g5, %g1, %i3
				sub	%g3, %i3, %g3
		.LVL76:
				sub	%g0, %g3, %g1
		.LVL80:
				sethi	%hi(31744), %g2
		.LVL81:
				or	%g2, 1023, %g2
				cmp	%i0, %g2
		.L44:
  193   xsin=sin {debug}
				srl	%i5, %g1, %i5
		.LVL77:
		.LBE193:
				ba,pt	%xcc, .L42
				 add	%i5, %g5, %g5
		.LVL78:
		.L40:
  194   sin = -sin %if Theta < K32
  195   sin = sin & (K64-1); sin = sin!(\(K16-1)) %if sin > K16
				movg	%icc, %g3, %g1
				sethi	%hi(64512), %g2
				or	%g2, 1023, %g2
				and	%g1, %g2, %g1
				sethi	%hi(-16384), %g2
				or	%g1, %g2, %g2
				sethi	%hi(16384), %g4
				cmp	%g1, %g4
				movle	%icc, %g1, %g2
				st	%g2, [%i1]
		.L46:
  196
  197   xcos=cos {debug}
				lduw	[%i2], %g4
		.LVL82:
  198   cos = cos & (K64-1); cos = cos!(\(K16-1)) %if cos > K16
				sethi	%hi(64512), %g1
				or	%g1, 1023, %g1
				and	%g4, %g1, %g1
				sethi	%hi(-16384), %g2
				or	%g1, %g2, %g2
				sethi	%hi(16384), %g5
		.LVL83:
				cmp	%g1, %g5
				movle	%icc, %g1, %g2
		.L49:
  199
  200   %if debug > 1 %start
  201     print string("                  Theta ="); write(theta*1608//1024,8)
  202     print string("; SIN(Theta) = "); phex(xsin);
  203     print string("; COS(Theta) = "); phex(xcos);
  204     newline
  205   %finish
  206
  207   ! There is a bug in this implementation that fails near multiples of 90 degrees -
  208   ! this test catches the broken cases and uses an approximation to repair the results :-(
  209   ! I will remove these hacks later, if I ever find and fix the bug properly!
  210   ! My suspicion is of overflow of a partial 16x16 multiplication somewhere, or maybe a '<<'.
  211   %if xsin&16_FFFFC000 # 16_FFFFC000 %and xsin&16_FFFFC000 # 0 %then %start
				andcc	%g3, 1, %g0
				bne,pt	%xcc, .L61
				 st	%g2, [%i2]
		.L48:
  212     %if                  theta < 16_0400 %start
				cmp	%i0, 1023
				bg,pt	%icc, .L51
				 sethi	%hi(-15360), %g1
  213       sin = theta*1608//1024
				mulx	%i0, 1608, %i0
		.LVL84:
				sra	%i0, 10, %i0
  214     %else %if 16_3C00 <= theta < 16_4000
  215       sin = K16 - (16_4000-theta)//25
				sethi	%hi(16384), %g2
				sub	%g2, %i0, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sub	%g2, %g1, %g1
				st	%g1, [%i1]
		.L52:
		.L68:
		.L55:
  216     %else %if 16_4000 <= theta < 16_4400
  217       sin = K16 - (theta-16_4000)//25
				sethi	%hi(-16384), %g1
				add	%i0, %g1, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(16384), %g2
				sub	%g2, %g1, %g1
  218     %else %if 16_7C00 <= theta < 16_8400
				ba,pt	%xcc, .L55
				 st	%g1, [%i1]
		.LVL93:
		.L84:
  219       sin = (16_8000-theta)*1608//1024
				sethi	%hi(32768), %g1
				sub	%g1, %i0, %g1
				mulx	%g1, 1608, %g1
				add	%g1, 1023, %g2
				cmp	%g1, 0
				movl	%icc, %g2, %g1
				sra	%g1, 10, %g1
  220     %else %if 16_BC00 <= theta < 16_C000
				ba,pt	%xcc, .L55
				 st	%g1, [%i1]
		.LVL94:
		.L85:
  221       sin = -K16 + (16_C000-theta)//25
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L82
				 sethi	%hi(-16384), %g1
		.L54:
		.LVL87:
		.LBE194:
		.LBB195:
				sethi	%hi(49152), %g1
				sub	%g1, %i0, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(-16384), %g2
				add	%g1, %g2, %g1
  222     %else %if 16_C000 <= theta < 16_C400
				ba,pt	%xcc, .L55
				 st	%g1, [%i1]
		.LVL95:
		.L86:
  223       sin = -K16 + (theta-16_C000)//25
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L83
				 sethi	%hi(-31744), %g1
		.L56:
		.LVL88:
		.LBE195:
		.LBB196:
				sethi	%hi(-49152), %g1
				add	%i0, %g1, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(-16384), %g2
				add	%g1, %g2, %g1
  224     %else %if 16_FC00 <= theta
				ba,pt	%xcc, .L55
				 st	%g1, [%i1]
		.L60:
		.LBB199:
  225       sin = -(16_10000-theta)*1608//1024
				add	%i0, %g1, %g1
				cmp	%g1, 2047
				bleu,pn	%icc, .L84
				 sethi	%hi(-48128), %g1
		.L57:
		.LVL89:
		.LBE196:
		.LBB197:
				sub	%g1, %i0, %g1
				mulx	%g1, 1608, %g1
				add	%g1, 1023, %g2
				cmp	%g1, 0
				movl	%icc, %g2, %g1
				sra	%g1, 10, %g1
				sub	%g0, %g1, %g1
  226     %else
				or	%g1, 1023, %g1
				cmp	%i0, %g1
				ble,pn	%icc, .L60
				 sethi	%hi(65536), %g1
				ba,pt	%xcc, .L55
				 st	%g1, [%i1]
		.LVL91:
		.L82:
  227       print string("Oops, missed a case: sin "); phex(theta); newline; %stop
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L85
				 sethi	%hi(-49152), %g1
		.L58:
		.LVL90:
		.LBE197:
		.LBB198:
				mov	256, %o2
				sethi	%hi(.LC20), %o1
				or	%o1, %lo(.LC20), %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL96:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, 1527, %o0
		.LVL97:
				mov	256, %o2
				add	%fp, 1527, %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL98:
		.LBE199:
		.LBB200:
		.LBB201:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, 1263, %o0
		.LVL99:
				call	_imp_printstring, 0
				 add	%fp, 1263, %o0
		.LVL100:
		.LBE201:
		.LBE200:
  228     %finish
				call	PHEX.6104, 0
				 mov	%i4, %o0
		.LVL101:
		.LBB202:
		.LBB203:
				call	_imp_newline, 0
				 nop
		.LVL102:
		.LBE203:
		.LBE202:
		.LBB204:
		.LBB205:
				call	exit, 0
				 mov	0, %o0
		.LVL103:
		.L50:
		.L61:
		.LBE205:
		.LBE204:
  229   %finish
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L86
				 sethi	%hi(63488), %g1
		.L59:
		.LBE198:
  230
  231   %if xcos&16_FFFFC000 # 16_FFFFC000 %and xcos&16_FFFFC000 # 0 %then %start
				andcc	%g4, 1, %g0
				bne,pn	%xcc, .L21
				 st	%i0, [%i1]
		.L53:
				andcc	%g4, 1, %g0
				be,pt	%xcc, .L93
				 sethi	%hi(-15360), %g1
				ba,pt	%xcc, .L21
				 nop
		.LVL92:
		.L83:
				andcc	%g4, 1, %g0
				bne,pn	%xcc, .L21
				 cmp	%i0, 1023
  232     %if                  theta < 16_0400 %start
				ble,pn	%icc, .L53
				 sethi	%hi(-15360), %g1
		.L62:
		.LVL104:
		.L93:
		.LBB206:
  233       cos = K16 - (theta)//25
				sdivx	%i4, 25, %i4
		.LVL85:
				sethi	%hi(16384), %g1
				sub	%g1, %i4, %i4
				st	%i4, [%i2]
		.L21:
  234     %else %if 16_3C00 <= theta < 16_4400
  235       cos = (16_4000-theta)*1608//1024
				sethi	%hi(16384), %g1
				sub	%g1, %i0, %g1
				mulx	%g1, 1608, %g1
				add	%g1, 1023, %g2
				cmp	%g1, 0
				movl	%icc, %g2, %g1
				sra	%g1, 10, %g1
  236     %else %if 16_7C00 <= theta < 16_8000
				ba,pt	%xcc, .L21
				 st	%g1, [%i2]
		.LVL109:
		.L88:
  237       cos = -K16 + (16_8000-theta)//25
				sethi	%hi(32768), %g1
				sub	%g1, %i0, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(-16384), %g2
				add	%g1, %g2, %g1
  238     %else %if 16_8000 <= theta < 16_8400
				ba,pt	%xcc, .L21
				 st	%g1, [%i2]
		.LVL110:
		.L89:
  239       cos = -K16 + (theta-16_8000)//25
				sethi	%hi(-32768), %g1
				add	%i0, %g1, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(-16384), %g2
				add	%g1, %g2, %g1
  240     %else %if 16_BC00 <= theta < 16_C400
				ba,pt	%xcc, .L21
				 st	%g1, [%i2]
		.LVL111:
		.L90:
  241       cos = (theta-16_C000)*1608//1024
				add	%i0, %g1, %g1
				cmp	%g1, 2047
				bleu,pn	%icc, .L87
				 sethi	%hi(-31744), %g1
		.L63:
		.LVL105:
		.LBE206:
		.LBB207:
				sethi	%hi(-49152), %g1
				add	%i0, %g1, %g1
				mulx	%g1, 1608, %g1
				add	%g1, 1023, %g2
				cmp	%g1, 0
				movl	%icc, %g2, %g1
				sra	%g1, 10, %g1
  242     %else %if 16_FC00 <= theta
				ba,pt	%xcc, .L21
				 st	%g1, [%i2]
		.L67:
		.LBB210:
  243       cos = K16 - (16_10000-theta)//25
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L88
				 sethi	%hi(-32768), %g1
		.L64:
		.LVL106:
		.LBE207:
		.LBB208:
				sub	%g1, %i0, %g1
				sra	%g1, 0, %g1
				sdivx	%g1, 25, %g1
				sethi	%hi(16384), %g2
				sub	%g2, %g1, %g1
  244     %else
				or	%g1, 1023, %g1
				cmp	%i0, %g1
				ble,pn	%icc, .L67
				 sethi	%hi(65536), %g1
				ba,pt	%xcc, .L21
				 st	%g1, [%i2]
		.LVL108:
		.L87:
  245       print string("Oops, missed a case: cos "); phex(theta); newline; %stop
				add	%i0, %g1, %g1
				cmp	%g1, 1023
				bleu,pn	%icc, .L89
				 sethi	%hi(-48128), %g1
		.L65:
		.LVL107:
		.LBE208:
		.LBB209:
				mov	256, %o2
				sethi	%hi(.LC21), %o1
				or	%o1, %lo(.LC21), %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL112:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, 1527, %o0
		.LVL113:
				mov	256, %o2
				add	%fp, 1527, %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL114:
		.LBE210:
		.LBB211:
		.LBB212:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, 1263, %o0
		.LVL115:
				call	_imp_printstring, 0
				 add	%fp, 1263, %o0
		.LVL116:
		.LBE212:
		.LBE211:
  246     %finish
				call	PHEX.6104, 0
				 mov	%i4, %o0
		.LVL117:
		.LBB213:
		.LBB214:
				call	_imp_newline, 0
				 nop
		.LVL118:
		.LBE214:
		.LBE213:
		.LBB215:
		.LBB216:
				call	exit, 0
				 mov	0, %o0
		.LVL119:
		.L81:
		.LBE216:
		.LBE215:
				call	__stack_chk_fail, 0
				 nop
		.LVL120:
				nop
		.LFE190:
				.section	.rodata.cst4
				.align 4
		.LC48:
				.long	0
				.align 4
		.LC49:
				.long	1092616192
				.section	.rodata.cst8
				.align 8
		.LC50:
				.long	1071644672
				.long	0
				.align 8
		.LC51:
				.long	1051772663
				.long	-1598689907
				.section	".text"
				.align 4
				.proc	020
		PROUND.6230:
		.LFB191:
  247   %finish
				add	%i0, %g1, %g1
				cmp	%g1, 2047
				bleu,pn	%icc, .L90
				 sethi	%hi(63488), %g1
		.L66:
		.LBE209:
  248 %end
?HALFBASE unused
  249
				ldx	[%fp+2039], %g1
				ldx	[%g7+40], %g2
				xor	%g1, %g2, %g1
				mov	0, %g2
				brnz,pn	%g1, .L81
				 nop
				return	%i7+8
				 nop
		.LVL86:
		.L51:
		.LBB194:
  250 %external %real %fn %spec sin %alias "sinf" (%real angle)  ;! use C's math lib to check results.
  251 %external %real %fn %spec cos %alias "cosf" (%real angle)
  252
  253 %real Theta
  254 %integer i, sinTheta, cosTheta, CheckSinTheta, CheckCosTheta, sinErr = 0, cosErr = 0, err
  255
  256 %routine pround(%integer f, n)
		.LVL121:
				save	%sp, -192, %sp
		.LVL122:
  257   ! This is a quick (and rather ugly) hack due to the current Imp compiler
  258   ! not implementing all of the usual floating point I/O library calls yet
  259
  260   %real r, sign = 1.0
  261   %integer tens = 0, p
  262
				sethi	%hi(1065353216), %g1
				ba,pt	%xcc, .L98
				 mov	0, %i4
		.LVL126:
		.L108:
				sub	%g0, %i0, %i0
				sra	%i0, 0, %i0
		.LVL127:
  263   %if f=0 %start
				brz,pt	%i0, .L95
				 mov	0, %i5
		.L96:
  264     r = 0
				st	%g0, [%fp+2043]
		.LVL148:
		.L102:
		.LBB230:
		.LBB231:
				call	_imp_printsymbol, 0
				 mov	32, %o0
		.LVL149:
		.L103:
		.LBE231:
		.LBE230:
				add	%i5, 2, %o1
		.L109:
		.LBB232:
		.LBB233:
				sra	%o1, 0, %o1
				ld	[%fp+2043], %f8
		.LVL150:
				call	_imp_printfl, 0
				 fstod	%f8, %f0
		.LVL151:
		.LBE233:
		.LBE232:
  265   %else
  266     f = -f %and sign = -1.0 %if f < 0
				cmp	%i0, 0
				bl,pn	%icc, .L108
				 st	%g1, [%fp+2035]
		.LVL123:
		.L97:
  267     r = f / K16
				sethi	%hi(15360), %g1
				or	%g1, 1023, %g1
				add	%g1, %i0, %g1
				cmp	%i0, 0
				movl	%icc, %g1, %i0
		.LVL124:
				sra	%i0, 14, %i0
				st	%i0, [%fp+2043]
				ld	[%fp+2043], %f8
				fitos	%f8, %f8
				st	%f8, [%fp+2043]
		.LVL125:
  268     r = r * 10.0 %and tens = tens+1 %until 100 <= INT PT(r) < 1000
				sethi	%hi(-1082130432), %g1
				or	%g1, %lo(-1082130432), %g1
				ba,pt	%xcc, .L97
				 st	%g1, [%fp+2035]
		.LVL128:
		.L105:
		.L98:
  269     p = tens
				sethi	%hi(.LC49), %g1
				ld	[%fp+2043], %f8
				ld	[%g1+%lo(.LC49)], %f9
				fmuls	%f8, %f9, %f8
				st	%f8, [%fp+2043]
		.LVL129:
  270     r = INT(r)  { round to 3 significant digits }
				add	%i4, 1, %i5
		.LVL130:
		.LBB217:
		.LBB218:
		.LBB219:
				call	floorf, 0
				 fmovs	%f8, %f1
		.LVL131:
				fstoi	%f0, %f0
		.LBE219:
		.LBE218:
				mov	%i5, %g1
  271     r = r / 10.0 %and tens = tens-1 %while tens > 0
  272     r = r + 0.000001 { handle real values not exactly representable in decimal }
				cmp	%i5, 0
				ble,pn	%icc, .L100
				 fitos	%f8, %f8
				addcc	%g1, -1, %g1
		.LVL138:
				bne,pt	%icc, .L101
				 fdivs	%f8, %f9, %f8
		.LVL139:
		.L100:
				fstod	%f8, %f8
		.LVL140:
				sethi	%hi(.LC51), %g1
				ldd	[%g1+%lo(.LC51)], %f10
				faddd	%f8, %f10, %f8
				fdtos	%f8, %f8
				st	%f8, [%fp+2043]
		.LDL11:
		.LVL141:
  273   %finish
				sethi	%hi(.LC49), %g2
				ld	[%g2+%lo(.LC49)], %f9
		.LVL137:
		.L101:
		.LDL10:
  274   spaces(n - (p+3))
				ld	[%fp+2043], %f8
				fstod	%f8, %f8
		.LVL133:
		.LBE217:
		.LBB220:
		.LBB221:
		.LBB222:
		.LBB223:
				sethi	%hi(.LC50), %g1
				ldd	[%g1+%lo(.LC50)], %f0
		.LVL134:
				call	floor, 0
				 faddd	%f8, %f0, %f0
		.LVL135:
				fdtoi	%f0, %f8
		.LVL136:
		.LBE223:
		.LBE222:
		.LBE221:
		.LBE220:
				add	%i4, 4, %i4
		.LVL142:
				sub	%i1, %i4, %i4
		.LBB224:
		.LBB225:
				call	_imp_spaces, 0
				 sra	%i4, 0, %o0
		.LVL143:
		.LBE225:
		.LBE224:
				add	%i1, -3, %o0
		.LBB229:
		.LBB226:
				call	_imp_spaces, 0
				 sra	%o0, 0, %o0
		.LVL147:
		.LBE226:
		.LBE229:
  275   %if sign < 0 %then print symbol('-') %else print symbol(' ')
				sethi	%hi(.LC48), %g1
				ld	[%g1+%lo(.LC48)], %f8
				ld	[%fp+2035], %f9
				fcmpes	%fcc3, %f9, %f8
				fbge,pn	%fcc3, .L102
				 nop
		.LVL144:
		.LBB227:
		.LBB228:
				call	_imp_printsymbol, 0
				 mov	45, %o0
		.LVL145:
		.LBE228:
		.LBE227:
				ba,pt	%xcc, .L109
				 add	%i5, 2, %o1
		.LVL146:
		.L95:
  276   print fl(r, p+2) { library call truncates, doesn't round :-( }
				st	%f0, [%fp+2039]
				lduw	[%fp+2039], %g1
				add	%g1, -100, %g1
				cmp	%g1, 899
				bgu,a,pt %icc, .L105
				 mov	%i5, %i4
		.L99:
		.LVL132:
  277 %end
  278
				return	%i7+8
				 nop
		.LFE191:
				.section	".rodata"
		.LC0:
				.byte	82
				.asciz	"Note: this CORDIC was implemented to only 14 bits of accuracy for 16 bit machines,"
				.skip	172
		.LC1:
				.byte	56
				.asciz	"      so we will report results to 3 significant digits."
				.skip	198
		.LC2:
				.byte	22
				.asciz	"sin and cos of  -9 is "
				.skip	232
		.LC3:
				.byte	22
				.asciz	"sin and cos of   0 is "
				.skip	232
		.LC4:
				.byte	22
				.asciz	"sin and cos of 1.5 is "
				.skip	232
		.LC5:
				.byte	22
				.asciz	"sin and cos of   6 is "
				.skip	232
				.section	.rodata.cst8
				.align 8
		.LC52:
				.long	1072693248
				.long	0
				.section	.rodata.cst4
				.align 4
		.LC53:
				.long	1082130432
				.align 4
		.LC54:
				.long	1225785344
				.section	.rodata.cst8
				.align 8
		.LC55:
				.long	1071644672
				.long	0
				.section	.rodata.cst4
				.align 4
		.LC56:
				.long	0
				.section	.rodata.cst8
				.align 8
		.LC57:
				.long	1089994752
				.long	0
				.section	.rodata.cst4
				.align 4
		.LC58:
				.long	1220542464
				.section	".text"
				.align 4
				.global main
				.proc	04
		main:
		.LFB185:
  279   ! We get about 3 significant digits of accuracy
  280   print string("Note: this CORDIC was implemented to only 14 bits of accuracy for 16 bit machines,"); newline
				mov	256, %o2
				sethi	%hi(.LC0), %o1
				or	%o1, %lo(.LC0), %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL157:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, -1033, %o0
		.LVL158:
				mov	256, %o2
				add	%fp, -1033, %o1
				call	memcpy, 0
				 add	%fp, 1783, %o0
		.LVL159:
		.LBE234:
		.LBB235:
		.LBB236:
				mov	256, %o2
				add	%fp, 1783, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL160:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL161:
		.LBE236:
		.LBE235:
		.LBB237:
		.LBB238:
				call	_imp_newline, 0
				 sethi	%hi(.LC55), %i1
		.LVL162:
		.LBE238:
		.LBE237:
		.LBB239:
  281   print string("      so we will report results to 3 significant digits."); newlines(2)
				mov	256, %o2
				sethi	%hi(.LC1), %o1
				or	%o1, %lo(.LC1), %o1
				call	memcpy, 0
				 add	%fp, 1527, %o0
		.LVL163:
				mov	256, %o2
				add	%fp, 1527, %o1
				call	memcpy, 0
				 add	%fp, -777, %o0
		.LVL164:
				mov	256, %o2
				add	%fp, -777, %o1
				call	memcpy, 0
				 add	%fp, 1527, %o0
		.LVL165:
		.LBE239:
		.LBB240:
		.LBB241:
				mov	256, %o2
				add	%fp, 1527, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL166:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL167:
		.LBE241:
		.LBE240:
		.LBB242:
		.LBB243:
				call	_imp_newlines, 0
				 mov	2, %o0
		.LVL168:
		.LBE243:
		.LBE242:
  282
  283   SinCos(INT(-9*K64/(2*PI)), sinTheta, cosTheta)
				ld	[%fp-1049], %f0
				fadds	%f0, %f0, %f8
				sethi	%hi(.LC54), %g1
				ld	[%g1+%lo(.LC54)], %f0
				fdivs	%f0, %f8, %f0
				fstod	%f0, %f0
		.LVL169:
		.LBB244:
		.LBB245:
		.LBB246:
				ldd	[%i1+%lo(.LC55)], %f8
				call	floor, 0
				 fsubd	%f8, %f0, %f0
		.LVL170:
				fdtoi	%f0, %f0
		.LBE246:
		.LBE245:
		.LBE244:
				add	%fp, -1049, %g5
				add	%fp, -1053, %o2
				add	%fp, -1057, %o1
				st	%f0, [%fp-1317]
				call	SINCOS.6117, 0
				 ldsw	[%fp-1317], %o0
		.LVL171:
		.LBB247:
  284   printstring("sin and cos of  -9 is "); pround(sinTheta,6); space; pround(cosTheta,6); newline
				mov	256, %o2
				sethi	%hi(.LC2), %o1
				or	%o1, %lo(.LC2), %o1
				call	memcpy, 0
				 add	%fp, 1271, %o0
		.LVL172:
				mov	256, %o2
				add	%fp, 1271, %o1
				call	memcpy, 0
				 add	%fp, -521, %o0
		.LVL173:
				mov	256, %o2
				add	%fp, -521, %o1
				call	memcpy, 0
				 add	%fp, 1271, %o0
		.LVL174:
		.LBE247:
		.LBB248:
		.LBB249:
				mov	256, %o2
				add	%fp, 1271, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL175:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL176:
		.LBE249:
		.LBE248:
  285
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1057], %o0
		.LVL177:
		.LBB250:
		.LBB251:
				call	_imp_space, 0
				 nop
		.LVL178:
		.LBE251:
		.LBE250:
  286   SinCos(INT(0*K64/(2*PI)), sinTheta, cosTheta)
				ld	[%fp-1049], %f0
				fadds	%f0, %f0, %f8
				sethi	%hi(.LC56), %g1
				ld	[%g1+%lo(.LC56)], %f0
				fdivs	%f0, %f8, %f0
				fstod	%f0, %f0
		.LBB254:
		.LBB255:
		.LBB256:
		.LBB257:
				ldd	[%i1+%lo(.LC55)], %f8
				call	floor, 0
				 faddd	%f0, %f8, %f0
		.LVL181:
				fdtoi	%f0, %f0
		.LBE257:
		.LBE256:
		.LBE255:
		.LBE254:
				add	%fp, -1049, %g5
				add	%fp, -1053, %o2
				add	%fp, -1057, %o1
				st	%f0, [%fp-1317]
				call	SINCOS.6117, 0
				 ldsw	[%fp-1317], %o0
		.LVL182:
		.LBB258:
				mov	256, %o2
				sethi	%hi(.LC3), %o1
				or	%o1, %lo(.LC3), %o1
				call	memcpy, 0
				 add	%fp, 1015, %o0
		.LVL183:
				mov	256, %o2
				add	%fp, 1015, %o1
				call	memcpy, 0
				 add	%fp, -265, %o0
		.LVL184:
				mov	256, %o2
				add	%fp, -265, %o1
				call	memcpy, 0
				 add	%fp, 1015, %o0
		.LVL185:
		.LBE258:
		.LBB259:
		.LBB260:
				mov	256, %o2
				add	%fp, 1015, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL186:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL187:
		.LBE260:
		.LBE259:
  287   printstring("sin and cos of   0 is "); pround(sinTheta,6); space; pround(cosTheta,6); newline
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1053], %o0
		.LVL179:
		.LBB252:
		.LBB253:
				call	_imp_newline, 0
				 nop
		.LVL180:
		.LBE253:
		.LBE252:
  288
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1057], %o0
		.LVL188:
		.LBB261:
		.LBB262:
				call	_imp_space, 0
				 nop
		.LVL189:
		.LBE262:
		.LBE261:
  289   SinCos(INT(1.5*K64/(2*PI)), sinTheta, cosTheta)
				ld	[%fp-1049], %f0
				fadds	%f0, %f0, %f0
				fstod	%f0, %f0
				sethi	%hi(.LC57), %g1
				ldd	[%g1+%lo(.LC57)], %f8
				fdivd	%f8, %f0, %f0
		.LBB265:
		.LBB266:
		.LBB267:
		.LBB268:
				ldd	[%i1+%lo(.LC55)], %f8
				call	floor, 0
				 faddd	%f0, %f8, %f0
		.LVL192:
				fdtoi	%f0, %f0
		.LBE268:
		.LBE267:
		.LBE266:
		.LBE265:
				add	%fp, -1049, %g5
				add	%fp, -1053, %o2
				add	%fp, -1057, %o1
				st	%f0, [%fp-1317]
				call	SINCOS.6117, 0
				 ldsw	[%fp-1317], %o0
		.LVL193:
		.LBB269:
				mov	256, %o2
				sethi	%hi(.LC4), %o1
				or	%o1, %lo(.LC4), %o1
				call	memcpy, 0
				 add	%fp, 759, %o0
		.LVL194:
				mov	256, %o2
				add	%fp, 759, %o1
				call	memcpy, 0
				 add	%fp, -9, %o0
		.LVL195:
				mov	256, %o2
				add	%fp, -9, %o1
				call	memcpy, 0
				 add	%fp, 759, %o0
		.LVL196:
		.LBE269:
		.LBB270:
		.LBB271:
				mov	256, %o2
				add	%fp, 759, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL197:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL198:
		.LBE271:
		.LBE270:
  290   printstring("sin and cos of 1.5 is "); pround(sinTheta,6); space; pround(cosTheta,6); newline
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1053], %o0
		.LVL190:
		.LBB263:
		.LBB264:
				call	_imp_newline, 0
				 nop
		.LVL191:
		.LBE264:
		.LBE263:
  291
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1057], %o0
		.LVL199:
		.LBB272:
		.LBB273:
				call	_imp_space, 0
				 nop
		.LVL200:
		.LBE273:
		.LBE272:
  292   SinCos(INT(6*K64/(2*PI)), sinTheta, cosTheta)
				ld	[%fp-1049], %f0
				fadds	%f0, %f0, %f8
				sethi	%hi(.LC58), %g1
				ld	[%g1+%lo(.LC58)], %f0
				fdivs	%f0, %f8, %f0
				fstod	%f0, %f0
		.LBB276:
		.LBB277:
		.LBB278:
		.LBB279:
				ldd	[%i1+%lo(.LC55)], %f8
				call	floor, 0
				 faddd	%f0, %f8, %f0
		.LVL203:
				fdtoi	%f0, %f0
		.LBE279:
		.LBE278:
		.LBE277:
		.LBE276:
				add	%fp, -1049, %g5
				add	%fp, -1053, %o2
				add	%fp, -1057, %o1
				st	%f0, [%fp-1317]
				call	SINCOS.6117, 0
				 ldsw	[%fp-1317], %o0
		.LVL204:
		.LBB280:
				mov	256, %o2
				sethi	%hi(.LC5), %o1
				or	%o1, %lo(.LC5), %o1
				call	memcpy, 0
				 add	%fp, 503, %o0
		.LVL205:
				mov	256, %o2
				add	%fp, 503, %o1
				call	memcpy, 0
				 add	%fp, 247, %o0
		.LVL206:
				mov	256, %o2
				add	%fp, 247, %o1
				call	memcpy, 0
				 add	%fp, 503, %o0
		.LVL207:
		.LBE280:
		.LBB281:
		.LBB282:
				mov	256, %o2
				add	%fp, 503, %o1
				call	memcpy, 0
				 add	%fp, -1313, %o0
		.LVL208:
				call	_imp_printstring, 0
				 add	%fp, -1313, %o0
		.LVL209:
		.LBE282:
		.LBE281:
  293   printstring("sin and cos of   6 is "); pround(sinTheta,6); space; pround(cosTheta,6); newline
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1053], %o0
		.LVL201:
		.LBB274:
		.LBB275:
				call	_imp_newline, 0
				 nop
		.LVL202:
		.LBE275:
		.LBE274:
  294
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1057], %o0
		.LVL210:
		.LBB283:
		.LBB284:
				call	_imp_space, 0
				 nop
		.LVL211:
		.LBE284:
		.LBE283:
  295
  296   %if debug # 0 %start
				mov	6, %o1
				call	PROUND.6230, 0
				 ldsw	[%fp-1053], %o0
		.LVL212:
		.LBB285:
		.LBB286:
				call	_imp_newline, 0
				 nop
		.LVL213:
		.LDL12:
		.LBE286:
		.LBE285:
		.LBB287:
		.LBB288:
				call	exit, 0
				 mov	0, %o0
		.LVL214:
		.LBE288:
		.LBE287:
				nop
		.LFE185:
				.common	XINIT.6120,4,4
				.common	ARCTAN.6119,56,4
				.common	INITIALISED.6130,4,4
		.Letext0:
  297     %for i = 0, 4096, K64 %cycle  { A circle is 64K units }
  298       Theta = i*2*PI/K64 { A circle is 2Pi radians }
  299
  300       SinCos(i, sinTheta, cosTheta)
  301
  302       print string("Cordic:         Theta = "); phex(i)
  303       print string("; Sin(Theta) = "); write(sinTheta, 0)
  304       print string("; Cos(Theta) = "); write(cosTheta, 0)
  305       newline;
  306
  307       CheckSinTheta = INT(sin(Theta)*K16); CheckCosTheta = INT(cos(Theta)*K16);
  308
  309       print string("Floating point: Theta = "); phex(INT(Theta/(2*PI)*K64))
  310       print string("; Sin(Theta) = "); write(CheckSinTheta, 0)
  311       print string("; Cos(Theta) = "); write(CheckCosTheta, 0)
  312       newlines(2)
  313
  314       err = CheckSinTheta - sinTheta; err = -err %if err < 0; sinErr = sinErr + err
  315       err = CheckCosTheta - cosTheta; err = -err %if err < 0; cosErr = cosErr + err
  316
  317     %repeat
  318
  319     { Use this to test if algorithmic tweaks improve the accuracy }
  320     print string("Cumulative error:  sin = "); write(sinErr, 0)
  321     print string(",  cos = "); write(cosErr, 0)
  322     newline
  323
  324   %finish
  325 %end %of %program
?K8 unused
  253 Statements compiled
