summaryrefslogtreecommitdiffstats
path: root/private/crt32/string/ppc/strcatp.s
blob: bbbfd7a968da555f17c44ab30d59a37c8a311059 (plain) (blame)
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
//      TITLE("strcpy strcat")
//++
//
// Copyright (c) 1994  IBM Corporation
//
// Module Name:
//
//    strcatp.s
//
// Abstract:
//
//    The module implements the routines strcpy and strcat.
//
// Author:
//
//    Jeff Simon   (jhs) 02-Aug-1994
//
// Environment:
//
//    User or Kernel mode.
//
// Revision History:
//
//    Peter Johnston (plj@vnet.ibm.com) 08-Aug-1994
//
//      Minor optimization.
//
//--

#include <kxppc.h>

//++
//
// PUCHAR
// strcpy (
//     PUCHAR dest;
//     PUCHAR src;
// )
//
// Routine Description:
//
//    Copies an ANSI (null terminated) string from src to dest.
//
// Arguments:
//
//    dest (r.3) - A pointer to the string destination  
//
//    src  (r.4) - A pointer to the string source  
//
//
// Return Value:
//
//    dest      Pointer to the destination string.
//
//--

        LEAF_ENTRY(strcpy)

        lbz     r.5,0(r.4)              // get first byte
        addi    r.9,r.3,-1              // pref for store with update
        cmpwi   r.5,0                   // check if first byte was last
        beq     cpdone                  // jif so

cploop: lbzu    r.6,1(r.4)              // get next byte
        stbu    r.5,1(r.9)              // store previous byte
        or.     r.5,r.6,r.6             // mv to store reg and check if done
        bne     cploop

cpdone: stbu    r.5,1(r.9)              // store last byte

        LEAF_EXIT(strcpy)

//++
//
// PUCHAR
// strcat (
//     PUCHAR str1;
//     PUCHAR str2;
//
// Routine Description:
//
//    This function concatenates a source string (str2) to the end of
//    the desintation string (str1). 
//
// Arguments:
//
//    str1 (r.3) - A pointer to the string destination  
//
//    str2 (r.4) - A pointer to the string source  
//
//
// Return Value:
//
//    str1      Pointer to the destination string.
//
//--


        LEAF_ENTRY(strcat)

        lbz     r.5,0(r.4)              // Load 1st char str2
        lbz     r.6,0(r.3)              // Load 1st char str1
        cmpwi   cr.1,r.5,0              // check if str2 null
        cmpwi   r.6,0                   // check if str1 null
        mr      r.9,r.3                 // copy char ptr

//
// If str2 is empty, we have nothing to do, return early.
//

        beqlr   cr.1                    // return if str2 empty

//
// If str 1 empty, we're done scanning already.
//

        beq     ctcpy                   // if str1 null start cat

//
// Scan str1 until we find its null terminator.
//

ctscan: lbzu    r.6,1(r.9)              // get next byte str1
        cmpwi   r.6,0                   // test for null
        bne     ctscan                  // if not null, continue scan

//
// We found the end of str1, we know we have data in str2, all that
// remains is to strcpy str2 to the end of str1, set up for and use
// the body of strcpy (above) to do this.
//

ctcpy:  addi    r.9,r.9,-1              // prep for store with update
        b       cploop                  // finish in strcpy

        LEAF_EXIT(strcat)