URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [mcore/] [lib1.asm] - Rev 282
Compare with Previous | Blame | View Log
/* libgcc routines for the MCore.Copyright (C) 1993, 1999, 2000, 2009 Free Software Foundation, Inc.This file is part of GCC.GCC is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 3, or (at your option) anylater version.This file is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.Under Section 7 of GPL version 3, you are granted additionalpermissions described in the GCC Runtime Library Exception, version3.1, as published by the Free Software Foundation.You should have received a copy of the GNU General Public License anda 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/>. */#define CONCAT1(a, b) CONCAT2(a, b)#define CONCAT2(a, b) a ## b/* Use the right prefix for global labels. */#define SYM(x) CONCAT1 (__, x)#ifdef __ELF__#define TYPE(x) .type SYM (x),@function#define SIZE(x) .size SYM (x), . - SYM (x)#else#define TYPE(x)#define SIZE(x)#endif.macro FUNC_START name.text.globl SYM (\name)TYPE (\name)SYM (\name):.endm.macro FUNC_END nameSIZE (\name).endm#ifdef L_udivsi3FUNC_START udiv32FUNC_START udivsi32movi r1,0 // r1-r2 form 64 bit dividendmovi r4,1 // r4 is quotient (1 for a sentinel)cmpnei r3,0 // look for 0 divisorbt 9ftrap 3 // divide by 09:// control iterations; skip across high order 0 bits in dividendmov r7,r2cmpnei r7,0bt 8fmovi r2,0 // 0 dividendjmp r15 // quick return8:ff1 r7 // figure distance to skiplsl r4,r7 // move the sentinel along (with 0's behind)lsl r2,r7 // and the low 32 bits of numerator// appears to be wrong...// tested out incorrectly in our OS work...// mov r7,r3 // looking at divisor// ff1 r7 // I can move 32-r7 more bits to left.// addi r7,1 // ok, one short of that...// mov r1,r2// lsr r1,r7 // bits that came from low order...// rsubi r7,31 // r7 == "32-n" == LEFT distance// addi r7,1 // this is (32-n)// lsl r4,r7 // fixes the high 32 (quotient)// lsl r2,r7// cmpnei r4,0// bf 4f // the sentinel went away...// run the remaining bits1: lslc r2,1 // 1 bit left shift of r1-r2addc r1,r1cmphs r1,r3 // upper 32 of dividend >= divisor?bf 2fsub r1,r3 // if yes, subtract divisor2: addc r4,r4 // shift by 1 and count subtractsbf 1b // if sentinel falls out of quotient, stop4: mov r2,r4 // return quotientmov r3,r1 // and piggyback the remainderjmp r15FUNC_END udiv32FUNC_END udivsi32#endif#ifdef L_umodsi3FUNC_START urem32FUNC_START umodsi3movi r1,0 // r1-r2 form 64 bit dividendmovi r4,1 // r4 is quotient (1 for a sentinel)cmpnei r3,0 // look for 0 divisorbt 9ftrap 3 // divide by 09:// control iterations; skip across high order 0 bits in dividendmov r7,r2cmpnei r7,0bt 8fmovi r2,0 // 0 dividendjmp r15 // quick return8:ff1 r7 // figure distance to skiplsl r4,r7 // move the sentinel along (with 0's behind)lsl r2,r7 // and the low 32 bits of numerator1: lslc r2,1 // 1 bit left shift of r1-r2addc r1,r1cmphs r1,r3 // upper 32 of dividend >= divisor?bf 2fsub r1,r3 // if yes, subtract divisor2: addc r4,r4 // shift by 1 and count subtractsbf 1b // if sentinel falls out of quotient, stopmov r2,r1 // return remainderjmp r15FUNC_END urem32FUNC_END umodsi3#endif#ifdef L_divsi3FUNC_START div32FUNC_START divsi3mov r5,r2 // calc sign of quotientxor r5,r3abs r2 // do unsigned divideabs r3movi r1,0 // r1-r2 form 64 bit dividendmovi r4,1 // r4 is quotient (1 for a sentinel)cmpnei r3,0 // look for 0 divisorbt 9ftrap 3 // divide by 09:// control iterations; skip across high order 0 bits in dividendmov r7,r2cmpnei r7,0bt 8fmovi r2,0 // 0 dividendjmp r15 // quick return8:ff1 r7 // figure distance to skiplsl r4,r7 // move the sentinel along (with 0's behind)lsl r2,r7 // and the low 32 bits of numerator// tested out incorrectly in our OS work...// mov r7,r3 // looking at divisor// ff1 r7 // I can move 32-r7 more bits to left.// addi r7,1 // ok, one short of that...// mov r1,r2// lsr r1,r7 // bits that came from low order...// rsubi r7,31 // r7 == "32-n" == LEFT distance// addi r7,1 // this is (32-n)// lsl r4,r7 // fixes the high 32 (quotient)// lsl r2,r7// cmpnei r4,0// bf 4f // the sentinel went away...// run the remaining bits1: lslc r2,1 // 1 bit left shift of r1-r2addc r1,r1cmphs r1,r3 // upper 32 of dividend >= divisor?bf 2fsub r1,r3 // if yes, subtract divisor2: addc r4,r4 // shift by 1 and count subtractsbf 1b // if sentinel falls out of quotient, stop4: mov r2,r4 // return quotientmov r3,r1 // piggyback the remainderbtsti r5,31 // after adjusting for signbf 3frsubi r2,0rsubi r3,03: jmp r15FUNC_END div32FUNC_END divsi3#endif#ifdef L_modsi3FUNC_START rem32FUNC_START modsi3mov r5,r2 // calc sign of remainderabs r2 // do unsigned divideabs r3movi r1,0 // r1-r2 form 64 bit dividendmovi r4,1 // r4 is quotient (1 for a sentinel)cmpnei r3,0 // look for 0 divisorbt 9ftrap 3 // divide by 09:// control iterations; skip across high order 0 bits in dividendmov r7,r2cmpnei r7,0bt 8fmovi r2,0 // 0 dividendjmp r15 // quick return8:ff1 r7 // figure distance to skiplsl r4,r7 // move the sentinel along (with 0's behind)lsl r2,r7 // and the low 32 bits of numerator1: lslc r2,1 // 1 bit left shift of r1-r2addc r1,r1cmphs r1,r3 // upper 32 of dividend >= divisor?bf 2fsub r1,r3 // if yes, subtract divisor2: addc r4,r4 // shift by 1 and count subtractsbf 1b // if sentinel falls out of quotient, stopmov r2,r1 // return remainderbtsti r5,31 // after adjusting for signbf 3frsubi r2,03: jmp r15FUNC_END rem32FUNC_END modsi3#endif/* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2}will behave as __cmpdf2. So, we stub the implementations tojump on to __cmpdf2 and __cmpsf2.All of these shortcircuit the return path so that __cmp{sd}f2will go directly back to the caller. */.macro COMPARE_DF_JUMP name.import SYM (cmpdf2)FUNC_START \namejmpi SYM (cmpdf2)FUNC_END \name.endm#ifdef L_eqdf2COMPARE_DF_JUMP eqdf2#endif /* L_eqdf2 */#ifdef L_nedf2COMPARE_DF_JUMP nedf2#endif /* L_nedf2 */#ifdef L_gtdf2COMPARE_DF_JUMP gtdf2#endif /* L_gtdf2 */#ifdef L_gedf2COMPARE_DF_JUMP gedf2#endif /* L_gedf2 */#ifdef L_ltdf2COMPARE_DF_JUMP ltdf2#endif /* L_ltdf2 */#ifdef L_ledf2COMPARE_DF_JUMP ledf2#endif /* L_ledf2 *//* SINGLE PRECISION FLOATING POINT STUBS */.macro COMPARE_SF_JUMP name.import SYM (cmpsf2)FUNC_START \namejmpi SYM (cmpsf2)FUNC_END \name.endm#ifdef L_eqsf2COMPARE_SF_JUMP eqsf2#endif /* L_eqsf2 */#ifdef L_nesf2COMPARE_SF_JUMP nesf2#endif /* L_nesf2 */#ifdef L_gtsf2COMPARE_SF_JUMP gtsf2#endif /* L_gtsf2 */#ifdef L_gesf2COMPARE_SF_JUMP __gesf2#endif /* L_gesf2 */#ifdef L_ltsf2COMPARE_SF_JUMP __ltsf2#endif /* L_ltsf2 */#ifdef L_lesf2COMPARE_SF_JUMP lesf2#endif /* L_lesf2 */
