.ad 8
.bm 8
.fm 4
.bt $COPYRIGHT SAP AG, 1988-2002$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$VSP32A$
.tt 2 $$$
.tt 3 $$RTE-Extension-32A$1999-03-29$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2000 SAP AG

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    ========== licence end

.fo
.nf
.sp
Module  : RTE-Extension-32A
=========
.sp
Purpose : Pufferroutinen und Vergleichsroutinen
          VSP32 und VSP32A zusammen ergeben VSP30
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

        PROCEDURE
              s30map (VAR code_t : c_table;
                          VAR source : moveobject;
                          spos : integer;
                          VAR dest : moveobject;
                          dpos : integer;
                          length : integer);

        PROCEDURE
              s30lcm      (VAR buf1     : moveobject;
                          fieldpos1    : integer;
                          fieldlength1 : integer;
                          VAR buf2     : moveobject;
                          fieldpos2    : integer;
                          fieldlength2 : integer;
                          VAR l_result : lcomp_result);

        PROCEDURE
              s30lcm1     (VAR buf1     : moveobject;
                          fieldpos1    : integer;
                          fieldlength1 : integer;
                          VAR buf2     : moveobject;
                          fieldpos2    : integer;
                          fieldlength2 : integer;
                          VAR l_result : lcomp_result);

        PROCEDURE
              s30lcm2     (VAR buf1     : moveobject;
                          fieldpos1    : integer;
                          fieldlength1 : integer;
                          VAR buf2     : moveobject;
                          fieldpos2    : integer;
                          fieldlength2 : integer;
                          VAR l_result : lcomp_result);

        PROCEDURE
              s30lcm3     (VAR buf1     : moveobject;
                          fieldpos1    : integer;
                          fieldlength1 : integer;
                          VAR buf2     : moveobject;
                          fieldpos2    : integer;
                          fieldlength2 : integer;
                          VAR l_result : lcomp_result);

        FUNCTION
              sp30a24 : int4;

        PROCEDURE
              s30xorc4 (c4_1          : tsp_c4;
			c4_2          : tsp_c4;
			VAR c4_target : tsp_c4);

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1979-06-07
.sp
.cp 3
Version : 1994-08-09
.sp
.cp 3
Release :      Date : 1999-03-29
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

Die Positionsangabe POS gibt das erste Byte des betroffenen Feldes an.
Das erste Byte im Puffer ist durch POS = 1 ansprechbar.
.sp 4
PROCEDURE  S30LCM:
.sp
Vergleicht zwei Strings in Puffern buf1, buf2 an den Positonen
fieldpos1, fieldpos2 der L?angen fieldlength1, fieldlength2.
Der K?urzer String wird mit Bin?arnullen aufgef?ullt.
l_result kann drei Werte annehmen:
   1. wenn  1 > 2  ::=  l_greater
   2. wenn  1 < 2  ::=  l_less
   3. wenn  1 = 2  ::=  l_equal.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:


.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

(*------------------------------*)

PROCEDURE
      s30map (VAR code_t : c_table;
                  VAR source : moveobject;
                  spos : integer;
                  VAR dest : moveobject;
                  dpos : integer;
                  length : integer);

VAR
      i : integer;

BEGIN
FOR i:= 0 TO length-1 DO
    dest [dpos+i] := code_t [ord(source [spos+i] ) + 1 ]
(*ENDFOR*)
END;

(*------------------------------*)

PROCEDURE
      s30lcm      (VAR buf1     : moveobject;
                  fieldpos1    : integer;
                  fieldlength1 : integer;
                  VAR buf2     : moveobject;
                  fieldpos2    : integer;
                  fieldlength2 : integer;
                  VAR l_result : lcomp_result);

VAR
      prefix_length  : integer;
      i              : integer;
      char_detected  : boolean;
      prefix_compare : lcomp_result;

BEGIN
(* buf1 field > buf2 field  =>  l_result = l_greater *)
l_result := l_equal;
IF   fieldlength1 <= 0
THEN
     BEGIN
     IF   fieldlength2 <= 0
     THEN
          l_result := l_equal
     ELSE (* fieldlength2 > 0 *)
          BEGIN
          i := 0;
          REPEAT
                 char_detected := (buf2 [fieldpos2+i ] <> chr(0));
                 i := i + 1
          UNTIL
                (i >= fieldlength2) OR char_detected;
          (*ENDREPEAT*)
          IF   char_detected
          THEN
               l_result := l_less
          ELSE
               l_result := l_equal
          (*ENDIF*)
          END
     (*ENDIF*)
     END
ELSE (* fieldlength1 > 0 *)
     IF   fieldlength2 <= 0
     THEN
          BEGIN
          i := 0;
          REPEAT
                 char_detected := (buf1 [fieldpos1+i ] <> chr(0));
                 i := i + 1
          UNTIL
                (i >= fieldlength1) OR char_detected;
          (*ENDREPEAT*)
          IF   char_detected
          THEN
               l_result := l_greater
          ELSE
               l_result := l_equal
          (*ENDIF*)
          END
     ELSE (* fieldlength1 > 0 AND fieldlength2 > 0 *)
          BEGIN
          IF   fieldlength1 > fieldlength2
          THEN
               prefix_length := fieldlength2
          ELSE
               prefix_length := fieldlength1;
          (*ENDIF*)
          i := 0;
          prefix_compare := l_equal;
          REPEAT
                 IF   buf1 [fieldpos1+i ] <> buf2 [fieldpos2+i ]
                 THEN
                      BEGIN
                      IF   buf1 [fieldpos1+i ] > buf2 [fieldpos2+i ]
                      THEN
                           prefix_compare := l_greater
                      ELSE
                           prefix_compare := l_less
                      (*ENDIF*)
                      END;
                 (*ENDIF*)
                 i := i + 1
          UNTIL
                (prefix_compare <> l_equal) OR (i >= prefix_length);
          (*ENDREPEAT*)
          CASE prefix_compare OF
               l_greater:
                    l_result := l_greater;
               l_less:
                    l_result := l_less;
               l_equal:
                    BEGIN
                    IF   fieldlength1 = fieldlength2
                    THEN
                         l_result := l_equal
                    ELSE
                         IF   fieldlength1 > fieldlength2
                         THEN
                              BEGIN
                              i := prefix_length;
                              REPEAT
                                     char_detected :=
                                                 (buf1 [fieldpos1+i ]
                                                 <> chr(0));
                                     i := i + 1
                              UNTIL
                                    (i >= fieldlength1) OR char_detected;
                              (*ENDREPEAT*)
                              IF   char_detected
                              THEN
                                   l_result := l_greater
                              ELSE
                                   l_result := l_equal
                              (*ENDIF*)
                              END
                         ELSE (* fieldlength1 < fieldlength2 *)
                              BEGIN
                              i := prefix_length;
                              REPEAT
                                     char_detected :=
                                                 (buf2 [fieldpos2+i ]
                                                 <> chr(0));
                                     i := i + 1
                              UNTIL
                                    (i >= fieldlength2) OR char_detected;
                              (*ENDREPEAT*)
                              IF   char_detected
                              THEN
                                   l_result := l_less
                              ELSE
                                   l_result := l_equal
                              (*ENDIF*)
                              END
                         (*ENDIF*)
                    (*ENDIF*)
                    END
               END
          (*ENDCASE*)
          END
     (*ENDIF*)
(*ENDIF*)
END;

(*------------------------------*)

PROCEDURE
      s30xorc4  (c4_1     : tsp_c4;
            c4_2          : tsp_c4;
            VAR c4_target : tsp_c4);

TYPE
      four_byte_range = 0..31;
      four_byte_set   = PACKED SET OF four_byte_range;

      set_map_c4 = RECORD
            CASE boolean OF
                true :
                    (map_set : four_byte_set);
                false :
                    (map_c4  : tsp_c4);
                END;
            (*ENDCASE*)


VAR
      xor_map  : set_map_c4;
      set_map  : set_map_c4;

BEGIN
xor_map.map_c4 := c4_1;
set_map.map_c4 := c4_2;
xor_map.map_set := (xor_map.map_set + set_map.map_set) -
      (xor_map.map_set * set_map.map_set);
c4_target:= xor_map.map_c4
END;

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :

&if $MACH = T35
#=========================================================

        .data   0
        .text   0
	.globl  _sp30a24
_sp30a24:
	movw    $926190621,pr0
	ret

#=========================================================

                .text
.globl          _s30map
#       PROCEDURE
#             s30map (VAR code_t : c_table          { pr0 } ;
#                         VAR source : moveobject { pr1 } ;
#                         spos : integer          { pr2 } ;
#                         VAR dest : moveobject   { pr3 } ;
#                         dpos : integer          { pr4 } ;
#                         length : integer        { pr5 }  );
#
#       VAR
#             i : integer       { lr0 } ;
#
#       { lr2 = addr ( source [ spos ] ) = pr1 + pr2 - 1 }
#       { lr3 = addr ( dest   [ dpos ] ) = pr3 + pr4 - 1 }
#
#
_s30map:
#                                       BEGIN
#
                mova     0xffffffff(pr1),lr2      # init lr2
                addw     pr2,lr2
                mova     0xffffffff(pr3),lr3      # init lr3
                addw     pr4,lr3
#
#                                       FOR i:= 0 TO length-1 DO
                mova     0xffffffff(pr5),lr1
                mtstw    lr1,lr1
                btc      n,_vmap_ret
                movw     $0,lr0
#                                           dest [dpos+i] := code_t
#                                                [ord(source [spos+i] ) + 1 ]
_vmap_loop:     movzbw   (lr2),pr7
                addw     pr0,pr7
                movb     (pr7),(lr3)
#                                       (*ENDFOR*)
                cmpw     lr1,lr0
                btc      z,_vmap_ret
                addw     $1,lr0
                addw     $1,lr2
                addw     $1,lr3
                br       _vmap_loop
#                                       END;
_vmap_ret:      ret
#
.globl          _s30lcm3
.globl          _s30lcm2
.globl          _s30lcm1
.globl          _s30lcm
#       PROCEDURE
#             s30lcm      (VAR buf1     : moveobject   { pr0 } ;
#                         fieldpos1    : integer      { pr1 } ;
#                         fldlng1      : integer      { pr2 } ;
#                         VAR buf2     : moveobject   { pr3 } ;
#                         fieldpos2    : integer      { pr4 } ;
#                         fldlng2      : integer      { pr5 } ;
#                         VAR l_result : lcomp_result { pr6 } );
#       VAR
#             prefix_length  : integer      { lr0 } ;
#             i              : integer      { lr1 } ;
#             char_detected  : boolean      { lr2 - optimiert-entfallen } ;
#             prefix_compare : lcomp_result { lr3 } ;
#
#       { lr4 = addr ( buf1 [ fieldpos1] ) = pr0 + pr1 - 1 }
#       { lr5 = addr ( buf2 [ fieldpos2] ) = pr3 + pr4 - 1 }
#
_s30lcm:
_s30lcm1:
_s30lcm2:
_s30lcm3:
#                                       BEGIN
#
                mova     0xffffffff(pr0),lr4      # init lr4
                addw     pr1,lr4
                mova     0xffffffff(pr3),lr5      # init lr5
                addw     pr4,lr5
#
#                                       (* buf1 field > buf2 field  =>
#                                            l_result = l_greater *)
#                                       l_result := l_equal;
                movb     $1,(pr6)
#                                       IF   fldlng1 <= 0
                mtstw    pr2,pr2
                bfc      nz,_lcomp_008
#                                       THEN
#                                          BEGIN
#                                          IF   fldlng2 <= 0
                mtstw    pr5,pr5
                bfc      nz,_lcomp_001
#                                          THEN
#                                              l_result := l_equal
                movb     $1,(pr6)
                br       _lcomp_ret
#                                          ELSE (* fldlng2 > 0 *)
#                                             BEGIN
#                                             i := 0;
_lcomp_001:     movw     $0,lr1
#                                             REPEAT
#                                                 char_detected :=
#                                                   (buf2 [fieldpos2+i ]
#                                                                <> chr(0));
_lcomp_002:     movw     lr5,pr7
                addw     lr1,pr7
                movzbw   (pr7),pr7
                bfc      z,_lcomp_050
#                                                 i := i + 1
                mova     1(lr1),lr1
#                                             UNTIL
#                                                (i >= fldlng2)
                cmpw     pr5,lr1
                btc      n,_lcomp_002
#                                                 OR char_detected;
#                                             (*ENDREPEAT*)
#                                             IF   char_detected
                br       _lcomp_007
#                                             THEN
#                                                l_result := l_less
_lcomp_050:     movb     $0,(pr6)
                br       _lcomp_ret
#                                             ELSE
#                                                l_result := l_equal
_lcomp_007:     movb     $1,(pr6)
#                                             (*ENDIF*)
#                                             END
#                                          (*ENDIF*)
#                                          END
                br       _lcomp_ret
#                                       ELSE (* fldlng1 > 0 *)
#                                          IF   fldlng2 <= 0
_lcomp_008:     mtstw    pr5,pr5
                bfc      nz,_lcomp_015
#                                          THEN
#                                             BEGIN
#                                             i := 0;
                movw     $0,lr1
#                                             REPEAT
#                                                 char_detected :=
#                                                   (buf1 [fieldpos1+i ]
#                                                                <> chr(0));
_lcomp_009:     movw     lr4,pr7
                addw     lr1,pr7
                movzbw   (pr7),pr7
                bfc      z,_lcomp_055
#                                                 i := i + 1
                mova     1(lr1),lr1
#                                             UNTIL
#                                                (i >= fldlng1)
                cmpw     pr2,lr1
                btc      n,_lcomp_009
#                                                OR char_detected;
#                                             (*ENDREPEAT*)
#                                             IF   char_detected
                br       _lcomp_014
#                                             THEN
#                                                l_result := l_greater
_lcomp_055:     movb     $2,(pr6)
                br       _lcomp_ret
#                                             ELSE
#                                                l_result := l_equal
_lcomp_014:     movb     $1,(pr6)
#                                             (*ENDIF*)
#                                             END
                br       _lcomp_ret
#                                          ELSE (* fldlng1 > 0 AND
#                                                  fldlng2 > 0 *)
#                                             BEGIN
#                                             IF   fldlng1 > fldlng2
_lcomp_015:     cmpw     pr5,pr2
                btc      nz,_lcomp_016
#                                             THEN
#                                                prefix_length := fldlng2
                movw     pr5,lr0
                br       _lcomp_017
#                                             ELSE
#                                                prefix_length := fldlng1;
_lcomp_016:     movw     pr2,lr0
#                                             (*ENDIF*)
#                                             i := 0;
_lcomp_017:     movw     $0,lr1
#                                             prefix_compare := l_equal;
                movw     $1,lr3
#                                             REPEAT
#                                                IF   buf1 [fieldpos1+i ] <>
#                                                     buf2 [fieldpos2+i ]
_lcomp_018:     movw     lr4,pr7
                addw     lr1,pr7
                movzbw   (pr7),pr7
                movw     lr5,pr8
                addw     lr1,pr8
                movzbw   (pr8),pr8
                cmpw     pr8,pr7
                btc      z,_lcomp_020
#                                                THEN
#                                                   BEGIN
#                                                   IF   buf1 [fieldpos1+i ]
#                                                      > buf2 [fieldpos2+i ]
                btc      nz,_lcomp_019
#                                                   THEN
#                                                      prefix_compare :=
#                                                                 l_greater
                movw     $2,lr3
                br       _lcomp_020
#                                                   ELSE
#                                                      prefix_compare :=
#                                                                 l_less
_lcomp_019:     movw     $0,lr3
#                                                   (*ENDIF*)
#                                                   END;
#                                                (*ENDIF*)
#                                                i := i + 1
_lcomp_020:     mova     1(lr1),lr1
#                                             UNTIL
#                                                (prefix_compare <> l_equal)
                ucmpw    $1,lr3
                bfc      z,_lcomp_022
#                                                OR (i >= prefix_length);
                cmpw     lr0,lr1
                btc      n,_lcomp_018
#                                             (*ENDREPEAT*)
#                                             CASE prefix_compare OF
_lcomp_022:     movw     lr3,tr0
                cmpw     $0,tr0
                btc      n,_lcomp_ret
                btc      z,_lcomp_024
                cmpw     $1,tr0
                btc      z,_lcomp_025
                cmpw     $2,tr0
                btc      z,_lcomp_023
                br       _lcomp_ret
#                                             l_greater:
#                                                 l_result := l_greater;
_lcomp_023:     movb     $2,(pr6)
                br       _lcomp_ret
#                                             l_less:
#                                                 l_result := l_less;
_lcomp_024:     movb     $0,(pr6)
                br       _lcomp_ret
#                                             l_equal:
#                                                 BEGIN
#                                                 IF   fldlng1 = fldlng2
_lcomp_025:     cmpw     pr5,pr2
                bfc      z,_lcomp_026
#                                                 THEN
#                                                    l_result := l_equal
                movb     $1,(pr6)
                br       _lcomp_ret
#                                                 ELSE
#                                                    IF   fldlng1 > fldlng2
_lcomp_026:     cmpw     pr5,pr2
                btc      nz,_lcomp_033
#                                                    THEN
#                                                        BEGIN
#                                                        i := prefix_length;
                movw     lr0,lr1
#                                                        REPEAT
#                                                            char_detected :=
#                                                      (buf1 [fieldpos1+i ]
#                                                      <> chr(0));
_lcomp_027:     movw     lr4,pr7
                addw     lr1,pr7
                movzbw   (pr7),pr7
                bfc      z,_lcomp_060
#                                                            i := i + 1
                mova     1(lr1),lr1
#                                                        UNTIL
#                                                           (i >= fldlng1)
                cmpw     pr2,lr1
                btc      n,_lcomp_027
#                                                           OR char_detected;
#                                                        (*ENDREPEAT*)
#                                                        IF   char_detected
                br       _lcomp_032
#                                                        THEN
#                                                         l_result := l_greater
_lcomp_060:     movb     $2,(pr6)
                br       _lcomp_ret
#                                                        ELSE
#                                                         l_result := l_equal
_lcomp_032:     movb     $1,(pr6)
#                                                        (*ENDIF*)
#                                                        END
                br       _lcomp_ret
#                                                    ELSE (* fldlng1 <
#                                                              fldlng2 *)
#                                                       BEGIN
#                                                       i := prefix_length;
_lcomp_033:     movw     lr0,lr1
#                                                       REPEAT
#                                                           char_detected :=
#                                                       (buf2 [fieldpos2+i ]
#                                                       <> chr(0));
_lcomp_034:     movw     lr5,pr7
                addw     lr1,pr7
                movzbw   (pr7),pr7
                bfc      z,_lcomp_065
#                                                           i := i + 1
                mova     1(lr1),lr1
#                                                       UNTIL
#                                                          (i >= fldlng2)
                cmpw     pr5,lr1
                btc      n,_lcomp_034
#                                                          OR char_detected;
#                                                       (*ENDREPEAT*)
#                                                       IF   char_detected
                br       _lcomp_039
#                                                       THEN
#                                                         l_result := l_less
_lcomp_065:     movb     $0,(pr6)
                br       _lcomp_ret
#                                                       ELSE
#                                                         l_result := l_equal
_lcomp_039:     movb     $1,(pr6)
#                                                       (*ENDIF*)
#                                                       END
                br       _lcomp_ret
#                                                    (*ENDIF*)
#                                                 (*ENDIF*)
#                                                 END
#                                             END
#                                             (*ENDCASE*)
#                                             END
#                                          (*ENDIF*)
#                                       (*ENDIF*)
#                                       END;
_lcomp_ret:     ret
#
#       PROCEDURE
#             s30xorc4  (c4_1     : tsp_c4;
#                   c4_2          : tsp_c4;
#                   VAR c4_target : tsp_c4);
#
#Could also be written in C (we know that sizeof(tsp_c4) == 4)
#
#int s30xorc4(c_1, c_2, c_target)
#unsigned char *c_1;
#unsigned char *c_2;
#unsigned char *c_target;
#{
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#}
#
	.globl	_s30xorc4
_s30xorc4:
	movzbw	(pr0),tr0
	movzbw	(pr1),tr1
	xorw	tr1,tr0
	cvtwb	tr0,(pr2)
	addw	$0x1,pr2
	addw	$0x1,pr0
	addw	$0x1,pr1
	movzbw	(pr0),tr0
	movzbw	(pr1),tr1
	xorw	tr1,tr0
	cvtwb	tr0,(pr2)
	addw	$0x1,pr2
	addw	$0x1,pr0
	addw	$0x1,pr1
	movzbw	(pr0),tr0
	movzbw	(pr1),tr1
	xorw	tr1,tr0
	cvtwb	tr0,(pr2)
	addw	$0x1,pr2
	addw	$0x1,pr0
	addw	$0x1,pr1
	movzbw	(pr0),tr0
	movzbw	(pr1),tr1
	xorw	tr1,tr0
	cvtwb	tr0,(pr2)
	ret
&endif /* T35 */

&if $MACH in [ I386 ]
	.file   "vsp32a.s"
	.text

#============================================================================/
#
#       PROCEDURE
#             s30map (VAR code_t : c_table;
#                         VAR source : moveobject;
#                         spos : integer;
#                         VAR dest : moveobject;
#                         dpos : integer;
#                         length : integer);
#
	.globl  s30map
s30map:

	pushl   %ebp                    # build stack frame
	movl    %esp, %ebp
	pushl   %edi                    # save register
	pushl   %esi                    # save register
	pushl   %ebx                    # save register

M_PARMPOS       =       8

M_TAB           =       M_PARMPOS
M_SRC           =       M_PARMPOS + 4
M_SPOS          =       M_PARMPOS + 8
M_DST           =       M_PARMPOS + 12
M_DPOS          =       M_PARMPOS + 16
M_LGT           =       M_PARMPOS + 20

	movl    M_LGT(%ebp), %ecx       # get length
	orl     %ecx, %ecx              # set condition codes
	je      .L01_leave              # LEN = 0 : nothing to do

	movl    M_TAB(%ebp), %ebx       # get table address

	movl    M_SRC(%ebp), %esi       # get source buffer address
	addl    M_SPOS(%ebp), %esi      # compute start address
	decl    %esi                    # correct for start pos = 1

	movl    M_DST(%ebp), %edi       # get destination buffer address
	addl    M_DPOS(%ebp), %edi      # compute start address
	decl    %edi                    # correct for start pos = 1

	cld                             # set direction to forward

.L01_loop:

	slodb                           # move (%esi) to %al, update %esi
	xlat                            # move (%ebx+%al) to %al
	sstob                           # move %al to (%edi), update %edi
	loop    .L01_loop

.L01_leave:

	popl    %ebx                    # restore register
	popl    %esi                    # restore register
	popl    %edi                    # restore register
	leave                           # remove stack frame
	ret

#============================================================================/
#
#       PROCEDURE
#             s30cmp      (VAR buf1     : moveobject;
#                         fieldpos1    : integer;
#                         fieldlength1 : integer;
#                         VAR buf2     : moveobject;
#                         fieldpos2    : integer;
#                         fieldlength2 : integer;
#                         VAR l_result : lcomp_result);
#
	.globl  s30cmp
	.globl  s30cmp1
	.globl  s30cmp2
	.globl  s30cmp3
s30cmp:
s30cmp1:
s30cmp2:
s30cmp3:

	pushl   %ebp                    # build stack frame
	movl    %esp, %ebp
	pushl   %edi                    # save register
	pushl   %esi                    # save register
	pushl   %ebx                    # save register

L_PARMPOS       =       8

L_BUF1          =       L_PARMPOS
L_POS1          =       L_PARMPOS + 4
L_LGT1          =       L_PARMPOS + 8
L_BUF2          =       L_PARMPOS + 12
L_POS2          =       L_PARMPOS + 16
L_LGT2          =       L_PARMPOS + 20
L_RES           =       L_PARMPOS + 24

L_LSS           =       0
L_EQU           =       1
L_GTR           =       2

	movl    L_BUF1(%ebp), %esi      # get buffer1 address
	addl    L_POS1(%ebp), %esi      # add buffer position
	decl    %esi                    # correct for start pos = 1
	movl    L_LGT1(%ebp), %ecx      # get length1

	movl    L_BUF2(%ebp), %edi      # get buffer2 address
	addl    L_POS2(%ebp), %edi      # add buffer position
	decl    %edi                    # correct for start pos = 1
	movl    L_LGT2(%ebp), %ebx      # get length2

	# %edx indicates, which string is longer:
	# 0:	length1 < length2
	# 1:	length1 = length2
	# 2:	length1 > length2

	xorl    %edx, %edx              # assume length1 < length2
	cmpl    %ebx, %ecx              # compare length1, length2
	jb      .L04_lss                # jump, if length1 < length2
	je      .L04_equ                # jump, if length1 = length2
.L04_gtr:
	incl	%edx
.L04_equ:
	incl	%edx
.L04_lss:

	cmpl	$1, %edx		# test length relation
	jb      .L04_lchk               # jump, if length1 < length2
	xchgl   %ecx, %ebx              # exchange lengths, shorter in %ecx

.L04_lchk:
	cmpl    $0, %ecx                # test length
	je      .L04_rem                # if length zero, check remainder

	subl    %ecx, %ebx              # get remaining length

	cld                             # set direction to forward

	repz                            # repeat the following instruction,
					# while %ecx <> 0 and instruction
					# result is equal; decrement %ecx
	scmpb                           # compare (%esi) with (%edi);
					# update %esi and %edi
	jne     .L04_end                # if non-matching byte found, leave

.L04_rem:
	cmpl    $0, %ebx                # test remaining length
	je      .L04_end                # if remaining length zero, leave

	movl    %ebx, %ecx              # get remaining length

	cmpl	$1, %edx		# test length relation
	ja      .L04_greater            # jump to greater, if length1 > length2
	jmp     .L04_less               # jump to less, if length1 < length2

.L04_end:
	je      .L04_equal              # jump, if lcomp result equal
	ja      .L04_greater            # jump, if lcomp result greater

.L04_less:
	movl    $L_LSS, %edx            # result = less
	jmp     .L04_leave

.L04_equal:
	movl    $L_EQU, %edx            # result = equal
	jmp     .L04_leave

.L04_greater:
	movl    $L_GTR, %edx            # result = greater

.L04_leave:
	movl    L_RES(%ebp), %edi       # get result address
	movb    %dl, (%edi)             # set result

	popl    %ebx                    # restore register
	popl    %esi                    # restore register
	popl    %edi                    # restore register
	leave                           # remove stack frame
	ret

#============================================================================/
#
#       PROCEDURE
#             s30lcm      (VAR buf1     : moveobject;
#                         fieldpos1    : integer;
#                         fieldlength1 : integer;
#                         VAR buf2     : moveobject;
#                         fieldpos2    : integer;
#                         fieldlength2 : integer;
#                         VAR l_result : lcomp_result);
#
	.globl  s30lcm
	.globl  s30lcm1
	.globl  s30lcm2
	.globl  s30lcm3
s30lcm:
s30lcm1:
s30lcm2:
s30lcm3:

	pushl   %ebp                    # build stack frame
	movl    %esp, %ebp
	pushl   %edi                    # save register
	pushl   %esi                    # save register
	pushl   %ebx                    # save register

L_PARMPOS       =       8

L_BUF1          =       L_PARMPOS
L_POS1          =       L_PARMPOS + 4
L_LGT1          =       L_PARMPOS + 8
L_BUF2          =       L_PARMPOS + 12
L_POS2          =       L_PARMPOS + 16
L_LGT2          =       L_PARMPOS + 20
L_RES           =       L_PARMPOS + 24

L_LSS           =       0
L_EQU           =       1
L_GTR           =       2

	movl    L_BUF1(%ebp), %esi      # get buffer1 address
	addl    L_POS1(%ebp), %esi      # add buffer position
	decl    %esi                    # correct for start pos = 1
	movl    L_LGT1(%ebp), %ecx      # get length1

	movl    L_BUF2(%ebp), %edi      # get buffer2 address
	addl    L_POS2(%ebp), %edi      # add buffer position
	decl    %edi                    # correct for start pos = 1
	movl    L_LGT2(%ebp), %ebx      # get length2

	# %edx indicates, which string is longer:
	# 0:	length1 < length2
	# 1:	length1 = length2
	# 2:	length1 > length2

	xorl    %edx, %edx              # assume length1 < length2
	cmpl    %ebx, %ecx              # compare length1, length2
	jb      .L02_lss                # jump, if length1 < length2
	je      .L02_equ                # jump, if length1 = length2
.L02_gtr:
	incl	%edx
.L02_equ:
	incl	%edx
.L02_lss:

	cmpl	$1, %edx		# test length relation
	jb      .L02_lchk               # jump, if length1 < length2
	xchgl   %ecx, %ebx              # exchange lengths, shorter in %ecx

.L02_lchk:
	cmpl    $0, %ecx                # test length
	je      .L02_rem                # if length zero, check remainder

	subl    %ecx, %ebx              # get remaining length

	cld                             # set direction to forward

	repz                            # repeat the following instruction,
					# while %ecx <> 0 and instruction
					# result is equal; decrement %ecx
	scmpb                           # compare (%esi) with (%edi);
					# update %esi and %edi
	jne     .L02_end                # if non-matching byte found, leave

.L02_rem:
	cmpl    $0, %ebx                # test remaining length
	je      .L02_end                # if remaining length zero, leave

	movl    %ebx, %ecx              # get remaining length

	cmpl	$1, %edx		# test length relation
	ja      .L02_loop               # jump, if length1 > length2
	xchgl   %esi, %edi              # exchange buffer addresses, s > d

.L02_loop:
	lodsb				# load %al with (%esi), update %esi
	orb     %al, %al                # test byte
	loope   .L02_loop               # loop, while %ecx <> zero and
					# condition codes show equal
	je      .L02_end                # jump, if last byte zero
.L02_cond:
	cmpl	$1, %edx		# set condition codes for
					# length relation

.L02_end:
	je      .L02_equal              # jump, if lcomp result equal
	ja      .L02_greater            # jump, if lcomp result greater

.L02_less:
	movl    $L_LSS, %edx            # result = less
	jmp     .L02_leave

.L02_equal:
	movl    $L_EQU, %edx            # result = equal
	jmp     .L02_leave

.L02_greater:
	movl    $L_GTR, %edx            # result = greater

.L02_leave:
	movl    L_RES(%ebp), %edi       # get result address
	movb    %dl, (%edi)             # set result

	popl    %ebx                    # restore register
	popl    %esi                    # restore register
	popl    %edi                    # restore register
	leave                           # remove stack frame
	ret

#============================================================================/
#
#       FUNCTION
#             s30lenl     (VAR str     : moveobject ;
#                         val          : char ;
#                         start        : integer ;
#                         cnt          : integer ) : integer ;
#
	.globl  s30lenl
s30lenl:

	pushl   %ebp                    # build stack frame
	movl    %esp, %ebp
	pushl   %edi                    # save register

L_PARMPOS       =       8

L_STR           =       L_PARMPOS
L_VAL           =       L_PARMPOS + 4
L_START         =       L_PARMPOS + 8
L_CNT           =       L_PARMPOS + 12

	movl    L_STR(%ebp), %edi       # get staring address
	addl    L_START(%ebp), %edi     # add start position
	decl    %edi                    # correct for start pos = 1
	movl    L_CNT(%ebp), %ecx       # get count
	movl    L_VAL(%ebp), %eax       # get value

	cld                             # set direction to forward

	repnz                           # repeat the following instruction,
					# while %ecx <> 0 and instruction
					# result is unequal; decrement %ecx
	scasb                           # compare %al with (%edi);
					# update %edi

	jne     .L03_count              # if 'val' not found, jump
	incl	%ecx			# backstep before 'val'

.L03_count:
	movl    L_CNT(%ebp), %eax       # get count
	subl	%ecx, %eax		# subtract remainig bytes
					# return value in %eax

	popl    %edi                    # restore register
	leave                           # remove stack frame
	ret

#============================================================================/
#
#	Link-Check
#
	.globl  sp30a24
sp30a24:

	movl    $926190621 , %eax       # set link check code
	ret

#============================================================================/
#
#       PROCEDURE
#             s30xorc4 (c4_1     : tsp_c4;
#                   c4_2          : tsp_c4;
#                   VAR c4_target : tsp_c4);
#
#Could also be written in C (we know that sizeof(tsp_c4) == 4)
#
#int s30xorc4(c_1, c_2, c_target)
#unsigned char *c_1;
#unsigned char *c_2;
#unsigned char *c_target;
#{
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#    c_target++;
#    c_1++;
#    c_2++;
#
#    *c_target = *c_1 ^ *c_2;
#}
	.globl	s30xorc4
	.align	4
s30xorc4:
	pushl   %ebp                    # build stack frame
	movl    %esp, %ebp
	pushl   %edi                    # save register
	pushl   %esi                    # save register
	pushl   %ebx                    # save register

	movl	8(%ebp),%edi
	movl	12(%ebp),%esi
	movl	16(%ebp),%ebx
	movzbl	(%edi),%eax
	movzbl	(%esi),%edx
	xorl	%edx,%eax
	movb	%al,(%ebx)
	incl	%ebx
	incl	%edi
	incl	%esi
	movzbl	(%edi),%eax
	movzbl	(%esi),%edx
	xorl	%edx,%eax
	movb	%al,(%ebx)
	incl	%ebx
	incl	%edi
	incl	%esi
	movzbl	(%edi),%eax
	movzbl	(%esi),%edx
	xorl	%edx,%eax
	movb	%al,(%ebx)
	incl	%ebx
	incl	%edi
	incl	%esi
	movzbl	(%edi),%eax
	movzbl	(%esi),%edx
	xorl	%edx,%eax
	movb	%al,(%ebx)

	popl    %ebx                    # restore register
	popl    %esi                    # restore register
	popl    %edi                    # restore register
	leave                           # remove stack frame
	ret
&endif I386

&if $MACH = ALPHA
&ifdef BIT64
	.text
	.align	4
	.globl	s30map
	.ent	s30map
/* void s30map(code_t, source, spos, dest, dpos, length)
 *             unsigned char *code_t;
 *             unsigned char *source;
 *             int spos;
 *             unsigned char *dest;
 *             int dpos;
 *             int length;
 */
s30map:
	ldgp	$gp, 0($27)
	.frame	$sp, 0, $26, 0
	.prologue	1
				# code_t in $16
				# source in $17
				# spos   in $18
				# dest   in $19
				# dpos   in $20
				# length in $21
	addl	$18, -1, $1	# spos - 1             into $1
	addq	$17, $1, $17	# source += (spos - 1) in   $17
	addl	$20, -1, $2	# dpos - 1             into $2
	addq	$19, $2, $19	# dest += (dpos - 1)   in   $19
	ble	$21, s30map_ret	# if ( length <= 0 ) skip loop, return
	.align	3
s30map_lp:
	ldq_u	$3, 0($17)	# source
	extbl	$3, $17, $3
	addq	$3, $16, $4	# code_t[*source]
	ldq_u	$5, 0($4)
	extbl	$5, $4, $5
	.set	 noat
	ldq_u	$28, 0($19)	# dest
	insbl	$5, $19, $6
	mskbl	$28, $19, $28
	bis	$28, $6, $28
	stq_u	$28, 0($19)	# *dest = code_t[*source]
	.set	 at
	addq	$19, 1, $19	# dest++
	addq	$17, 1, $17	# *source++
	addl	$21, -1, $21	# length--
	bgt	$21, s30map_lp	# if ( length > 0 ) loop again
s30map_ret:
	ret	$31, ($26), 1	# return
	.end	s30map

	.text
	.align	4
	.globl	s30lcm
	.globl	s30lcm1
	.globl	s30lcm2
	.globl	s30lcm3
	.ent	s30lcm
/* # define L_LESS	0
 * # define L_EQUAL	1
 * # define L_GREATER	2
 * void s30lcm(buf1, fieldpos1, fieldlen1, buf2, fieldpos2, fieldlen2, retval)
 *             unsigned char *buf1;
 *             int fieldpos1;
 *             int fieldlen1;
 *             unsigned char *buf2;
 *             int fieldpos2;
 *             int fieldlen2;
 *             unsigned char *retval;
 */
s30lcm:
s30lcm1:
s30lcm2:
s30lcm3:
	ldgp	$gp, 0($27)
	lda	$sp, -64($sp)
	stq	$26, 0($sp)
	.mask	0x04000000, -64
	.frame	$sp, 64, $26, 48
	.prologue	1
	bis	$16, $16, $2	# buf1      into $2
	addl	$17, 0, $3	# fieldpos1 into $3
	addl	$18, 0, $1	# fieldlen1 into $1
				# buf2      in   $19
	addl	$20, 0, $20	# fieldpos2 in   $20
	addl	$21, 0, $21	# fieldlen2 in   $21
				# retval    on stack

	subq	$1, $21, $4	# if ( fieldlen1 != fieldlen2 )
	bne	$4, s30lcm_1	#     goto s30lcm_1
				# now we know that fieldlen1 == fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#      buf2 + fieldpos2 - 1,
				#      fieldlen1 )
	addq	$3, $2, $16	# fieldpos1 + buf1       into $16
	addq	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addq	$20, $19, $17	# fieldpos2 + buf2       into $17
	addq	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$1, $1, $18	# fieldlen1              into $18
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	beq	$0, s30lcm_ret1	# if ( rc == 0 ) prepare to return
	blt	$0, s30lcm_ret0	# if ( rc < 0 ) prepare to return
s30lcm_ret2:			# prepare to return with *retval = L_GREATER
	ldil	$22, 2		# L_GREATER is 2
	ldq	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	insbl	$22, $23, $24
	mskbl	$28, $23, $28
	bis	$28, $24, $28
	stq_u	$28, 0($23)	# (*retval) = L_GREATER
	.set	 at
	br	$31, s30lcm_ret	# return

s30lcm_1:			# now we know that fieldlen1 != fieldlen2
	subq	$1, $21, $25	# if ( fieldlen1 > fieldlen2 )
	bgt	$25, s30lcm_3	#     goto s301lcm_3
				# now we know that fieldlen1 < fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#      buf2 + fieldpos2 - 1,
				#      fieldlen1 )
	addq	$3, $2, $16	# fieldpos1 + buf1       into $16
	addq	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addq	$20, $19, $17	# fieldpos2 + buf2       into $17
	addq	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$1, $1, $18	# fieldlen1              into $18
	stq	$19, 40($sp)	# save buf1
	stl	$20, 48($sp)	# save fieldpos2
	stl	$21, 56($sp)	# save fieldlen2
	stl	$1, 32($sp)	# save fieldlen1
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	ldq	$19, 40($sp)	# restore buf2
	ldl	$20, 48($sp)	# restore fieldpos2
	ldl	$21, 56($sp)	# restore fieldlen2
	ldl	$1, 32($sp)	# restore fieldlen1
	bne	$0, s30lcm_2	# if ( rc != 0 ) goto s30lcm_2
				# for ( buf2 += fieldpos2-1, ix=fieldlen1;
				#       ix < fieldlen2; ix++)
	addl	$20, -1, $27	# fieldpos2 - 1         into $27
	addq	$19, $27, $19	# buf2 += fieldpos2 - 1 in   $19
	bis	$1, $1, $0	# ix = fieldlen1        into $0
				# we still know that fieldlen1 < fieldlen2
	.align	3
s30lcm_lp1:			# start loop
	addq	$0, $19, $5	# buf2[ix] address  into $5
	ldq_u	$6, 0($5)	# buf2[ix] contents into $6
	extbl	$6, $5, $6
	bne	$6, s30lcm_ret0	# if ( buf2[ix] != '\0' ) prepare to return
	addl	$0, 1, $0	# ix++
	subq	$0, $21, $8	# if ( ix < fieldlen2 )
	bne	$8, s30lcm_lp1	#    loop again
	br	$31, s30lcm_ret1	# prepare to return

s30lcm_2:			# now we know that rc != 0
	bgt	$0, s30lcm_ret2	# if ( rc > 0 ) prepare to return
	br	$31, s30lcm_ret0	# prepare to return

s30lcm_3:			# now we know that fieldlen1 > fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#    buf2 + fieldpos2 - 1,
				#    fieldlen2 )
	addq	$3, $2, $16	# fieldpos1 + buf1       into $16
	addq	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addq	$20, $19, $17	# fieldpos2 + buf2       into $17
	addq	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$21, $21, $18	# fieldlen2              into $18
	stl	$21, 56($sp)	# save fieldlen2
	stl	$1, 32($sp)	# save fieldlen1
	stq	$2, 16($sp)	# save buf1
	stl	$3, 24($sp)	# save fieldpos1
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	bne	$0, s30lcm_4	# if ( rc != 0 ) prepare to return
	ldl	$21, 56($sp)	# restore fieldlen2
	ldl	$1, 32($sp)	# restore fieldlen1
	ldq	$2, 16($sp)	# restore buf1
	ldl	$3, 24($sp)	# restore fieldpos1
				# for ( buf1 += fieldpos1-1, ix=fieldlen2;
				#     ix < fieldlen1; ix++)
	addl	$3, -1, $6	# fieldpos1 - 1           into $6
	addq	$2, $6, $2	# buf1 += (fieldpos1 - 1) in   $2
	bis	$21, $21, $0	# ix = fieldlen2          into $0
				# we still know that fieldlen1 > fieldlen2
	.align	3
s30lcm_lp2:			# start loop
	addq	$0, $2, $8	# buf1[ix] addr into $8
	ldq_u	$22, 0($8)	# buf1[ix] contents into $22
	extbl	$22, $8, $22
	bne	$22, s30lcm_ret2	# if ( buf1[ix] != '\0' ) prepare to ret
	addl	$0, 1, $0	# ix++
	subq	$0, $1, $27	# if ( ix != fieldlen1 )
	bne	$27, s30lcm_lp2	#    loop again
s30lcm_ret1:			# prepare to return with *retval = L_EQUAL
	ldil	$22, 1		# L_EQUAL is 1
	ldq	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	insbl	$22, $23, $24
	mskbl	$28, $23, $28
	bis	$28, $24, $28
	stq_u	$28, 0($23)	# (*retval) = L_EQUAL
	.set	 at
	br	$31, s30lcm_ret	# return

s30lcm_4:			# now we know that rc != 0
	bgt	$0, s30lcm_ret2	# if ( rc > 0 ) prepare to return
s30lcm_ret0:			# prepare to return with *retval = L_LESS
	ldq	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	mskbl	$28, $23, $28
	stq_u	$28, 0($23)	# (*retval) = L_LESS
	.set	 at
s30lcm_ret:			# return
	ldq	$26, 0($sp)
	lda	$sp, 64($sp)
	ret	$31, ($26), 1
	.end	s30lcm

	.text
	.align	4
	.globl	s30xorc4
	.ent	s30xorc4
/* void s30xorc4(c_1, c_2, c_target)
 *               unsigned char *c_1;
 *               unsigned char *c_2;
 *               unsigned char *c_target;
 */
s30xorc4:
	ldgp	$gp, 0($27)
	.frame	$sp, 0, $26, 0
	.prologue	1
	uldl	$1, 0($17)	# *(unaligned int)c_2
	uldl	$2, 0($16)	# *(unaligned int)c_1
	xor	$1, $2, $3	# *c_2 ^ *c_1
	ustl	$3, 0($18)	# *(unaligned int)c_target
	ret	$31, ($26), 1	# return
	.end	s30xorc4

	.text
	.align	4
	.globl	sp30a24
	.ent	sp30a24
/* int sp30a24()
 */
sp30a24:
	ldgp	$gp, 0($27)
	.frame	$sp, 0, $26, 0
	.prologue	1
	ldil	$0, 926190621	# return link check code
	ret	$31, ($26), 1
	.end	sp30a24

	.text	
	.align	4
	.globl	s30cmp
	.globl	s30cmp1
	.globl	s30cmp2
	.globl	s30cmp3
	.ent	s30cmp 2
/* # define L_LESS	0
 * # define L_EQUAL	1
 * # define L_GREATER	2
 * s30cmp ( unsigned char * buf1,
 *          int             fieldpos1,
 *          int             fieldlength1,
 *          unsigned char * buf2,
 *          int             fieldpos2,
 *          int             fieldlength2,
 *          unsigned char * l_result)
 */
s30cmp:
s30cmp1:
s30cmp2:
s30cmp3:
	ldgp	$gp, 0($27)
	lda	$sp, -16($sp)
	stq	$26, 0($sp)
	.mask	0x04000000, -16
	.frame	$sp, 16, $26, 0
	.prologue	1
	bis	$16, $16, $3	# buf1
	addl	$17, 0, $2	# fieldpos1
	addl	$18, 0, $1	# fieldlength1
	addl	$20, 0, $20	# fieldpos2
	addl	$21, 0, $21	# fieldlength2

	subq	$1, $21, $4	# compare fieldlength1 with fieldlength2
	bne	$4, s30cmp_a	# if fieldlength1 != fieldlength2 goto s30cmp_a
	addq	$2, $3, $16	# memcmp arg1: fieldpos1 + buf1
	addq	$16, -1, $16	# memcmp arg1: - 1
	addq	$20, $19, $17	# memcmp arg2: fieldpos2 + buf2
	addq	$17, -1, $17	# memcmp arg2: - 1
	bis	$1, $1, $18	# memcmp arg3: fieldlength1
	jsr	$26, memcmp	# i = memcmp()
	ldgp	$gp, 0($26)
	blt	$0, s30cmp_L	# if i < 0 goto s30cmp_L
	bgt	$0, s30cmp_G	# if i > 0 goto s30cmp_G
	ldil	$7, 1		# L_EQUAL
	br	$31, s30cmp_GE 	# goto s30cmp_GE

s30cmp_a:			# fieldlength1 != fieldlength2
	bgt	$4, s30cmp_b	# if fieldlength1 > fieldlength2 goto s30cmp_b
	addq	$2, $3, $16	# memcmp arg1: buf1 + fieldpos1
	addq	$16, -1, $16	# memcmp arg1: - 1
	addq	$20, $19, $17	# memcmp arg2: buf2 + fieldpos2
	addq	$17, -1, $17	# memcmp arg2: - 1
	bis	$1, $1, $18	# memcmp arg3: fieldlength1
	.livereg	0x0001F002,0x00000000
	jsr	$26, memcmp	# i = memcmp()
	ldgp	$gp, 0($26)
	bgt	$0, s30cmp_G	# if i > 0 goto s30cmp_G
	br	$31, s30cmp_L	# goto s30cmp_L

s30cmp_b:			# fieldlength1 > fieldlength2
	addq	$2, $3, $16	# memcmp arg1: buf1 + fieldpos1
	addq	$16, -1, $16	# memcmp arg1: - 1
	addq	$20, $19, $17	# memcmp arg2: buf2 + fieldpos2
	addq	$17, -1, $17	# memcmp arg2: - 1
	bis	$21, $21, $18	# memcmp arg3: fieldlength2
	.livereg	0x0001F002,0x00000000
	jsr	$26, memcmp	# i = memcmp()
	ldgp	$gp, 0($26)
	blt	$0, s30cmp_L	# if i < 0 goto s30cmp_L
s30cmp_G:
	ldil	$7, 2		# L_GREATER
s30cmp_GE:
	ldq	$8, 16($sp)	# l_result
	.set	 noat
	ldq_u	$28, 0($8)	# *l_result
	insbl	$7, $8, $24	# either L_GREATER or L_EQUAL
	mskbl	$28, $8, $28
	bis	$28, $24, $28
	stq_u	$28, 0($8)	# *l_result = either L_GREATER or L_EQUAL
	.set	 at
	br	$31, s30cmp_ret	# goto return

s30cmp_L:
	ldq	$8, 16($sp)	# l_result
	.set	 noat
	ldq_u	$28, 0($8)
	mskbl	$28, $8, $28
	stq_u	$28, 0($8)	# *l_result = L_LESS
	.set	 at
s30cmp_ret:
	ldq	$26, 0($sp)	# get return address
	lda	$sp, 16($sp)	# restore stack
	ret	$31, ($26), 1	# return
	.end	s30cmp
&else
/* BIT32 FOR ALPHA NT */
	.text
	.align	4
	.globl	s30map
	.ent	s30map
/* void s30map(code_t, source, spos, dest, dpos, length)
 *             unsigned char *code_t;
 *             unsigned char *source;
 *             int spos;
 *             unsigned char *dest;
 *             int dpos;
 *             int length;
 */
s30map:
//	ldgp	$gp, 0($27)
//	.frame	$sp, 0, $26, 0
	.prologue	0
				# code_t in $16
				# source in $17
				# spos   in $18
				# dest   in $19
				# dpos   in $20
				# length in $21
	addl	$18, -1, $1	# spos - 1             into $1
	addl	$17, $1, $17	# source += (spos - 1) in   $17
	addl	$20, -1, $2	# dpos - 1             into $2
	addl	$19, $2, $19	# dest += (dpos - 1)   in   $19
	ble	$21, s30map_ret	# if ( length <= 0 ) skip loop, return
	.align	3
s30map_lp:
	ldq_u	$3, 0($17)	# source
	extbl	$3, $17, $3
	addl	$3, $16, $4	# code_t[*source]
	ldq_u	$5, 0($4)
	extbl	$5, $4, $5
	.set	 noat
	ldq_u	$28, 0($19)	# dest
	insbl	$5, $19, $6
	mskbl	$28, $19, $28
	bis	$28, $6, $28
	stq_u	$28, 0($19)	# *dest = code_t[*source]
	.set	 at
	addl	$19, 1, $19	# dest++
	addl	$17, 1, $17	# *source++
	addl	$21, -1, $21	# length--
	bgt	$21, s30map_lp	# if ( length > 0 ) loop again
s30map_ret:
	ret	$31, ($26), 1	# return
	.end	s30map

	.text
	.align	4
	.globl	s30lcm
	.globl	s30lcm1
	.globl	s30lcm2
	.globl	s30lcm3
	.ent	s30lcm
/* # define L_LESS	0
 * # define L_EQUAL	1
 * # define L_GREATER	2
 * void s30lcm(buf1, fieldpos1, fieldlen1, buf2, fieldpos2, fieldlen2, retval)
 *             unsigned char *buf1;
 *             int fieldpos1;
 *             int fieldlen1;
 *             unsigned char *buf2;
 *             int fieldpos2;
 *             int fieldlen2;
 *             unsigned char *retval;
 */
s30lcm:
s30lcm1:
s30lcm2:
s30lcm3:
//	ldgp	$gp, 0($27)
//	.mask	0x04000000, -64
//	.frame	$sp, 64, $26, 48
	.prologue	0

	lda	$sp, -64($sp)
	stq	$26, 0($sp)

	bis	$16, $16, $2	# buf1      into $2
	addl	$17, 0, $3	# fieldpos1 into $3
	addl	$18, 0, $1	# fieldlen1 into $1
				# buf2      in   $19
	#addl	$20, 0, $20	# fieldpos2 in   $20
	#addl	$21, 0, $21	# fieldlen2 in   $21
				# retval    on stack

	subl	$1, $21, $4	# if ( fieldlen1 != fieldlen2 )
	bne	$4, s30lcm_1	#     goto s30lcm_1
				# now we know that fieldlen1 == fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#      buf2 + fieldpos2 - 1,
				#      fieldlen1 )
	addl	$3, $2, $16	# fieldpos1 + buf1       into $16
	addl	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addl	$20, $19, $17	# fieldpos2 + buf2       into $17
	addl	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$1, $1, $18	# fieldlen1              into $18
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	beq	$0, s30lcm_ret1	# if ( rc == 0 ) prepare to return
	blt	$0, s30lcm_ret0	# if ( rc < 0 ) prepare to return
s30lcm_ret2:			# prepare to return with *retval = L_GREATER
	ldil	$22, 2		# L_GREATER is 2
	ldl	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	insbl	$22, $23, $24
	mskbl	$28, $23, $28
	bis	$28, $24, $28
	stq_u	$28, 0($23)	# (*retval) = L_GREATER
	.set	 at
	br	$31, s30lcm_ret	# return

s30lcm_1:			# now we know that fieldlen1 != fieldlen2
	subl	$1, $21, $25	# if ( fieldlen1 > fieldlen2 )
	bgt	$25, s30lcm_3	#     goto s301lcm_3
				# now we know that fieldlen1 < fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#      buf2 + fieldpos2 - 1,
				#      fieldlen1 )
	addl	$3, $2, $16	# fieldpos1 + buf1       into $16
	addl	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addl	$20, $19, $17	# fieldpos2 + buf2       into $17
	addl	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$1, $1, $18	# fieldlen1              into $18
	stl	$19, 40($sp)	# save buf1
	stl	$20, 48($sp)	# save fieldpos2
	stl	$21, 56($sp)	# save fieldlen2
	stl	$1, 32($sp)	# save fieldlen1
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	ldq	$19, 40($sp)	# restore buf2
	ldl	$20, 48($sp)	# restore fieldpos2
	ldl	$21, 56($sp)	# restore fieldlen2
	ldl	$1, 32($sp)	# restore fieldlen1
	bne	$0, s30lcm_2	# if ( rc != 0 ) goto s30lcm_2
				# for ( buf2 += fieldpos2-1, ix=fieldlen1;
				#       ix < fieldlen2; ix++)
	addl	$20, -1, $27	# fieldpos2 - 1         into $27
	addl	$19, $27, $19	# buf2 += fieldpos2 - 1 in   $19
	bis	$1, $1, $0	# ix = fieldlen1        into $0
				# we still know that fieldlen1 < fieldlen2
	.align	3
s30lcm_lp1:			# start loop
	addl	$0, $19, $5	# buf2[ix] address  into $5
	ldq_u	$6, 0($5)	# buf2[ix] contents into $6
	extbl	$6, $5, $6
	bne	$6, s30lcm_ret0	# if ( buf2[ix] != '\0' ) prepare to return
	addl	$0, 1, $0	# ix++
	subl	$0, $21, $8	# if ( ix < fieldlen2 )
	bne	$8, s30lcm_lp1	#    loop again
	br	$31, s30lcm_ret1	# prepare to return

s30lcm_2:			# now we know that rc != 0
	bgt	$0, s30lcm_ret2	# if ( rc > 0 ) prepare to return
	br	$31, s30lcm_ret0	# prepare to return

s30lcm_3:			# now we know that fieldlen1 > fieldlen2
				# rc = memcmp ( buf1 + fieldpos1 - 1,
				#    buf2 + fieldpos2 - 1,
				#    fieldlen2 )
	addl	$3, $2, $16	# fieldpos1 + buf1       into $16
	addl	$16, -1, $16	# (fieldpos1 + buf1) - 1 into $16
	addl	$20, $19, $17	# fieldpos2 + buf2       into $17
	addl	$17, -1, $17	# (fieldpos2 + buf2) - 1 into $17
	bis	$21, $21, $18	# fieldlen2              into $18
	stl	$21, 56($sp)	# save fieldlen2
	stl	$1, 32($sp)	# save fieldlen1
	stq	$2, 16($sp)	# save buf1
	stl	$3, 24($sp)	# save fieldpos1
	jsr	$26, memcmp
	ldgp	$gp, 0($26)
	bne	$0, s30lcm_4	# if ( rc != 0 ) prepare to return
	ldl	$21, 56($sp)	# restore fieldlen2
	ldl	$1, 32($sp)	# restore fieldlen1
	ldq	$2, 16($sp)	# restore buf1
	ldl	$3, 24($sp)	# restore fieldpos1
				# for ( buf1 += fieldpos1-1, ix=fieldlen2;
				#     ix < fieldlen1; ix++)
	addl	$3, -1, $6	# fieldpos1 - 1           into $6
	addl	$2, $6, $2	# buf1 += (fieldpos1 - 1) in   $2
	bis	$21, $21, $0	# ix = fieldlen2          into $0
				# we still know that fieldlen1 > fieldlen2
	.align	3
s30lcm_lp2:			# start loop
	addl	$0, $2, $8	# buf1[ix] addr into $8
	ldq_u	$22, 0($8)	# buf1[ix] contents into $22
	extbl	$22, $8, $22
	bne	$22, s30lcm_ret2	# if ( buf1[ix] != '\0' ) prepare to ret
	addl	$0, 1, $0	# ix++
	subl	$0, $1, $27	# if ( ix != fieldlen1 )
	bne	$27, s30lcm_lp2	#    loop again
s30lcm_ret1:			# prepare to return with *retval = L_EQUAL
	ldil	$22, 1		# L_EQUAL is 1
	ldq	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	insbl	$22, $23, $24
	mskbl	$28, $23, $28
	bis	$28, $24, $28
	stq_u	$28, 0($23)	# (*retval) = L_EQUAL
	.set	 at
	br	$31, s30lcm_ret	# return

s30lcm_4:			# now we know that rc != 0
	bgt	$0, s30lcm_ret2	# if ( rc > 0 ) prepare to return
s30lcm_ret0:			# prepare to return with *retval = L_LESS
	ldq	$23, 64($sp)	# get retval from stack
	.set	 noat
	ldq_u	$28, 0($23)
	mskbl	$28, $23, $28
	stq_u	$28, 0($23)	# (*retval) = L_LESS
	.set	 at
s30lcm_ret:			# return
	ldq	$26, 0($sp)
	lda	$sp, 64($sp)
	ret	$31, ($26), 1
	.end	s30lcm

	.text
	.align	4
	.globl	s30xorc4
	.ent	s30xorc4
/* void s30xorc4(c_1, c_2, c_target)
 *               unsigned char *c_1;
 *               unsigned char *c_2;
 *               unsigned char *c_target;
 */
s30xorc4:
//	ldgp	$gp, 0($27)
//	.frame	$sp, 0, $26, 0
	.prologue	0

	ldq_u	$1, 0($16)	# c_1
	extbl	$1, $16, $1
	ldq_u	$2, 0($17)	# c_2
	extbl	$2, $17, $2
	xor	$1, $2, $3	# *c_1 ^ *c_2 into $3
	.set	 noat
	ldq_u	$28, 0($18)	# c_target into $28
	insbl	$3, $18, $4
	mskbl	$28, $18, $28
	bis	$28, $4, $28
	stq_u	$28, 0($18)	# *c_target = (*c_1 ^ *c_2)
	.set	 at

	addl	$16, 1, $16	# c_1++
	addl	$17, 1, $17	# c_2++
	addl	$18, 1, $18	# c_target++

	ldq_u	$1, 0($16)	# c_1
	extbl	$1, $16, $1
	ldq_u	$2, 0($17)	# c_2
	extbl	$2, $17, $2
	xor	$1, $2, $3	# *c_1 ^ *c_2 into $3
	.set	 noat
	ldq_u	$28, 0($18)	# c_target into $28
	insbl	$3, $18, $4
	mskbl	$28, $18, $28
	bis	$28, $4, $28
	stq_u	$28, 0($18)	# *c_target = (*c_1 ^ *c_2)
	.set	 at

	addl	$16, 1, $16	# c_1++
	addl	$17, 1, $17	# c_2++
	addl	$18, 1, $18	# c_target++

	ldq_u	$1, 0($16)	# c_1
	extbl	$1, $16, $1
	ldq_u	$2, 0($17)	# c_2
	extbl	$2, $17, $2
	xor	$1, $2, $3	# *c_1 ^ *c_2 into $3
	.set	 noat
	ldq_u	$28, 0($18)	# c_target into $28
	insbl	$3, $18, $4
	mskbl	$28, $18, $28
	bis	$28, $4, $28
	stq_u	$28, 0($18)	# *c_target = (*c_1 ^ *c_2)
	.set	 at

	addl	$16, 1, $16	# c_1++
	addl	$17, 1, $17	# c_2++
	addl	$18, 1, $18	# c_target++

	ldq_u	$1, 0($16)	# c_1
	extbl	$1, $16, $1
	ldq_u	$2, 0($17)	# c_2
	extbl	$2, $17, $2
	xor	$1, $2, $3	# *c_1 ^ *c_2 into $3
	.set	 noat
	ldq_u	$28, 0($18)	# c_target into $28
	insbl	$3, $18, $4
	mskbl	$28, $18, $28
	bis	$28, $4, $28
	stq_u	$28, 0($18)	# *c_target = (*c_1 ^ *c_2)
	.set	 at

	ret	$31, ($26), 1	# return
	.end	s30xorc4

	.text
	.align	4
	.globl	sp30a24
	.ent	sp30a24
/* int sp30a24()
 */
sp30a24:
//	ldgp	$gp, 0($27)
//	.frame	$sp, 0, $26, 0
	.prologue	0
	ldil	$0, 926190621	# return link check code
	ret	$31, ($26), 1
	.end	sp30a24
&endif
&endif

.CM *-END-* code ----------------------------------------
.sp
.sp
***********************************************************
ANZAHL STATEMENTS :         195
ANZAHL LINES OF CODE :         652
.pa
