/* This C language subroutine provides support for the integer types of the language. The Run Time Library for the C Language. Gordon A. Sterling (617) 461 - 3076 DSP Development Tools Engineering Version 1.1 Created on 6/10/90 Updated on 5/94 by AS int ___sdiv(int N, int D); unsigned int ___udiv(unsigned int N, unsigned int D); int ___smod(int N, int modulo); unsigned int ___umod(unsigned int N unsigned int modulo); long int ___sldiv(long int N, long int D); unsigned long int ___uldiv(unsigned long int N, unsigned long int D); long int ___slmod(long int N, long int modulo); unsigned long int ___ulmod(unsigned long int N, unsigned long int modulo); int ___dtoi(double x); int ___ldtoi(long double x); unsigned int ___dtoui(double x); unsigned int ___ldtoui(long double x); Adding GCC entry points. (gas/mmh) ___divsi3, ___udivsi3, ___modsi3, ___umodsi3 ___truncdfsi2, ___fixdfsi Added ___fixunsdfsi */ #include "lib_glob.h" #include "int_glob.h" .SEGMENT/CODE Code_Space_Name; .FILE RTL_FILENAME; .GLOBAL ___sdiv, ___sldiv, ___udiv, ___uldiv; .GLOBAL ___smod, ___slmod, ___umod, ___ulmod; .GLOBAL ___dtoi, ___ldtoi; .GLOBAL ___divsi3, ___udivsi3, ___modsi3, ___umodsi3; .GLOBAL ___truncdfsi2, ___fixdfsi; .GLOBAL ___fixunsdfsi; ___divsi3: ___sldiv: ___sdiv: put(R7); put(R11); R2=MODE1; BIT SET MODE1 32768; /*Set TRUNCATE mode*/ BIT CLR MODE1 65536; /*Set to 40-BIT mode*/ /* WARNING: In this sequence of code, the compiler passes param1 in */ /* R4 and param2 in R8. The float divide routine does not alter */ /* either of these registers, so the are used at the end of the */ /* routine. gas */ F11=2.0; CALL (PC, ___float_divide) (DB); F7=FLOAT R4; /*Convert to long float*/ F12=FLOAT R8; F7=PASS F7, R11=dm_1; IF LT JUMP (PC, fix_neg1); JUMP (PC, fixed_up1) (DB); R0=FIX F7, MODE1=R2; R2=PASS R11, R12=R8; /* Get param2 again */ fix_neg1: F7=ABS F7; R2=-R11, MODE1=R2; R0=FIX F7, R12=R8; /* Get param2 again */ R0=-R0; fixed_up1: R11=R0*R12 (SSI), R7=R4; /* Get param1 again */ R11=R7-R11, FETCH_RETURN /* Need to check quotient */ R11=CLIP R11 BY R12; R12=R11+R12, R11=R11-R12; IF EQ R0=R0+R2; restore_state: FETCH_RETURN get(R11,1); get(R7,2); RETURN (DB); RESTORE_STACK RESTORE_FRAME /* This routine provides unsigned integer division. This is the same as signed division except when the MSB is set. In this case the value is downshifted one bit, and the floating point value is scaled by one. */ ___udivsi3: ___uldiv: ___udiv: R0=R8-1, R2=MODE1; /* if dividing by one */ IF EQ JUMP (PC, restore_state) (DB); R0=PASS R4, put(R7); /* return first arg */ R7=PASS R4, put(R11); R1=MR2F; R1=MR1F, put(R1); R1=MR0F, put(R1); MRF=0, put(R1); MR0F=R7; BIT CLR MODE1 32768; BIT CLR MODE1 65536; F11=FLOAT R4, R0=dm_1; /*Attempt a normal float, R0=1*/ IF LE R7=LSHIFT R7 BY -1; /*If result is negative*/ IF LE F11=FLOAT R7 BY R0; /*Downshift input 1*/ F11=FLOAT R8, F7=F11; /*and refloat with scale of 1*/ IF LE R12=LSHIFT R8 BY -1; /*Repeat for second number*/ IF LE F11=FLOAT R12 BY R0; CALL (PC, ___float_divide) (DB); F12=PASS F11; F11=2.0; R0=FIX F7, R12=dm_M1; /*Try a normal fix, R12=-1*/ IF NOT AV R12=R12+1; /*Normal fix will work*/ R0=FIX F7 BY R12, R11=R8; /*Read divisor*/ R12=-R12, R7=R4; /*Read dividend*/ R0=LSHIFT R0 BY R12, R12=R11; /*Shift up if necessary*/ R11=MRF-R0*R12 (UUI); /*Need to test quotient*/ IF MS JUMP (PC, get_outta_here) (DB), R0=R0-1; R11=R11-R12, MODE1=R2; R11=R11-R11+CI-1; IF GT R0=R0+1; get_outta_here: get(R1,1); MR0F=R1, get(R1,2); MR1F=R1, get(R1,3); JUMP (PC, restore_state) (DB); MR2F=R1; alter(3); ___modsi3: ___slmod: ___smod: put(R7); F7=FLOAT R4, put(R11); /*Convert to long float*/ F12=FLOAT R8, R2=MODE1; BIT SET MODE1 32768; /*Set TRUNCATE mode*/ CALL (PC, ___float_divide) (DB); BIT CLR MODE1 65536; /*Set to 40-BIT mode*/ F11=2.0; F7=PASS F7; IF LE JUMP (PC, fix_neg2); JUMP (PC, fixed_up2) (DB); R0=FIX F7, R12=R8; /* Get param2 to compute integer quotient*/ R0=R0*R12 (SSI), R7=R4; /* Multiply quotient by divisor*/ fix_neg2: F7=ABS F7; R0=FIX F7, R12=R8; /* Compute integer quotient*/ R0=-R0; R0=R0*R12 (SSI), R7=R4; /* Multiply quotient by divisor*/ fixed_up2: R0=R7-R0; /*Subtract product from input*/ R11=CLIP R0 BY R12; /*Get maximum argument*/ COMP(R12,R11); IF EQ R0=R0-R12; /*Remove one more modulo */ R12=-R12; JUMP (PC, restore_state) (DB); COMP(R12,R11), MODE1=R2; /*If max > modulo, reduce*/ IF EQ R0=R0-R12; /*Remove one more modulo*/ ___umodsi3: ___ulmod: ___umod: R0=R0-R0, put(R7); /* return zero */ R12=PASS R8, put(R11); R11=R8-1, R2=MODE1; /* if dividing by one */ IF EQ JUMP (PC, restore_state); R1=MR2F; R1=MR1F, put(R1); R1=MR0F, put(R1); MRF=0, put(R1); MR0F=R4; BIT CLR MODE1 32768; BIT CLR MODE1 65536; R0=1; /*Used in float operation*/ F11=FLOAT R4, R7=R4; /*Attempt a normal float*/ IF LE R7=LSHIFT R7 BY -1; /*If result is negative*/ IF LE F11=FLOAT R7 BY R0; /*Downshift input 1*/ F11=FLOAT R12, F7=F11; /*and refloat with scale of 1*/ IF LE R12=LSHIFT R12 BY -1; /*Repeat for second number*/ IF LE F11=FLOAT R12 BY R0; CALL (PC, ___float_divide) (DB); F12=PASS F11; F11=2.0; R11=-1; R0=FIX F7, R12=R8; /*Attempt normal FIX */ IF NOT AV R11=R11+1; /*If no overflow set R11=0 */ R0=FIX F7 BY R11; /*If overflowed scale by -1 */ R11=-R11, get(R1,1); /*Invert for shift */ R0=LSHIFT R0 BY R11; /*If overflowed upshift output*/ R0=MRF-R0*R12 (UUI), R11=dm_0; /*Mult quotient by div & sub from*/ /*input, R11=0 */ IF MS R0=R0+R12; /*If rem is neg, add rem to denom*/ R2=R0-R12, MODE1=R2; IF AC R0=R0-R12; /* otherwise, rem > denom, so sub*/ MR0F=R1, get(R1,2); MR1F=R1, get(R1,3); JUMP (PC, restore_state) (DB); MR2F=R1; alter(3); ___fixdfsi: ___truncdfsi2: ___ldtoi: ___dtoi: reads(R4,1); R0=PASS R4, reads(R8,2); /* Copy param1 */ CALL (PC, ___lib_dtoi) (DB); put(R3); R1=PASS R8, FETCH_RETURN /* Copy param2 */ get(R3,1); RETURN (DB); RESTORE_STACK RESTORE_FRAME ___fixunsdfsi: ___ldtoui: ___dtoui: reads(R4,1); R0=PASS R4, reads(R8,2); /* Copy param1 */ CALL (PC, ___lib_dtoui) (DB); put(R3); R1=PASS R8, FETCH_RETURN /* Copy param2 */ get(R3,1); RETURN (DB); RESTORE_STACK RESTORE_FRAME .ENDSEG;