;
; 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_asmppc.p
;   2.12.1998 by Sam Jordan
;
;   PowerPC assembler optimizations of several functions in xform.c
;   Originally written for AMIGA OS/PowerOpen. To use this source on other
;   PowerPC based platforms or with other programming models, some
;   modifications might be needed.

                XDEF    _gl_xform_normals_3fv

_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 )

                stfd    f14,-1*8(r1)
                stfd    f15,-2*8(r1)
                stfd    f16,-3*8(r1)
                stfd    f17,-4*8(r1)
                stfd    f18,-5*8(r1)
                mr.     r3,r3
                beq     .end

;         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];

                subi    r5,r5,4
                lfsu    f0,4(r5)                ;f0 = m[0]
                lfsu    f1,4(r5)                ;f1 = m[1]
                lfsu    f2,4(r5)                ;f2 = m[2]
                addi    r5,r5,4
                lfsu    f3,4(r5)                ;f3 = m[4]
                lfsu    f4,4(r5)                ;f4 = m[5]
                lfsu    f5,4(r5)                ;f5 = m[6]
                addi    r5,r5,4
                lfsu    f6,4(r5)                ;f6 = m[8]
                lfsu    f7,4(r5)                ;f7 = m[9]
                lfsu    f8,4(r5)                ;f8 = m[10]
                mtctr   r3
                subi    r4,r4,4
                subi    r6,r6,4
                ls      f9,_f_0                 ;f9 = 0.0
                ls      f10,_f_0_5              ;f10 = 0.5

;   if (normalize) {

                mr.     r7,r7
                beq     .notnormalized

;      if (rescale) {

                mr.     r8,r8
                beq     .notrescaled1

;         GLfloat f = GL_SQRT( m2*m2 + m6*m6 + m10*m10 );
;         f = (f == 0.0F) ? 1.0F : (1.0F / f);

                fmuls   f11,f2,f2
                fmadds  f11,f3,f3,f11
                fmadds  f11,f4,f4,f11

                fcmpu   f9,f11
                fadd    f12,f10,f10
                fadd    f12,f12,f10
                bne     .notzero1
                ls      f11,_f_1
                b       .loop1
.notzero1
                frsqrte f13,f11
                fmuls   f14,f11,f10
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f13,f16,f13
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f13,f16,f13
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f11,f16,f13

;         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);
;            }

                lfsu    f12,4(r6)               ;f12 = ux = u[i][0]
                fmuls   f15,f12,f0
                fmuls   f16,f12,f3
                fmuls   f17,f12,f6
                lfsu    f13,4(r6)               ;f13 = uy = u[i][1]
                fmadds  f15,f13,f1,f15
                fmadds  f16,f13,f4,f16
                fmadds  f17,f13,f7,f17
                lfsu    f14,4(r6)               ;f14 = uz = u[i][2]
                fmadds  f15,f14,f2,f15
                fmadds  f16,f14,f5,f16
                fmadds  f17,f14,f8,f17
                fmuls   f15,f15,f11             ;f15 = tx
                fmuls   f16,f16,f11             ;f16 = ty
                fmuls   f17,f17,f11             ;f17 = tz


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

                fmuls   f14,f15,f15
                fmadds  f14,f16,f16,f14
                fmadds  f14,f17,f17,f14

                fcmpu   f9,f14
                fadd    f12,f10,f10
                fadd    f12,f12,f10
                bne     .notzero1b
                ls      f14,_f_1
                b       .zero2
.notzero1b
                frsqrte f13,f14
                fmuls   f11,f14,f10
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f13,f14,f13
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f13,f14,f13
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f14,f14,f13
.zero2

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

                fmuls   f15,f15,f14
                stfsu   f15,4(r4)
                fmuls   f16,f16,f14
                stfsu   f16,4(r4)
                fmuls   f17,f17,f14
                stfsu   f17,4(r4)

;            }
;         }

                bdnz    .loop1
                b       .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;
;            }

                lfsu    f12,4(r6)               ;f12 = ux = u[i][0]
                fmuls   f15,f12,f0
                fmuls   f16,f12,f3
                fmuls   f17,f12,f6
                lfsu    f13,4(r6)               ;f13 = uy = u[i][1]
                fmadds  f15,f13,f1,f15
                fmadds  f16,f13,f4,f16
                fmadds  f17,f13,f7,f17
                lfsu    f14,4(r6)               ;f14 = uz = u[i][2]
                fmadds  f15,f14,f2,f15          ;f15 = tx
                fmadds  f16,f14,f5,f16          ;f16 = ty
                fmadds  f17,f14,f8,f17          ;f17 = tz

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

                fmuls   f14,f15,f15
                fmadds  f14,f16,f16,f14
                fmadds  f14,f17,f17,f14

                fcmpu   f9,f14
                fadd    f12,f10,f10
                fadd    f12,f12,f10
                bne     .notzero2b
                ls      f14,_f_1
                b       .zero3
.notzero2b
                frsqrte f13,f14
                fmuls   f11,f14,f10
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f13,f14,f13
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f13,f14,f13
                fmuls   f18,f13,f13
                fnmsubs f14,f18,f11,f12
                fmuls   f14,f14,f13
.zero3


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

                fmuls   f15,f15,f14
                stfsu   f15,4(r4)
                fmuls   f16,f16,f14
                stfsu   f16,4(r4)
                fmuls   f17,f17,f14
                stfsu   f17,4(r4)

;            }
;         }

                bdnz    .loop2
                b       .end

.notnormalized

;      if (rescale) {

                mr.     r8,r8
                beq     .notrescaled2

;         GLfloat f = GL_SQRT( m2*m2 + m6*m6 + m10*m10 );
;         f = (f == 0.0F) ? 1.0F : (1.0F / f);

                fmuls   f11,f2,f2
                fmadds  f11,f3,f3,f11
                fmadds  f11,f4,f4,f11

                fcmpu   f9,f11
                fadd    f12,f10,f10
                fadd    f12,f12,f10
                bne     .notzero3
                ls      f11,_f_1
                b       .zero4
.notzero3
                frsqrte f13,f11
                fmuls   f14,f11,f10
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f13,f16,f13
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f13,f16,f13
                fmuls   f15,f13,f13
                fnmsubs f16,f15,f14,f12
                fmuls   f11,f16,f13
.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);
;            }

                lfsu    f12,4(r6)               ;f12 = ux = u[i][0]
                fmuls   f15,f12,f0
                fmuls   f16,f12,f3
                fmuls   f17,f12,f6
                lfsu    f13,4(r6)               ;f13 = uy = u[i][1]
                fmadds  f15,f13,f1,f15
                fmadds  f16,f13,f4,f16
                fmadds  f17,f13,f7,f17
                lfsu    f14,4(r6)               ;f14 = uz = u[i][2]
                fmadds  f15,f14,f2,f15
                fmadds  f16,f14,f5,f16
                fmadds  f17,f14,f8,f17
                fmuls   f15,f15,f11             ;f15 = tx
                stfsu   f15,4(r4)
                fmuls   f16,f16,f11             ;f16 = ty
                stfsu   f16,4(r4)
                fmuls   f17,f17,f11             ;f17 = tz
                stfsu   f17,4(r4)

                bdnz    .loop3
                b       .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;
;            }

                lfsu    f12,4(r6)               ;f12 = ux = u[i][0]
                fmuls   f15,f12,f0
                fmuls   f16,f12,f3
                fmuls   f17,f12,f6
                lfsu    f13,4(r6)               ;f13 = uy = u[i][1]
                fmadds  f15,f13,f1,f15
                fmadds  f16,f13,f4,f16
                fmadds  f17,f13,f7,f17
                lfsu    f14,4(r6)               ;f14 = uz = u[i][2]
                fmadds  f15,f14,f2,f15
                stfsu   f15,4(r4)
                fmadds  f16,f14,f5,f16
                stfsu   f16,4(r4)
                fmadds  f17,f14,f8,f17
                stfsu   f17,4(r4)

                bdnz    .loop4
                b       .end
.end
                lfd     f18,-5*8(r1)
                lfd     f17,-4*8(r1)
                lfd     f16,-3*8(r1)
                lfd     f15,-2*8(r1)
                lfd     f14,-1*8(r1)
                blr


                section data
_f_0            dc.s    0
_f_0_5          dc.s    0.5
_f_1            dc.s    1.0

