Welcome to mirror list, hosted at ThFree Co, Russian Federation.

strcat.S « hppa « machine « libc « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9fcdd790f48ee7dfa37110a1ed888518b09f72cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
 *
 *  To anyone who acknowledges that this file is provided "AS IS"
 *  without any express or implied warranty:
 *      permission to use, copy, modify, and distribute this file
 *  for any purpose is hereby granted without fee, provided that
 *  the above copyright notice and this notice appears in all
 *  copies, and that the name of Hewlett-Packard Company not be
 *  used in advertising or publicity pertaining to distribution
 *  of the software without specific, written prior permission.
 *  Hewlett-Packard Company makes no representations about the
 *  suitability of this software for any purpose.
 */

/* HPUX_ID:	@(#) $Revision$	*/
/*
 * strcat(s1, s2)
 *
 * Concatenate s2 on the end of s1.  S1's space must be large enough.
 * Return s1.
 */
#include "DEFS.h"

#define	d_addr  r26
#define	s_addr  r25
#define	tmp6    r24
#define	tmp1    r19
#define	tmp2    r20
#define	tmp3    r21
#define	tmp4    r22
#define	tmp5	arg3
#define	save	r1


ENTRY(strcat)

	comb,=		r0,s_addr,done	/* quit if s2=NULL */
        copy      d_addr,ret0          /* The return value is the value of d_addr. DELAY SLOT*/

/* First look for end of s1 (d_addr) */

        extru       d_addr,31,2,tmp1   /* Extract the low two bits of the dest address. */
	combt,=		tmp1,r0,dont_mask
	dep		0,31,2,d_addr	/*set word alignment */
	ldwm		4(d_addr),tmp2
	sh3add		tmp1,r0,save	/* build mask based on tmp1 */
	mtctl		save,11
	zvdepi		-2,32,save
	or		save,tmp2,tmp2
	uxor,nbz	tmp2,r0,save
search:
	b,n		found_end	/* nullified under uxor conditions above and below */
dont_mask:
	ldwm		4(d_addr),tmp2
	comib,tr	r0,r0,search
	uxor,nbz	tmp2,r0,save

found_end:				/* at this point d_addr points to word */
	extru,<>	save,7,8,r0	/* following word with null */
	addib,tr,n	-4,d_addr,begin_copy	/*set d_addr to end of s1 */
	extru,<>	save,15,8,r0
	addib,tr,n	-3,d_addr,begin_copy
	extru,<>	save,23,8,r0
	addi		-1,d_addr,d_addr
	addi		-1,d_addr,d_addr


begin_copy:

        extru       s_addr,31,2,tmp1   /* Extract the low two bits of the source address. */
        extru       d_addr,31,2,tmp6   /* Extract the low two bits of the destination address. */
        sub,=       tmp6,tmp1,tmp3     /* Compute the shift quantity and don't branch if tmp6=tmp1. */
        b           not_aligned        /* Not_aligned says that shifts Will be needed. */
        dep         0,31,2,s_addr      /* Compute the word address of the source.  DELAY SLOT. */
/* aligned */

	combt,=		tmp6,r0,skip_mask
        ldwm        	4(0,s_addr),tmp1   /* tmp1 = *s_addr   s_addr += 4 (DELAY SLOT) */
	sh3add		tmp6,r0,save
	mtctl		save,r11
	zvdepi		-2,32,save
	or		save,tmp1,tmp1
	uxor,nbz	tmp1,r0,save
	b,n		first_null	/* special case: null in first word */
	b,n		skip_mask2

chunks:
	b,n		null_found	/* delay slot for uxor below */

skip_mask2:
	stbys,b,m	tmp1,4(d_addr)
	ldwm		4(s_addr),tmp1
skip_mask:
	comib,tr	0,0,chunks
	uxor,nbz	tmp1,r0,save

/* Begin non_aligned code.  */

not_aligned:
        sh3add,>=       tmp3,r0,tmp4        /* compute the shift amt.and skip load if tmp6 > tmp1. */
        ldwm         	4(0,s_addr),tmp1    /* load up the first word from the source. tmp1 = *s_addr++ */
        ldwm        	4(0,s_addr),tmp2    /* get either first or second word from source.  */
	combt,=		tmp6,r0,chunk2      /* don't mask if whole word is valid */
        mtctl        	tmp4,11             /* load the shift count into cr11 = shift count register. */
        vshd        	tmp1,tmp2,tmp3      /* position data !  (delay slot) */
	sh3add		tmp6,r0,save  	    /* setup r1 */
	mtctl		save,r11	    /* set-up cr11 for mask */
	zvdepi		-2,32,save
	or		save, tmp3, tmp3
	uxor,nbz	tmp3,r0,save
	b,n		first_null2
	b		did_mask
        mtctl        	tmp4,11            /* re-load the shift count into cr11 */

chunk2:
	vshd		tmp1,tmp2,tmp3
	uxor,nbz	tmp3, r0, save
	b,n		null_found
did_mask:
        stbys,b,m   	tmp3,4(0,d_addr)    /* store !  */

        ldwm        	4(0,s_addr),tmp1    /* get next word !  */
        vshd        	tmp2,tmp1,tmp3      /* position data !  */
	uxor,nbz	tmp3, r0, save
	b,n		null_found
	stwm		tmp3,4(d_addr)
	comib,tr	0,0,chunk2
	ldwm		4(s_addr),tmp2


null_found:				/* adjust d_addr and store final word */

	extru,<>	save,7,8,r0
	addib,tr,n	1,d_addr,store_final
	extru,<>	save,15,8,r0
	addib,tr,n	2,d_addr,store_final
	extru,<> 	save,23,8,r0
	addib,tr	3,d_addr,store_final2
	bv		0(r2)
	stw		save,0(d_addr)

store_final:
	bv		0(r2)
store_final2:
	stbys,e		save,0(d_addr) 	/* delay slot */

first_null:			/* null found in first word of aligned (wrt d_addr) */
	addi		-4,s_addr,s_addr
	ldbx		tmp6(s_addr),tmp4
	add		tmp6,s_addr,s_addr
	comib,=		0,tmp4,done
	stbs,ma		tmp4,1(d_addr)
	ldbs		1(s_addr),tmp4
	comib,=		0,tmp4,done
	stbs,ma		tmp4,1(d_addr)
	bv		0(r2)		/* done */
	stbs		0,0(d_addr)

first_null2:	/* null found in first word of non-aligned (wrt d_addr) */
	addibt,=	-1,tmp6,check3	/* check last 3 bytes of word */
	extru   	save,15,8,tmp4
	addibt,=,n	-1,tmp6,check2	/* check last 2 bytes */
	bv		0(r2)
	stbys,b		save, 0(d_addr)

check3:
	combt,=		tmp4,r0,done
	stbs,ma		tmp4,1(d_addr)
check2:
	extru,<>	save,23,8,tmp4
	bv		0(r2)
	stbs,ma		tmp4,1(d_addr)
	bv		0(r2)
	stbs		r0,0(d_addr)

done:
EXIT(strcat)