diff options
author | YamaArashi <shadow962@live.com> | 2016-01-06 01:47:28 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-01-06 01:47:28 -0800 |
commit | be8b04496302184c6e8f04d6179f9c3afc50aeb6 (patch) | |
tree | 726e2468c0c07add773c0dbd86ab6386844259ae /gcc/config/d30v/libgcc1.asm |
initial commit
Diffstat (limited to 'gcc/config/d30v/libgcc1.asm')
-rwxr-xr-x | gcc/config/d30v/libgcc1.asm | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/gcc/config/d30v/libgcc1.asm b/gcc/config/d30v/libgcc1.asm new file mode 100755 index 0000000..dd18248 --- /dev/null +++ b/gcc/config/d30v/libgcc1.asm @@ -0,0 +1,193 @@ +/* CYGNUS LOCAL -- meissner/d30v */ +/* Assembly support functions for libgcc1. + * + * Copyright (C) 1997 Free Software Foundation, Inc. + * Contributed by Cygnus Support + * + * 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 2, or (at your option) any + * later version. + * + * In addition to the permissions in the GNU General Public License, the + * Free Software Foundation gives you unlimited permission to link the + * compiled version of this file with other programs, and to distribute + * those programs without any restriction coming from the use of this + * file. (The General Public License restrictions do apply in other + * respects; for example, they cover modification of the file, and + * distribution when not linked into another program.) + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * As a special exception, if you link this library with files + * compiled with GCC to produce an executable, this does not cause + * the resulting executable to be covered by the GNU General Public License. + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + */ + + +#ifdef L_udivsi3 + +/* For division, we use the following algorithm: + * + * unsigned + * __divsi3 (unsigned a, unsigned b) + * { + * unsigned al = a; + * unsigned ah = 0; + * unsigned tmpf; + * int i; + * + * for (i = 32; i > 0; i--) + * { + * ah = (ah << 1) | (al >> 31); + * tmpf = (ah >= b) ? 1 : 0; + * ah -= ((tmpf) ? b : 0); + * al = (al << 1) | tmpf; + * } + * + * return al; // for __udivsi3 + * return ah; // for __umodsi3 + * } + */ + + .file "_udivsi3" + .text + .globl __umodsi3 + .globl __udivsi3 + .type __umodsi3,@function + .type __udivsi3,@function + .stabs "libgcc1.asm",100,0,0,__umodsi3 + .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0 + .stabs "__umodsi3:F(0,1)",36,0,1,__umodsi3 + .stabs "a:P(0,1)",64,0,1,2 + .stabs "b:P(0,1)",64,0,1,3 + +__umodsi3: + bra.s .Lmerge || orfg f1,f1,1 ; indicate this is __umodsi3 +.Lumod: + .size __umodsi3,.Lumod-__umodsi3 + .stabs "",36,0,0,.Lumod-__umodsi3 + + .stabs "__udivsi3:F(0,1)",36,0,1,__udivsi3 + .stabs "a:P(0,1)",64,0,1,2 + .stabs "b:P(0,1)",64,0,1,3 +__udivsi3: + andfg f1,f1,0 || nop ; indicate this is __udivsi3 + +.Lmerge: + ; r2 = al + ; r3 = b + ; r4 = ah + ; r5 = loop counter + ; f0 = tmpf + ; f1 = 1 if this is mod, 0 if this is div + or r4,r0,0 || sub r5,r0,-32 ; ah = 0, loop = 32 + +.Lloop: + src r4,r2,-1 || sub r5,r5,1 ; ah = (ah << 1) | (al >> 31); decrement loop count + cmpuge f0,r4,r3 || sra r2,r2,-1 ; f0 = (ah >= b); al <<= 1 + sub/tx r4,r4,r3 || or/tx r2,r2,1 ; ah -= (tmpf) ? b : 0; al |= tmpf + bratnz.s r5,.Lloop || nop ; loop back if not done + jmp link || or/xt r2,r0,r4 ; if mod, update register, then return to user +.Ludiv: + .size __udivsi3,.Ludiv-__udivsi3 + .stabs "",36,0,0,.Ludiv-__udivsi3 + +#endif /* L_udivsi3 */ + + +#ifdef L_divsi3 + +/* For division, we use the following algorithm: + * + * unsigned + * __divsi3 (unsigned a, unsigned b) + * { + * unsigned al = __builtin_abs (a); + * unsigned b2 = __builtin_abs (b); + * unsigned ah = 0; + * unsigned tmpf; + * int i; + * + * for (i = 32; i > 0; i--) + * { + * ah = (ah << 1) | (al >> 31); + * tmpf = (ah >= b2) ? 1 : 0; + * ah -= ((tmpf) ? b2 : 0); + * al = (al << 1) | tmpf; + * } + * + * if (a < 0) + * ah = -ah, al = -al; + * + * if (b < 0) + * al = -al; + * + * return al; // for __divsi3 + * return ah; // for __modsi3 + * } + */ + + .file "_divsi3" + .text + .globl __modsi3 + .globl __divsi3 + .type __modsi3,@function + .type __divsi3,@function + .stabs "libgcc1.asm",100,0,0,__modsi3 + .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0 + .stabs "__modsi3:F(0,1)",36,0,1,__modsi3 + .stabs "a:P(0,1)",64,0,1,2 + .stabs "b:P(0,1)",64,0,1,3 + +__modsi3: + bra.s .Lmerge || orfg f1,f1,1 ; indicate this is __modsi3 +.Lmod: + .size __modsi3,.Lmod-__modsi3 + .stabs "",36,0,0,.Lmod-__modsi3 + + .stabs "__divsi3:F(0,1)",36,0,1,__divsi3 + .stabs "a:P(0,1)",64,0,1,2 + .stabs "b:P(0,1)",64,0,1,3 +__divsi3: + andfg f1,f1,0 || nop ; indicate this is __divsi3 + +.Lmerge: + ; r2 = al + ; r3 = b2 + ; r4 = ah + ; r5 = loop counter + ; r6 = a + ; r7 = b + ; f0 = tmpf + ; f1 = 1 if this is mod, 0 if this is div + or r6,r0,r2 || or r7,r0,r3 ; copy original inputs + abs r2,r2 || abs r3,r3 ; make both postive + or r4,r0,0 || sub r5,r0,-32 ; ah = 0, loop = 32 + +.Lloop: + src r4,r2,-1 || sub r5,r5,1 ; ah = (ah << 1) | (al >> 31); decrement loop count + cmpuge f0,r4,r3 || sra r2,r2,-1 ; f0 = (ah >= b); al <<= 1 + sub/tx r4,r4,r3 || or/tx r2,r2,1 ; ah -= (tmpf) ? b : 0; al |= tmpf + bratnz.s r5,.Lloop || nop ; loop back if not done + cmplt f0,r6,0 || nop ; f0 = (a < 0) + + sub/tx r2,r0,r2 || sub/tx r4,r0,r4 ; negate both al, ah if (a < 0) + cmplt f0,r7,0 -> sub/tx r2,r0,r2 ; negate al if (b < 0) + jmp link || or/xt r2,r0,r4 ; update result if mod; return to user +.Ldiv: + .size __divsi3,.Ldiv-__divsi3 + .stabs "",36,0,0,.Ldiv-__divsi3 + +#endif /* L_divsi3 */ +/* END CYGNUS LOCAL -- meissner/d30v */ |