diff options
Diffstat (limited to 'libgcc/config/mips/vr4120-div.S')
-rw-r--r-- | libgcc/config/mips/vr4120-div.S | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S new file mode 100644 index 0000000000..7639c06230 --- /dev/null +++ b/libgcc/config/mips/vr4120-div.S @@ -0,0 +1,79 @@ +/* Support file for -mfix-vr4120. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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. + +GCC 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/>. */ + +/* This file contains functions which implement divsi3 and modsi3 for + -mfix-vr4120. div and ddiv do not give the correct result when one + of the operands is negative. */ + + .set nomips16 + +#define DIV \ + xor $3,$4,$5 /* t = x ^ y */ ; \ + li $2,0x80000000; \ + .set noreorder; \ + bgez $4,1f /* x >= 0 */; \ + and $3,$3,$2 /* t = (x ^ y) & 0x80000000 in delay slot */ ;\ + .set reorder; \ + subu $4,$0,$4 /* x = -x */ ; \ +1:; \ + .set noreorder; \ + bgez $5,2f /* y >= 0 */ ; \ + nop; \ + subu $5,$0,$5 /* y = -y */ ; \ + .set reorder; \ +2:; \ + divu $0,$4,$5; /* we use divu because of INT_MIN */ \ + .set noreorder; \ + bne $5,$0,3f; \ + nop; \ + break 7 /* division on zero y */ ; \ +3:; \ + .set reorder; \ + mflo $2 /* r = x / y */ ; \ + .set noreorder; \ + beq $3,$0,4f /* t == 0 */ ; \ + nop; \ + subu $2,$0,$2 /* r = -r */ ; \ + .set reorder; \ +4: + + .globl __vr4120_divsi3 + .ent __vr4120_divsi3 +__vr4120_divsi3: + DIV + j $31 + .end __vr4120_divsi3 + + .globl __vr4120_modsi3 + .ent __vr4120_modsi3 +__vr4120_modsi3: + move $6,$4 # x1 = x + move $7,$5 # y1 = y + DIV + mult $2,$7 # r = r * y1 + mflo $2 + .set noreorder + j $31 + subu $2,$6,$2 # r = x1 - r in delay slot + .end __vr4120_modsi3 |