]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/rl78/cmpsi2.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / rl78 / cmpsi2.S
1 ; Copyright (C) 2011-2022 Free Software Foundation, Inc.
2 ; Contributed by Red Hat.
3 ;
4 ; This file is free software; you can redistribute it and/or modify it
5 ; under the terms of the GNU General Public License as published by the
6 ; Free Software Foundation; either version 3, or (at your option) any
7 ; later version.
8 ;
9 ; This file is distributed in the hope that it will be useful, but
10 ; WITHOUT ANY WARRANTY; without even the implied warranty of
11 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ; General Public License for more details.
13 ;
14 ; Under Section 7 of GPL version 3, you are granted additional
15 ; permissions described in the GCC Runtime Library Exception, version
16 ; 3.1, as published by the Free Software Foundation.
17 ;
18 ; You should have received a copy of the GNU General Public License and
19 ; a copy of the GCC Runtime Library Exception along with this program;
20 ; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
21 ; <http://www.gnu.org/licenses/>.
22
23
24 #include "vregs.h"
25
26 .text
27
28 ;; int __cmpsi2 (signed long A, signed long B)
29 ;;
30 ;; Performs a signed comparison of A and B.
31 ;; If A is less than B it returns 0. If A is greater
32 ;; than B it returns 2. If they are equal it returns 1.
33
34 START_FUNC ___cmpsi2
35
36 ;; A is at [sp+4]
37 ;; B is at [sp+8]
38 ;; Result put in R8
39
40 ;; Initialise default return value.
41 onew bc
42
43 ;; Compare the high words.
44 movw ax, [sp + 10]
45 movw de, ax
46 movw ax, [sp + 6]
47 cmpw ax, de
48 skz
49 br !!.Lconvert_to_signed
50
51 .Lcompare_bottom_words:
52 ;; The top words are equal - compare the bottom words.
53 ;; Note - code from __ucmpsi2 branches into here.
54 movw ax, [sp + 8]
55 movw de, ax
56 movw ax, [sp + 4]
57 cmpw ax, de
58 sknz
59 br !!.Lless_than_or_greater_than
60 ;; The words are equal - return 1.
61 ;; Note - we could branch to the return code at the end of the
62 ;; function but a branch instruction takes 4 bytes, and the
63 ;; return sequence itself is only 4 bytes long...
64 movw ax, bc
65 movw r8, ax
66 ret
67
68 .Lconvert_to_signed:
69 ;; The top words are different. Unfortunately the comparison
70 ;; is always unsigned, so to get a signed result we XOR the CY
71 ;; flag with the top bits of AX and DE.
72 xor1 cy, a.7
73 mov a, d
74 xor1 cy, a.7
75 ;; Fall through.
76
77 .Lless_than_or_greater_than:
78 ;; We now have a signed less than/greater than result in CY.
79 ;; Return 0 for less than, 2 for greater than.
80 ;; Note - code from __ucmpsi2 branches into here.
81 incw bc
82 sknc
83 clrw bc
84
85 ;; Get the result value, currently in BC, into r8
86 movw ax, bc
87 movw r8, ax
88 ret
89
90 END_FUNC ___cmpsi2
91
92 ;; ------------------------------------------------------
93
94 ;; int __ucmpsi2 (unsigned long A, unsigned long B)
95 ;;
96 ;; Performs an unsigned comparison of A and B.
97 ;; If A is less than B it returns 0. If A is greater
98 ;; than B it returns 2. If they are equal it returns 1.
99
100 START_FUNC ___ucmpsi2
101
102 ;; A is at [sp+4]
103 ;; B is at [sp+8]
104 ;; Result put in R8..R9
105
106 ;; Initialise default return value.
107 onew bc
108
109 ;; Compare the high words.
110 movw ax, [sp + 10]
111 movw de, ax
112 movw ax, [sp + 6]
113 cmpw ax, de
114 skz
115 ;; Note: These branches go into the __cmpsi2 code!
116 br !!.Lless_than_or_greater_than
117 br !!.Lcompare_bottom_words
118
119 END_FUNC ___ucmpsi2
120
121 ;; ------------------------------------------------------
122
123 ;; signed int __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
124 ;; Result is negative if S1 is less than S2,
125 ;; positive if S1 is greater, 0 if S1 and S2 are equal.
126
127 START_FUNC __gcc_bcmp
128
129 ;; S1 is at [sp+4]
130 ;; S2 is at [sp+6]
131 ;; SIZE is at [sp+8]
132 ;; Result in r8/r9
133
134 movw r10, #0
135 1:
136 ;; Compare R10 against the SIZE parameter
137 movw ax, [sp+8]
138 subw ax, r10
139 sknz
140 br !!1f
141
142 ;; Load S2[r10] into R8
143 movw ax, [sp+6]
144 addw ax, r10
145 movw hl, ax
146 mov a, [hl]
147 mov r8, a
148
149 ;; Load S1[r10] into A
150 movw ax, [sp+4]
151 addw ax, r10
152 movw hl, ax
153 mov a, [hl]
154
155 ;; Increment offset
156 incw r10
157
158 ;; Compare loaded bytes
159 cmp a, r8
160 sknz
161 br !!1b
162
163 ;; They differ. Subtract *S2 from *S1 and return as the result.
164 mov x, a
165 mov a, #0
166 mov r9, #0
167 subw ax, r8
168 1:
169 movw r8, ax
170 ret
171
172 END_FUNC __gcc_bcmp