Optimised mul, added asm string functions
[fw/sdcc] / 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         ld      hl,#2
55         add     hl,sp
56         ld      e,(hl)
57         inc     hl
58         ld      d,(hl)
59         inc     hl
60         ld      a,(hl)
61         inc     hl
62         ld      b,(hl)
63         inc     hl
64         ld      c,(hl)
65         inc     hl
66         ld      h,(hl)
67         ld      l,a
68         ld      a,h
69         ld      h,b
70         ld      b,a
71
72         ;; Pending: could optimise this check to occur earlier.
73         or      c
74         ret     z
75
76         ldir
77         ret
78
79 ; int strcmp(const char *s1, const char *s2) 
80 _strcmp::
81         ;; Fall through to the correct style
82         ;; Fall through to correct type
83 __strcmp_rrf_s::                
84         ld      a,#5
85         rst     0x08
86 __strcmp_rrx_s::       
87         ld      hl,#2
88         add     hl,sp
89         
90         ld      e,(hl)
91         inc     hl
92         ld      d,(hl)
93         inc     hl
94         ld      a,(hl)
95         inc     hl
96         ld      h,(hl)
97         ld      l,a
98         
99 1$:     
100         ld      a,(de)
101         sub     (hl)
102
103         ;; Normally not taken, so use a jr (12/7) instead of jp (10)
104         jr      nz,2$
105
106         ;; A == 0
107         cp      (hl)
108
109         inc     de
110         inc     hl
111         ;; Normally taken.  Flag from the cp above.
112         jp      nz,1$
113 2$:     
114         ;; Sign extend
115         ld      l,a
116         rla
117         sbc     a
118         ld      h,a
119         ret
120