xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/rl78/cmpsi2.S (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1;   Copyright (C) 2011-2020 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
34START_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
90END_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
100START_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
119END_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
127START_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
1351:
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
1681:
169	movw	r8, ax
170        ret
171
172END_FUNC __gcc_bcmp
173