;
; Mesa 3-D graphics library
; Version:  2.5
; Copyright (C) 1995-1997  Brian Paul
;
; This library is free software; you can redistribute it and/or
; modify it under the terms of the GNU Library General Public
; License as published by the Free Software Foundation; either
; version 2 of the License, or (at your option) any later version.
;
; This library is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
; Library General Public License for more details.
;
; You should have received a copy of the GNU Library General Public
; License along with this library; if not, write to the Free
; Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;

;   xform_asm68k.s
;   2.12.1998 by Sam Jordan
;
;   68K assembler optimizations of several functions in xform.c
;   Originally written for AMIGA OS. To use this source on other 68K
;   based platforms some modifications might be needed.

		XDEF    _gl_xform_normals_3fv

		mc68040

_gl_xform_normals_3fv

;
; void gl_xform_normals_3fv( GLuint n, GLfloat v[][3], const GLfloat m[16],
;                            GLfloat u[][3], GLboolean normalize,
;                            GLboolean rescale )


		rsreset
.fpuregs        rs.x    8
.intregs        rs.l    1
		rs.l    1
.n              rs.l    1
.v              rs.l    1
.m              rs.l    1
.u              rs.l    1
.normalize      rs.b    1
		rs.b    1
.rescale        rs.b    1
		rs.b    1

		movem.l a2,-(sp)
		fmovem.x        fp0-fp7,-(sp)
		move.l  .n(sp),d0
		beq     .end
		move.l  .u(sp),a0
		move.l  .v(sp),a1
		move.l  .m(sp),a2

;         GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
;         GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
;         GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];

		fmove.s 2*4(a2),fp0             ;fp0 = m[2]
		fmove.s 6*4(a2),fp1             ;fp1 = m[6]
		fmove.s 10*4(a2),fp2            ;fp2 = m[10]

;   if (normalize) {

		tst.b   .normalize(sp)
		beq.b   .notnormalized

;      if (rescale) {

		tst.b   .rescale(sp)
		beq.b   .notrescaled1

;         GLfloat f = GL_SQRT( m2*m2 + m6*m6 + m10*m10 );

		fmove   fp0,fp6
		fmul    fp6,fp6
		fmove   fp1,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fmove   fp2,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fsqrt   fp6

;         f = (f == 0.0F) ? 1.0F : (1.0F / f);

		ftst    fp6
		bne     .notzero1
		fmove.s #1.0,fp7
		bra     .zero1
.notzero1
		fmove.s #1.0,fp7
		fdiv    fp6,fp7
.zero1

;         for (i=0;i<n;i++) {

.loop1

;            GLdouble tx, ty, tz;
;            {
;               GLfloat ux = u[i][0],  uy = u[i][1],  uz = u[i][2];
;               tx = f * (ux * m0 + uy * m1 + uz * m2);
;               ty = f * (ux * m4 + uy * m5 + uz * m6);
;               tz = f * (ux * m8 + uy * m9 + uz * m10);
;            }

		fmove.s 0*4(a0),fp3
		fmul.s  0*4(a2),fp3
		fmove.s 1*4(a0),fp4
		fmul.s  1*4(a2),fp4
		fadd    fp4,fp3
		fmove.s 2*4(a0),fp4
		fmul    fp0,fp4
		fadd    fp4,fp3
		fmul    fp7,fp3                 ;tx = fp3

		fmove.s 0*4(a0),fp4
		fmul.s  4*4(a2),fp4
		fmove.s 1*4(a0),fp5
		fmul.s  5*4(a2),fp5
		fadd    fp5,fp4
		fmove.s 2*4(a0),fp5
		fmul    fp1,fp5
		fadd    fp5,fp4
		fmul    fp7,fp4                 ;ty = fp4

		fmove.s 0*4(a0),fp5
		fmul.s  8*4(a2),fp5
		fmove.s 1*4(a0),fp6
		fmul.s  9*4(a2),fp6
		fadd    fp6,fp5
		fmove.s 2*4(a0),fp6
		fmul    fp2,fp6
		fadd    fp6,fp5
		fmul    fp7,fp5                 ;tz = fp5

		lea     3*4(a0),a0


;            {
;               GLdouble len, scale;
;               len = GL_SQRT( tx*tx + ty*ty + tz*tz );

		fmove.s fp7,-(sp)

		fmove   fp3,fp6
		fmul    fp6,fp6
		fmove   fp4,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fmove   fp5,fp7
		fmul    fp7,fp7
		fadd    fp6,fp7
		fsqrt   fp7

;               scale = (len>1E-30) ? (1.0 / len) : 1.0;

		fcmp.s  #$0da24260,fp7
		fbgt    .notzero2
		fmove.s #1.0,fp6
		bra     .zero2
.notzero2
		fmove.s #1.0,fp6
		fdiv    fp7,fp6
.zero2

		fmove.s (sp)+,fp7

;               v[i][0] = tx * scale;
;               v[i][1] = ty * scale;
;               v[i][2] = tz * scale;

		fmul    fp6,fp3
		fmove.s fp3,(a1)+
		fmul    fp6,fp4
		fmove.s fp4,(a1)+
		fmul    fp6,fp5
		fmove.s fp5,(a1)+

;            }
;         }


		subq.l  #1,d0
		bne     .loop1
		bra     .end

.notrescaled1

;         for (i=0;i<n;i++) {

.loop2

;            GLdouble tx, ty, tz;
;            {
;               GLfloat ux = u[i][0],  uy = u[i][1],  uz = u[i][2];
;               tx = ux * m0 + uy * m1 + uz * m2;
;               ty = ux * m4 + uy * m5 + uz * m6;
;               tz = ux * m8 + uy * m9 + uz * m10;
;            }

		fmove.s 0*4(a0),fp3
		fmul.s  0*4(a2),fp3
		fmove.s 1*4(a0),fp4
		fmul.s  1*4(a2),fp4
		fadd    fp4,fp3
		fmove.s 2*4(a0),fp4
		fmul    fp0,fp4
		fadd    fp4,fp3                 ;tx = fp3

		fmove.s 0*4(a0),fp4
		fmul.s  4*4(a2),fp4
		fmove.s 1*4(a0),fp5
		fmul.s  5*4(a2),fp5
		fadd    fp5,fp4
		fmove.s 2*4(a0),fp5
		fmul    fp1,fp5
		fadd    fp5,fp4                 ;ty = fp4

		fmove.s 0*4(a0),fp5
		fmul.s  8*4(a2),fp5
		fmove.s 1*4(a0),fp6
		fmul.s  9*4(a2),fp6
		fadd    fp6,fp5
		fmove.s 2*4(a0),fp6
		fmul    fp2,fp6
		fadd    fp6,fp5                 ;tz = fp5

		lea     3*4(a0),a0


;            {
;               GLdouble len, scale;
;               len = GL_SQRT( tx*tx + ty*ty + tz*tz );

		fmove   fp3,fp6
		fmul    fp6,fp6
		fmove   fp4,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fmove   fp5,fp7
		fmul    fp7,fp7
		fadd    fp6,fp7

		fsqrt   fp7

;               scale = (len>1E-30) ? (1.0 / len) : 1.0;

		fcmp.s  #$0da24260,fp7
		fbgt    .notzero3
		fmove.s #1.0,fp6
		bra     .zero3
.notzero3
		fmove.s #1.0,fp6
		fdiv    fp7,fp6
.zero3

;               v[i][0] = tx * scale;
;               v[i][1] = ty * scale;
;               v[i][2] = tz * scale;

		fmul    fp6,fp3
		fmove.s fp3,(a1)+
		fmul    fp6,fp4
		fmove.s fp4,(a1)+
		fmul    fp6,fp5
		fmove.s fp5,(a1)+

;            }
;         }

		subq.l  #1,d0
		bne     .loop2
		bra     .end

.notnormalized

;      if (rescale) {

		tst.b   .rescale(sp)
		beq.b   .notrescaled2

;         GLfloat f = GL_SQRT( m2*m2 + m6*m6 + m10*m10 );

		fmove   fp0,fp6
		fmul    fp6,fp6
		fmove   fp1,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fmove   fp2,fp7
		fmul    fp7,fp7
		fadd    fp7,fp6
		fsqrt   fp6

;         f = (f == 0.0F) ? 1.0F : (1.0F / f);

		ftst    fp6
		bne     .notzero4
		fmove.s #1.0,fp7
		bra     .zero4
.notzero4
		fmove.s #1.0,fp7
		fdiv    fp6,fp7
.zero4

;         for (i=0;i<n;i++) {

.loop3

;            {
;               GLfloat ux = u[i][0],  uy = u[i][1],  uz = u[i][2];
;               v[i][0] = f * (ux * m0 + uy * m1 + uz * m2);
;               v[i][1] = f * (ux * m4 + uy * m5 + uz * m6);
;               v[i][2] = f * (ux * m8 + uy * m9 + uz * m10);
;            }

		fmove.s 0*4(a0),fp5
		fmove.s 1*4(a0),fp6

		fmove   fp5,fp3
		fmul.s  0*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  1*4(a2),fp4
		fadd    fp4,fp3
		fmove.s 2*4(a0),fp4
		fmul    fp0,fp4
		fadd    fp4,fp3
		fmul    fp7,fp3
		fmove.s fp3,(a1)+

		fmove   fp5,fp3
		fmul.s  4*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  5*4(a2),fp4
		fadd    fp4,fp3
		fmove.s 2*4(a0),fp4
		fmul    fp1,fp4
		fadd    fp4,fp3
		fmul    fp7,fp3
		fmove.s fp3,(a1)+

		fmove   fp5,fp3
		fmul.s  8*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  9*4(a2),fp4
		fadd    fp4,fp3
		fmove.s 2*4(a0),fp4
		fmul    fp2,fp4
		fadd    fp4,fp3
		fmul    fp7,fp3
		fmove.s fp3,(a1)+

		lea     3*4(a0),a0

		subq.l  #1,d0
		bne     .loop3
		bra     .end


.notrescaled2

;         for (i=0;i<n;i++) {

.loop4

;            {
;               GLfloat ux = u[i][0],  uy = u[i][1],  uz = u[i][2];
;               v[i][0] = ux * m0 + uy * m1 + uz * m2;
;               v[i][1] = ux * m4 + uy * m5 + uz * m6;
;               v[i][2] = ux * m8 + uy * m9 + uz * m10;
;            }

		fmove.s (a0)+,fp5
		fmove.s (a0)+,fp6
		fmove.s (a0)+,fp7

		fmove   fp5,fp3
		fmul.s  0*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  1*4(a2),fp4
		fadd    fp4,fp3
		fmove   fp7,fp4
		fmul    fp0,fp4
		fadd    fp4,fp3
		fmove.s fp3,(a1)+

		fmove   fp5,fp3
		fmul.s  4*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  5*4(a2),fp4
		fadd    fp4,fp3
		fmove   fp7,fp4
		fmul    fp1,fp4
		fadd    fp4,fp3
		fmove.s fp3,(a1)+

		fmove   fp5,fp3
		fmul.s  8*4(a2),fp3
		fmove   fp6,fp4
		fmul.s  9*4(a2),fp4
		fadd    fp4,fp3
		fmove   fp7,fp4
		fmul    fp2,fp4
		fadd    fp4,fp3
		fmove.s fp3,(a1)+

		subq.l  #1,d0
		bne     .loop4
.end
		fmovem.x        (sp)+,fp0-fp7
		move.l  (sp)+,a2
		rts

