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