diff options
Diffstat (limited to 'gcc-4.9/libgcc/config/msp430/cmpsi2.S')
-rw-r--r-- | gcc-4.9/libgcc/config/msp430/cmpsi2.S | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/gcc-4.9/libgcc/config/msp430/cmpsi2.S b/gcc-4.9/libgcc/config/msp430/cmpsi2.S new file mode 100644 index 000000000..7f85c0b9b --- /dev/null +++ b/gcc-4.9/libgcc/config/msp430/cmpsi2.S @@ -0,0 +1,98 @@ +; Copyright (C) 2012-2014 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/>. + +#ifdef __MSP430X_LARGE__ +#define ret_ RETA +#else +#define ret_ RET +#endif + + .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. + + ;; Note - this code is also used by the __ucmpsi2 routine below. + + .global __cmpsi2 + .type __cmpsi2, @function +__cmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + cmp.w r13, r15 + jeq .L_compare_low + jge .L_less_than +.L_greater_than: + mov.w #2, r12 + ret_ +.L_less_than: + mov.w #0, r12 + ret_ + +.L_compare_low: + cmp.w r12, r14 + jl .L_greater_than + jne .L_less_than + mov.w #1, r12 + ret_ + + .size __cmpsi2, . - __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. + +;;; Note - this function branches into the __cmpsi2 code above. + + .global __ucmpsi2 + .type __ucmpsi2, @function +__ucmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + tst r13 + jn .L_top_bit_set_in_A + tst r15 +;;; If the top bit of B is set, but A's is clear we know that A < B. + jn .L_less_than +;;; Neither A nor B has their top bit set so we can use the __cmpsi2 routine. +;;; Note we use Jc rather than BR as that saves two bytes. The TST insn always +;;; sets the C bit. + jc __cmpsi2 + +.L_top_bit_set_in_A: + tst r15 +;;; If both A and B have their top bit set we can use the __cmpsi2 routine. + jn __cmpsi2 +;;; Otherwise A has its top bit set and B does not so A > B. + jc .L_greater_than + + .size __ucmpsi2, . - __ucmpsi2 |