aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libgcc/config/rl78/cmpsi2.S
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/libgcc/config/rl78/cmpsi2.S')
-rw-r--r--gcc-4.9/libgcc/config/rl78/cmpsi2.S121
1 files changed, 121 insertions, 0 deletions
diff --git a/gcc-4.9/libgcc/config/rl78/cmpsi2.S b/gcc-4.9/libgcc/config/rl78/cmpsi2.S
new file mode 100644
index 000000000..e87e15dea
--- /dev/null
+++ b/gcc-4.9/libgcc/config/rl78/cmpsi2.S
@@ -0,0 +1,121 @@
+; Copyright (C) 2011-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/>.
+
+
+#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.
+
+ .global ___cmpsi2
+ .type ___cmpsi2, @function
+___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
+
+ .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.
+
+ .global ___ucmpsi2
+ .type ___ucmpsi2, @function
+___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
+
+ .size ___ucmpsi2, . - ___ucmpsi2
+ \ No newline at end of file