1*c87b03e5Sespie/* libgcc routines for the MCore. 2*c87b03e5Sespie Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc. 3*c87b03e5Sespie 4*c87b03e5SespieThis file is part of GNU CC. 5*c87b03e5Sespie 6*c87b03e5SespieGNU CC is free software; you can redistribute it and/or modify it 7*c87b03e5Sespieunder the terms of the GNU General Public License as published by the 8*c87b03e5SespieFree Software Foundation; either version 2, or (at your option) any 9*c87b03e5Sespielater version. 10*c87b03e5Sespie 11*c87b03e5SespieIn addition to the permissions in the GNU General Public License, the 12*c87b03e5SespieFree Software Foundation gives you unlimited permission to link the 13*c87b03e5Sespiecompiled version of this file into combinations with other programs, 14*c87b03e5Sespieand to distribute those combinations without any restriction coming 15*c87b03e5Sespiefrom the use of this file. (The General Public License restrictions 16*c87b03e5Sespiedo apply in other respects; for example, they cover modification of 17*c87b03e5Sespiethe file, and distribution when not linked into a combine 18*c87b03e5Sespieexecutable.) 19*c87b03e5Sespie 20*c87b03e5SespieThis file is distributed in the hope that it will be useful, but 21*c87b03e5SespieWITHOUT ANY WARRANTY; without even the implied warranty of 22*c87b03e5SespieMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23*c87b03e5SespieGeneral Public License for more details. 24*c87b03e5Sespie 25*c87b03e5SespieYou should have received a copy of the GNU General Public License 26*c87b03e5Sespiealong with this program; see the file COPYING. If not, write to 27*c87b03e5Sespiethe Free Software Foundation, 59 Temple Place - Suite 330, 28*c87b03e5SespieBoston, MA 02111-1307, USA. */ 29*c87b03e5Sespie 30*c87b03e5Sespie#define CONCAT1(a, b) CONCAT2(a, b) 31*c87b03e5Sespie#define CONCAT2(a, b) a ## b 32*c87b03e5Sespie 33*c87b03e5Sespie/* Use the right prefix for global labels. */ 34*c87b03e5Sespie 35*c87b03e5Sespie#define SYM(x) CONCAT1 (__, x) 36*c87b03e5Sespie 37*c87b03e5Sespie#ifdef __ELF__ 38*c87b03e5Sespie#define TYPE(x) .type SYM (x),@function 39*c87b03e5Sespie#define SIZE(x) .size SYM (x), . - SYM (x) 40*c87b03e5Sespie#else 41*c87b03e5Sespie#define TYPE(x) 42*c87b03e5Sespie#define SIZE(x) 43*c87b03e5Sespie#endif 44*c87b03e5Sespie 45*c87b03e5Sespie.macro FUNC_START name 46*c87b03e5Sespie .text 47*c87b03e5Sespie .globl SYM (\name) 48*c87b03e5Sespie TYPE (\name) 49*c87b03e5SespieSYM (\name): 50*c87b03e5Sespie.endm 51*c87b03e5Sespie 52*c87b03e5Sespie.macro FUNC_END name 53*c87b03e5Sespie SIZE (\name) 54*c87b03e5Sespie.endm 55*c87b03e5Sespie 56*c87b03e5Sespie#ifdef L_udivsi3 57*c87b03e5SespieFUNC_START udiv32 58*c87b03e5SespieFUNC_START udivsi32 59*c87b03e5Sespie 60*c87b03e5Sespie movi r1,0 // r1-r2 form 64 bit dividend 61*c87b03e5Sespie movi r4,1 // r4 is quotient (1 for a sentinel) 62*c87b03e5Sespie 63*c87b03e5Sespie cmpnei r3,0 // look for 0 divisor 64*c87b03e5Sespie bt 9f 65*c87b03e5Sespie trap 3 // divide by 0 66*c87b03e5Sespie9: 67*c87b03e5Sespie // control iterations; skip across high order 0 bits in dividend 68*c87b03e5Sespie mov r7,r2 69*c87b03e5Sespie cmpnei r7,0 70*c87b03e5Sespie bt 8f 71*c87b03e5Sespie movi r2,0 // 0 dividend 72*c87b03e5Sespie jmp r15 // quick return 73*c87b03e5Sespie8: 74*c87b03e5Sespie ff1 r7 // figure distance to skip 75*c87b03e5Sespie lsl r4,r7 // move the sentinel along (with 0's behind) 76*c87b03e5Sespie lsl r2,r7 // and the low 32 bits of numerator 77*c87b03e5Sespie 78*c87b03e5Sespie// appears to be wrong... 79*c87b03e5Sespie// tested out incorrectly in our OS work... 80*c87b03e5Sespie// mov r7,r3 // looking at divisor 81*c87b03e5Sespie// ff1 r7 // I can move 32-r7 more bits to left. 82*c87b03e5Sespie// addi r7,1 // ok, one short of that... 83*c87b03e5Sespie// mov r1,r2 84*c87b03e5Sespie// lsr r1,r7 // bits that came from low order... 85*c87b03e5Sespie// rsubi r7,31 // r7 == "32-n" == LEFT distance 86*c87b03e5Sespie// addi r7,1 // this is (32-n) 87*c87b03e5Sespie// lsl r4,r7 // fixes the high 32 (quotient) 88*c87b03e5Sespie// lsl r2,r7 89*c87b03e5Sespie// cmpnei r4,0 90*c87b03e5Sespie// bf 4f // the sentinel went away... 91*c87b03e5Sespie 92*c87b03e5Sespie // run the remaining bits 93*c87b03e5Sespie 94*c87b03e5Sespie1: lslc r2,1 // 1 bit left shift of r1-r2 95*c87b03e5Sespie addc r1,r1 96*c87b03e5Sespie cmphs r1,r3 // upper 32 of dividend >= divisor? 97*c87b03e5Sespie bf 2f 98*c87b03e5Sespie sub r1,r3 // if yes, subtract divisor 99*c87b03e5Sespie2: addc r4,r4 // shift by 1 and count subtracts 100*c87b03e5Sespie bf 1b // if sentinel falls out of quotient, stop 101*c87b03e5Sespie 102*c87b03e5Sespie4: mov r2,r4 // return quotient 103*c87b03e5Sespie mov r3,r1 // and piggyback the remainder 104*c87b03e5Sespie jmp r15 105*c87b03e5SespieFUNC_END udiv32 106*c87b03e5SespieFUNC_END udivsi32 107*c87b03e5Sespie#endif 108*c87b03e5Sespie 109*c87b03e5Sespie#ifdef L_umodsi3 110*c87b03e5SespieFUNC_START urem32 111*c87b03e5SespieFUNC_START umodsi3 112*c87b03e5Sespie movi r1,0 // r1-r2 form 64 bit dividend 113*c87b03e5Sespie movi r4,1 // r4 is quotient (1 for a sentinel) 114*c87b03e5Sespie cmpnei r3,0 // look for 0 divisor 115*c87b03e5Sespie bt 9f 116*c87b03e5Sespie trap 3 // divide by 0 117*c87b03e5Sespie9: 118*c87b03e5Sespie // control iterations; skip across high order 0 bits in dividend 119*c87b03e5Sespie mov r7,r2 120*c87b03e5Sespie cmpnei r7,0 121*c87b03e5Sespie bt 8f 122*c87b03e5Sespie movi r2,0 // 0 dividend 123*c87b03e5Sespie jmp r15 // quick return 124*c87b03e5Sespie8: 125*c87b03e5Sespie ff1 r7 // figure distance to skip 126*c87b03e5Sespie lsl r4,r7 // move the sentinel along (with 0's behind) 127*c87b03e5Sespie lsl r2,r7 // and the low 32 bits of numerator 128*c87b03e5Sespie 129*c87b03e5Sespie1: lslc r2,1 // 1 bit left shift of r1-r2 130*c87b03e5Sespie addc r1,r1 131*c87b03e5Sespie cmphs r1,r3 // upper 32 of dividend >= divisor? 132*c87b03e5Sespie bf 2f 133*c87b03e5Sespie sub r1,r3 // if yes, subtract divisor 134*c87b03e5Sespie2: addc r4,r4 // shift by 1 and count subtracts 135*c87b03e5Sespie bf 1b // if sentinel falls out of quotient, stop 136*c87b03e5Sespie mov r2,r1 // return remainder 137*c87b03e5Sespie jmp r15 138*c87b03e5SespieFUNC_END urem32 139*c87b03e5SespieFUNC_END umodsi3 140*c87b03e5Sespie#endif 141*c87b03e5Sespie 142*c87b03e5Sespie#ifdef L_divsi3 143*c87b03e5SespieFUNC_START div32 144*c87b03e5SespieFUNC_START divsi3 145*c87b03e5Sespie mov r5,r2 // calc sign of quotient 146*c87b03e5Sespie xor r5,r3 147*c87b03e5Sespie abs r2 // do unsigned divide 148*c87b03e5Sespie abs r3 149*c87b03e5Sespie movi r1,0 // r1-r2 form 64 bit dividend 150*c87b03e5Sespie movi r4,1 // r4 is quotient (1 for a sentinel) 151*c87b03e5Sespie cmpnei r3,0 // look for 0 divisor 152*c87b03e5Sespie bt 9f 153*c87b03e5Sespie trap 3 // divide by 0 154*c87b03e5Sespie9: 155*c87b03e5Sespie // control iterations; skip across high order 0 bits in dividend 156*c87b03e5Sespie mov r7,r2 157*c87b03e5Sespie cmpnei r7,0 158*c87b03e5Sespie bt 8f 159*c87b03e5Sespie movi r2,0 // 0 dividend 160*c87b03e5Sespie jmp r15 // quick return 161*c87b03e5Sespie8: 162*c87b03e5Sespie ff1 r7 // figure distance to skip 163*c87b03e5Sespie lsl r4,r7 // move the sentinel along (with 0's behind) 164*c87b03e5Sespie lsl r2,r7 // and the low 32 bits of numerator 165*c87b03e5Sespie 166*c87b03e5Sespie// tested out incorrectly in our OS work... 167*c87b03e5Sespie// mov r7,r3 // looking at divisor 168*c87b03e5Sespie// ff1 r7 // I can move 32-r7 more bits to left. 169*c87b03e5Sespie// addi r7,1 // ok, one short of that... 170*c87b03e5Sespie// mov r1,r2 171*c87b03e5Sespie// lsr r1,r7 // bits that came from low order... 172*c87b03e5Sespie// rsubi r7,31 // r7 == "32-n" == LEFT distance 173*c87b03e5Sespie// addi r7,1 // this is (32-n) 174*c87b03e5Sespie// lsl r4,r7 // fixes the high 32 (quotient) 175*c87b03e5Sespie// lsl r2,r7 176*c87b03e5Sespie// cmpnei r4,0 177*c87b03e5Sespie// bf 4f // the sentinel went away... 178*c87b03e5Sespie 179*c87b03e5Sespie // run the remaining bits 180*c87b03e5Sespie1: lslc r2,1 // 1 bit left shift of r1-r2 181*c87b03e5Sespie addc r1,r1 182*c87b03e5Sespie cmphs r1,r3 // upper 32 of dividend >= divisor? 183*c87b03e5Sespie bf 2f 184*c87b03e5Sespie sub r1,r3 // if yes, subtract divisor 185*c87b03e5Sespie2: addc r4,r4 // shift by 1 and count subtracts 186*c87b03e5Sespie bf 1b // if sentinel falls out of quotient, stop 187*c87b03e5Sespie 188*c87b03e5Sespie4: mov r2,r4 // return quotient 189*c87b03e5Sespie mov r3,r1 // piggyback the remainder 190*c87b03e5Sespie btsti r5,31 // after adjusting for sign 191*c87b03e5Sespie bf 3f 192*c87b03e5Sespie rsubi r2,0 193*c87b03e5Sespie rsubi r3,0 194*c87b03e5Sespie3: jmp r15 195*c87b03e5SespieFUNC_END div32 196*c87b03e5SespieFUNC_END divsi3 197*c87b03e5Sespie#endif 198*c87b03e5Sespie 199*c87b03e5Sespie#ifdef L_modsi3 200*c87b03e5SespieFUNC_START rem32 201*c87b03e5SespieFUNC_START modsi3 202*c87b03e5Sespie mov r5,r2 // calc sign of remainder 203*c87b03e5Sespie abs r2 // do unsigned divide 204*c87b03e5Sespie abs r3 205*c87b03e5Sespie movi r1,0 // r1-r2 form 64 bit dividend 206*c87b03e5Sespie movi r4,1 // r4 is quotient (1 for a sentinel) 207*c87b03e5Sespie cmpnei r3,0 // look for 0 divisor 208*c87b03e5Sespie bt 9f 209*c87b03e5Sespie trap 3 // divide by 0 210*c87b03e5Sespie9: 211*c87b03e5Sespie // control iterations; skip across high order 0 bits in dividend 212*c87b03e5Sespie mov r7,r2 213*c87b03e5Sespie cmpnei r7,0 214*c87b03e5Sespie bt 8f 215*c87b03e5Sespie movi r2,0 // 0 dividend 216*c87b03e5Sespie jmp r15 // quick return 217*c87b03e5Sespie8: 218*c87b03e5Sespie ff1 r7 // figure distance to skip 219*c87b03e5Sespie lsl r4,r7 // move the sentinel along (with 0's behind) 220*c87b03e5Sespie lsl r2,r7 // and the low 32 bits of numerator 221*c87b03e5Sespie 222*c87b03e5Sespie1: lslc r2,1 // 1 bit left shift of r1-r2 223*c87b03e5Sespie addc r1,r1 224*c87b03e5Sespie cmphs r1,r3 // upper 32 of dividend >= divisor? 225*c87b03e5Sespie bf 2f 226*c87b03e5Sespie sub r1,r3 // if yes, subtract divisor 227*c87b03e5Sespie2: addc r4,r4 // shift by 1 and count subtracts 228*c87b03e5Sespie bf 1b // if sentinel falls out of quotient, stop 229*c87b03e5Sespie mov r2,r1 // return remainder 230*c87b03e5Sespie btsti r5,31 // after adjusting for sign 231*c87b03e5Sespie bf 3f 232*c87b03e5Sespie rsubi r2,0 233*c87b03e5Sespie3: jmp r15 234*c87b03e5SespieFUNC_END rem32 235*c87b03e5SespieFUNC_END modsi3 236*c87b03e5Sespie#endif 237*c87b03e5Sespie 238*c87b03e5Sespie 239*c87b03e5Sespie/* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2} 240*c87b03e5Sespie will behave as __cmpdf2. So, we stub the implementations to 241*c87b03e5Sespie jump on to __cmpdf2 and __cmpsf2. 242*c87b03e5Sespie 243*c87b03e5Sespie All of these shortcircuit the return path so that __cmp{sd}f2 244*c87b03e5Sespie will go directly back to the caller. */ 245*c87b03e5Sespie 246*c87b03e5Sespie.macro COMPARE_DF_JUMP name 247*c87b03e5Sespie .import SYM (cmpdf2) 248*c87b03e5SespieFUNC_START \name 249*c87b03e5Sespie jmpi SYM (cmpdf2) 250*c87b03e5SespieFUNC_END \name 251*c87b03e5Sespie.endm 252*c87b03e5Sespie 253*c87b03e5Sespie#ifdef L_eqdf2 254*c87b03e5SespieCOMPARE_DF_JUMP eqdf2 255*c87b03e5Sespie#endif /* L_eqdf2 */ 256*c87b03e5Sespie 257*c87b03e5Sespie#ifdef L_nedf2 258*c87b03e5SespieCOMPARE_DF_JUMP nedf2 259*c87b03e5Sespie#endif /* L_nedf2 */ 260*c87b03e5Sespie 261*c87b03e5Sespie#ifdef L_gtdf2 262*c87b03e5SespieCOMPARE_DF_JUMP gtdf2 263*c87b03e5Sespie#endif /* L_gtdf2 */ 264*c87b03e5Sespie 265*c87b03e5Sespie#ifdef L_gedf2 266*c87b03e5SespieCOMPARE_DF_JUMP gedf2 267*c87b03e5Sespie#endif /* L_gedf2 */ 268*c87b03e5Sespie 269*c87b03e5Sespie#ifdef L_ltdf2 270*c87b03e5SespieCOMPARE_DF_JUMP ltdf2 271*c87b03e5Sespie#endif /* L_ltdf2 */ 272*c87b03e5Sespie 273*c87b03e5Sespie#ifdef L_ledf2 274*c87b03e5SespieCOMPARE_DF_JUMP ledf2 275*c87b03e5Sespie#endif /* L_ledf2 */ 276*c87b03e5Sespie 277*c87b03e5Sespie/* SINGLE PRECISION FLOATING POINT STUBS */ 278*c87b03e5Sespie 279*c87b03e5Sespie.macro COMPARE_SF_JUMP name 280*c87b03e5Sespie .import SYM (cmpsf2) 281*c87b03e5SespieFUNC_START \name 282*c87b03e5Sespie jmpi SYM (cmpsf2) 283*c87b03e5SespieFUNC_END \name 284*c87b03e5Sespie.endm 285*c87b03e5Sespie 286*c87b03e5Sespie#ifdef L_eqsf2 287*c87b03e5SespieCOMPARE_SF_JUMP eqsf2 288*c87b03e5Sespie#endif /* L_eqsf2 */ 289*c87b03e5Sespie 290*c87b03e5Sespie#ifdef L_nesf2 291*c87b03e5SespieCOMPARE_SF_JUMP nesf2 292*c87b03e5Sespie#endif /* L_nesf2 */ 293*c87b03e5Sespie 294*c87b03e5Sespie#ifdef L_gtsf2 295*c87b03e5SespieCOMPARE_SF_JUMP gtsf2 296*c87b03e5Sespie#endif /* L_gtsf2 */ 297*c87b03e5Sespie 298*c87b03e5Sespie#ifdef L_gesf2 299*c87b03e5SespieCOMPARE_SF_JUMP __gesf2 300*c87b03e5Sespie#endif /* L_gesf2 */ 301*c87b03e5Sespie 302*c87b03e5Sespie#ifdef L_ltsf2 303*c87b03e5SespieCOMPARE_SF_JUMP __ltsf2 304*c87b03e5Sespie#endif /* L_ltsf2 */ 305*c87b03e5Sespie 306*c87b03e5Sespie#ifdef L_lesf2 307*c87b03e5SespieCOMPARE_SF_JUMP lesf2 308*c87b03e5Sespie#endif /* L_lesf2 */ 309