123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- ; Copyright (C) 2011-2022 Free Software Foundation, Inc.
- ; Contributed by Red Hat.
- ;
- ; This file is free software; you can redistribute it and/or modify it
- ; under the terms of the GNU General Public License as published by the
- ; Free Software Foundation; either version 3, or (at your option) any
- ; later version.
- ;
- ; This file is distributed in the hope that it will be useful, but
- ; WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ; General Public License for more details.
- ;
- ; Under Section 7 of GPL version 3, you are granted additional
- ; permissions described in the GCC Runtime Library Exception, version
- ; 3.1, as published by the Free Software Foundation.
- ;
- ; You should have received a copy of the GNU General Public License and
- ; a copy of the GCC Runtime Library Exception along with this program;
- ; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- ; <http://www.gnu.org/licenses/>.
- #include "vregs.h"
- .text
- ;; int __cmpsi2 (signed long A, signed long B)
- ;;
- ;; Performs a signed comparison of A and B.
- ;; If A is less than B it returns 0. If A is greater
- ;; than B it returns 2. If they are equal it returns 1.
- START_FUNC ___cmpsi2
- ;; A is at [sp+4]
- ;; B is at [sp+8]
- ;; Result put in R8
- ;; Initialise default return value.
- onew bc
-
- ;; Compare the high words.
- movw ax, [sp + 10]
- movw de, ax
- movw ax, [sp + 6]
- cmpw ax, de
- skz
- br !!.Lconvert_to_signed
- .Lcompare_bottom_words:
- ;; The top words are equal - compare the bottom words.
- ;; Note - code from __ucmpsi2 branches into here.
- movw ax, [sp + 8]
- movw de, ax
- movw ax, [sp + 4]
- cmpw ax, de
- sknz
- br !!.Lless_than_or_greater_than
- ;; The words are equal - return 1.
- ;; Note - we could branch to the return code at the end of the
- ;; function but a branch instruction takes 4 bytes, and the
- ;; return sequence itself is only 4 bytes long...
- movw ax, bc
- movw r8, ax
- ret
- .Lconvert_to_signed:
- ;; The top words are different. Unfortunately the comparison
- ;; is always unsigned, so to get a signed result we XOR the CY
- ;; flag with the top bits of AX and DE.
- xor1 cy, a.7
- mov a, d
- xor1 cy, a.7
- ;; Fall through.
- .Lless_than_or_greater_than:
- ;; We now have a signed less than/greater than result in CY.
- ;; Return 0 for less than, 2 for greater than.
- ;; Note - code from __ucmpsi2 branches into here.
- incw bc
- sknc
- clrw bc
- ;; Get the result value, currently in BC, into r8
- movw ax, bc
- movw r8, ax
- ret
- END_FUNC ___cmpsi2
- ;; ------------------------------------------------------
- ;; int __ucmpsi2 (unsigned long A, unsigned long B)
- ;;
- ;; Performs an unsigned comparison of A and B.
- ;; If A is less than B it returns 0. If A is greater
- ;; than B it returns 2. If they are equal it returns 1.
- START_FUNC ___ucmpsi2
- ;; A is at [sp+4]
- ;; B is at [sp+8]
- ;; Result put in R8..R9
- ;; Initialise default return value.
- onew bc
- ;; Compare the high words.
- movw ax, [sp + 10]
- movw de, ax
- movw ax, [sp + 6]
- cmpw ax, de
- skz
- ;; Note: These branches go into the __cmpsi2 code!
- br !!.Lless_than_or_greater_than
- br !!.Lcompare_bottom_words
- END_FUNC ___ucmpsi2
- ;; ------------------------------------------------------
-
- ;; signed int __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
- ;; Result is negative if S1 is less than S2,
- ;; positive if S1 is greater, 0 if S1 and S2 are equal.
- START_FUNC __gcc_bcmp
- ;; S1 is at [sp+4]
- ;; S2 is at [sp+6]
- ;; SIZE is at [sp+8]
- ;; Result in r8/r9
-
- movw r10, #0
- 1:
- ;; Compare R10 against the SIZE parameter
- movw ax, [sp+8]
- subw ax, r10
- sknz
- br !!1f
- ;; Load S2[r10] into R8
- movw ax, [sp+6]
- addw ax, r10
- movw hl, ax
- mov a, [hl]
- mov r8, a
- ;; Load S1[r10] into A
- movw ax, [sp+4]
- addw ax, r10
- movw hl, ax
- mov a, [hl]
- ;; Increment offset
- incw r10
- ;; Compare loaded bytes
- cmp a, r8
- sknz
- br !!1b
- ;; They differ. Subtract *S2 from *S1 and return as the result.
- mov x, a
- mov a, #0
- mov r9, #0
- subw ax, r8
- 1:
- movw r8, ax
- ret
- END_FUNC __gcc_bcmp
|