.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 1988-2005 SAP AG-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

.nf

.nf

    ========== licence begin  GPL
    Copyright (c) 1988-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program 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 General Public License for more details.

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


.fo


.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          : tsp00_C4;
			c4_2          : tsp00_C4;
			VAR c4_target : tsp00_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     : tsp00_C4;
            c4_2          : tsp00_C4;
            VAR c4_target : tsp00_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  : tsp00_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 in [ I386 ]
	.file   "vsp32a.s"
	.text
&if $MACH not in [ I386 ]
#============================================================================/
#
#       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
&endif not I386
#============================================================================/
#
#       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

&if $MACH not in [ I386 ]
#============================================================================/
#
#	Link-Check
#
	.globl  sp30a24
sp30a24:

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

#============================================================================/
#
#       PROCEDURE
#             s30xorc4 (c4_1     : tsp00_C4;
#                   c4_2          : tsp00_C4;
#                   VAR c4_target : tsp00_C4);
#
#Could also be written in C (we know that sizeof(tsp00_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 not I386
&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
