Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / z80 / asm_strings.s
1         ;; Implementation of some string functions in
2         ;; assembler.
3
4         ;; Why - because I want a better dhrystone score :)
5
6         ;; strcpy is disabled as the C version is almost as good.
7         ;; Just the setup and return is slower.
8         .if 0
9 ; char *strcpy(char *dest, const char *source)
10 _strcpy::
11         ;; Fall through to the correct type
12 __strcpy_rrf_s::
13         ld      a,#5
14         rst     0x08
15 __strcpy_rrx_s::
16         ld      hl,#2
17         add     hl,sp
18         ld      e,(hl)
19         inc     hl
20         ld      d,(hl)
21         inc     hl
22         ld      c,(hl)
23         inc     hl
24         ld      b,(hl)
25         ;; Setup the return value
26         ld      l,c
27         ld      h,b
28 1$:
29         ld      a,(bc)
30         ld      (de),a
31         or      a
32         jp      NZ,1$
33
34         ret
35         ;; Notes on strcpy styles:
36         ;;   *de = *hl; hl++; de++; or a; ret z; jp - slower as jp is
37         ;; same cost as conditional jump, so condition on ret is more expensive.
38         ;;   *de = *bc; bc++; de++; or a, jp nz - OK
39         ;; Can't use LDI as need to check for end of string.
40         ;; Above also matches the z88dk version.
41         .endif
42
43 ; void *memcpy(void *dest, const void *source, int count)
44 _memcpy::
45         ;; Fall through to correct type
46 __memcpy_rrf_s::
47         ld      a,#5
48         rst     0x08
49 __memcpy_rrx_s::
50         ;; Using LDIR
51         ;; LDIR:        do; *DE = *HL; HL++; BC--; while BC != 0
52
53         ;; All registers are already saved.
54         pop     iy      ; iy = return address
55         pop     de      ; de = destination pointer
56         pop     hl      ; hl = source pointer
57         pop     bc      ; bc = count
58         push    bc
59         push    hl
60         push    de
61         ld      a,b
62         or      c
63         jr      Z,1$
64         ldir
65 1$:
66         pop     hl      ; return hl = original destination pointer
67         push    hl
68         jp      (iy)
69         ret
70
71 ; int strcmp(const char *s1, const char *s2)
72 _strcmp::
73         ;; Fall through to the correct style
74         ;; Fall through to correct type
75 __strcmp_rrf_s::
76         ld      a,#5
77         rst     0x08
78 __strcmp_rrx_s::
79         ld      hl,#2
80         add     hl,sp
81
82         ld      e,(hl)
83         inc     hl
84         ld      d,(hl)
85         inc     hl
86         ld      a,(hl)
87         inc     hl
88         ld      h,(hl)
89         ld      l,a
90
91 1$:
92         ld      a,(de)
93         sub     (hl)
94
95         ;; Normally not taken, so use a jr (12/7) instead of jp (10)
96         jr      NZ,2$
97
98         ;; A == 0
99         cp      (hl)
100
101         inc     de
102         inc     hl
103         ;; Normally taken.  Flag from the cp above.
104         jp      nz,1$
105 2$:
106         ;; Sign extend
107         ld      l,a
108         rla
109         sbc     a
110         ld      h,a
111         ret
112