- Timestamp:
- May 1, 2004, 6:01:44 AM (21 years ago)
- Location:
- trunk/src/gcc/gcc/config/i386
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gcc/gcc/config/i386/emx-libgcc1.asm
-
Property cvs2svn:cvs-rev
changed from
1.3
to1.4
r1411 r1412 1 // 2 // r=bird: Need to determin the correct licensing on this code. 3 // Unless otherwise stated I guess it ends up as GPL. 4 // 5 6 // Avoid including emx/asm386.h 7 #define ALIGN .align 2, 0x90 8 9 #define LABEL0(name) _##name 10 #define LABEL(name) LABEL0(name) 11 1 .text 2 3 #ifdef L_alloca 4 .globl __alloca 5 // IN: EAX = stack space to allocate (rounded to 4 boundary by GCC) 6 // OUT: ESP adjusted down by EAX, stack probed 7 // NOTE: Never call this from C! 8 // CHG: EAX. ESP 9 __alloca: 10 pushl %ecx /* save work registers */ 11 movl %esp,%ecx /* keep a pointer to stack frame */ 12 negl %eax 13 leal 4+4(%esp,%eax),%esp /* adjust stack pointer */ 14 leal 4+4(%ecx),%eax 15 .align 2, 0x90 16 L1: subl $0x1000,%eax /* step down */ 17 cmpl %esp,%eax 18 jb L2 19 testb %al,(%eax) /* probe stack */ 20 jmp L1 21 L2: movl 4(%ecx),%eax /* return address */ 22 movl (%ecx),%ecx /* pop ECX */ 12 23 #if defined (__EPILOGUE__) 13 #define EPILOGUE_NO_RET(name) LABEL(__POST$##name): 14 #else 15 #define EPILOGUE_NO_RET(name) 16 #endif 17 18 .text 19 20 #ifdef L_alloca 21 .globl __alloca 22 23 // IN: EAX = stack space to allocate (rounded to 4 boundary by GCC) 24 // OUT: ESP adjusted down by EAX, stack probed 25 // NOTE: Never call this from C! 26 // CHG: EAX 27 28 ALIGN 29 __alloca: 30 pushl %ecx /* save work registers */ 31 movl %esp,%ecx /* keep a pointer to stack frame */ 32 negl %eax 33 leal 4+4(%esp,%eax),%esp /* adjust stack pointer */ 34 leal 4+4(%ecx),%eax 35 ALIGN 36 L1: subl $0x1000,%eax /* step down */ 37 cmpl %esp,%eax 38 jb L2 39 testb %al,(%eax) /* probe stack */ 40 jmp L1 41 L2: movl 4(%ecx),%eax /* return address */ 42 movl (%ecx),%ecx /* pop ECX */ 43 EPILOGUE_NO_RET(_alloca) 44 jmp *%eax /* return */ 24 ___POST$_alloca: 25 #endif 26 jmp *%eax /* return */ 45 27 46 28 #endif // L_alloca 47 29 48 //------------------------------------------------------------------------------49 // division of 64-bit numbers50 //51 // Original idea by Eberhard Mattes:52 //53 // There's a better solution: set x':=x, y':=y. Shift right both x' and54 // y' until x' < 2^32. Then divide x' by y'. The result can be off by -155 // due to the approximation. This can be checked by multiplying the56 // result by y and comparing to x-y. This verification step is not57 // required for x < 2^32.58 //59 // later (A.Z.) -60 //61 // There`s even a better solution: since i386+ can divide a 64-bit62 // integer by a 32-bit integer, we should shift both operands right until63 // quotient (i.e. y' in terms above) will be < 2^32. We can do this in one64 // step if we`ll use bsf/bsr i386+ instruction. If quotient is initially65 // less than 2^32, we can check first for overflow (i.e. if result will be66 // bigger or equal than 2^32) then proceed by well-known scheme (described67 // below) if it will overflow, and simply divide if it will not overflow.68 //69 // even more later (A.Z.) -70 //71 // hmm... after looking into libgcc2.c I see that it uses absolutely the72 // same idea :-) anyway, this asm implementation is shorter and faster73 //------------------------------------------------------------------------------74 // Here is how we`ll do 64-by-32 bit division (Eberhard Mattes):75 //76 // Divide 64-bit number by 32-bit number77 //78 // 2^32 a + b a 2^32 (a mod c) + b79 // ---------- = 2^32 --- + ------------------ (integer division)80 // c c c81 //82 // (2^32 a + b) mod c = (2^32 (a mod c) + b) mod c83 //84 // Proof:85 //86 // Divide by 2^32 c by successive subtraction (k steps) of 2^32 c.87 //88 // 2^32 a + b 2^32 a + b - 2^32 k c 2^32 (a-kc) + b89 // ---------- = 2^32 k + --------------------- = 2^32 k + ---------------90 // c c c91 //92 // For k = [a/c], the equality 0 <= a-kc < c is true. Then, a-kc = a mod c.93 // For this k, the final division cannot overflow.94 //------------------------------------------------------------------------------95 96 #ifdef L_udivdi397 98 // UDItype __udivdi3 (UDItype n, UDItype d)99 100 .globl ___udivdi3101 102 #define n 8+4(%esp)103 #define d 8+12(%esp)104 105 ALIGN106 ___udivdi3:107 pushl %ebx108 pushl %esi109 movl n, %eax110 movl 4+n, %edx // edx:eax = n111 movl d, %ebx112 movl 4+d, %esi // esi:ebx = d113 bsrl %esi, %ecx114 jnz Lshiftcl115 116 // We`re here when d is less than 2^32117 cmpl %ebx, %edx // edx < ebx?118 jb Ldiv // Yes, do a straight div119 120 // If we`re here, the result of division is a 64-bit integer121 // A 64-bit integer can result ONLY when (n >> 32) >= d122 movl %edx, %eax123 xorl %edx, %edx124 divl %ebx125 movl %eax, %esi // high-order 32 bits of result126 movl n, %eax // remainder of prev. div. in %edx127 Ldiv: divl %ebx128 movl %esi, %edx // edx:eax = result129 popl %esi130 popl %ebx131 ret132 133 Lshiftcl:134 // If we`re here, d is bigger or equal than 2^32135 // When cl is 31, we have result = n >= d ? 1 : 0136 cmpb $0x1f,%cl137 jb Lless31138 xorl %edx, %edx139 movl $1, %eax // Assume result = 1140 cmpl %esi, %edx141 ja Lexit142 jb Lzero143 cmpl %ebx, %eax144 jae Lexit145 Lzero: decl %eax146 Lexit: popl %esi147 popl %ebx148 ret149 150 Lless31:151 pushl %edi152 153 // Now we have to shift both n and d right cl times154 incb %cl155 xorl %edi, %edi156 shrdl %cl, %ebx, %edi // edi = discarded bits from d157 shrdl %cl, %esi, %ebx // now esi is free158 // Dirty trick: we should clear esi now, but rely on fact that esi >> cl = 0159 shrdl %cl, %eax, %esi // esi = discarded bits from n160 shrdl %cl, %edx, %eax // shift edx:eax right161 shrl %cl, %edx162 163 // Now ebx contains d, and edx:eax contains n164 divl %ebx165 166 // Now we should check whenever result*edi is167 // bigger or equal than remainder:esi -- if so, we168 // should decrement the result169 movl %eax, %ebx // Duplicate result into ebx170 movl %edx, %ecx // Duplicate remainder into ecx171 mull %edi172 cmpl %ecx, %edx173 jae Ldecres174 jb Lresok175 cmpl %esi, %eax176 jb Lresok177 178 Ldecres: decl %ebx179 Lresok: xorl %edx, %edx // edx:eax = result180 movl %ebx, %eax181 popl %edi182 popl %esi183 popl %ebx184 ret185 186 #endif // L_udivdi3187 188 #ifdef L_umoddi3189 190 // UDItype __umoddi3 (UDItype n, UDItype d)191 192 .globl ___umoddi3193 194 #define n 8+4(%esp)195 #define d 8+12(%esp)196 197 ALIGN198 ___umoddi3:199 pushl %ebx200 pushl %esi201 movl n, %eax202 movl 4+n, %edx // edx:eax = n203 movl d, %ebx204 movl 4+d, %esi // esi:ebx = d205 bsrl %esi, %ecx206 jnz Lshiftcl207 208 // We`re here when d is less than 2^32209 cmpl %ebx, %edx // edx < ebx?210 jb Ldiv // Yes, do a straight div211 212 // If we`re here, the result of division is a 64-bit integer213 // A 64-bit integer can result ONLY when (n >> 32) >= d214 movl %edx, %eax215 xorl %edx, %edx216 divl %ebx217 movl n, %eax // remainder of prev. div. in %edx218 Ldiv: divl %ebx219 movl %edx, %eax // lo(remainder) = edx220 xorl %edx, %edx // hi(remainder) = 0221 popl %esi222 popl %ebx223 ret224 225 Lshiftcl:226 // If we`re here, d is bigger or equal than 2^32227 // When cl is 31, we have result = n > d ? n - d : n228 cmpb $0x1f,%cl229 jb Lless31230 subl %ebx, %eax231 sbbl %esi, %edx232 jnc Lexit233 movl n, %eax234 movl 4+n, %edx // edx:eax = n235 Lexit: popl %esi236 popl %ebx237 ret238 239 Lless31:240 pushl %edi241 pushl %ecx242 243 // Now we have to shift both n and d right cl times244 incb %cl245 xorl %edi, %edi246 shrdl %cl, %ebx, %edi // edi = discarded bits from d247 shrdl %cl, %esi, %ebx // now esi is free248 // Dirty trick: we should clear esi now, but rely on fact that esi >> cl = 0249 shrdl %cl, %eax, %esi // esi = discarded bits from n250 shrdl %cl, %edx, %eax // shift edx:eax right251 shrl %cl, %edx252 253 // Now ebx contains d, and edx:eax contains n254 divl %ebx255 256 // Now compute remainder as (edx:esi - result*edi) >> cl257 movl %edx, %ecx // Duplicate remainder into ecx258 mull %edi259 260 subl %esi, %eax261 sbbl %ecx, %edx // Compute result*edi - ecx:esi262 jb Lnegok // remainder is bigger than result*edi263 jnz Lnotz264 265 testl %eax, %eax266 jz Lnormalize // modulo = 0267 268 Lnotz: subl %edi, %eax // Adjust modulo as if result269 sbbl %ebx, %edx // was decremented by one270 271 Lnegok: notl %edx272 negl %eax273 sbbl $-1, %edx274 275 Lnormalize: popl %ecx276 xorb $0x1f, %cl277 shrdl %cl, %edx, %eax278 shrl %cl, %edx279 280 popl %edi281 popl %esi282 popl %ebx283 ret284 285 #endif // L_umoddi3286 287 //**********************************************************//288 // //289 // Signed division/modulo uses unsigned versions of div/mod //290 // //291 //**********************************************************//292 293 #ifdef L_divdi3294 295 // DItype __divdi3 (DItype n, DItype d)296 297 .globl ___divdi3298 299 #define n 4+4(%esp)300 #define d 4+12(%esp)301 302 ALIGN303 ___divdi3:304 pushl %esi305 306 movl 4+n, %edx // edx:eax = n307 movl 4+d, %esi // esi:ecx = d308 movl %edx, %eax309 xorl %esi, %eax // Check resulting sign310 js Lnegate_sign311 312 testl %edx, %edx313 jns Lgoforit314 315 notl 4+n // Negate both args316 negl n317 sbbl $-1, 4+n318 319 notl 4+d320 negl d321 sbbl $-1, 4+d322 323 Lgoforit: popl %esi324 jmp ___udivdi3 // Dirty trick, but works325 326 Lnegate_sign: movl n, %eax327 movl d, %ecx328 329 testl %edx, %edx330 jns Ln_pos331 notl %edx332 negl %eax333 sbbl $-1, %edx334 Ln_pos:335 testl %esi, %esi336 jns Ld_pos337 notl %esi338 negl %ecx339 sbbl $-1, %esi340 Ld_pos:341 pushl %esi342 pushl %ecx343 pushl %edx344 pushl %eax345 call ___udivdi3346 addl $2*8, %esp347 348 notl %edx // Negate result349 negl %eax350 sbbl $-1, %edx351 352 popl %esi353 ret354 #endif // L_divdi3355 356 #ifdef L_moddi3357 358 // DItype __moddi3 (DItype n, DItype d)359 360 .globl ___moddi3361 362 #define n 4+4(%esp)363 #define d 4+12(%esp)364 365 ALIGN366 ___moddi3:367 pushl %esi368 369 movl 4+n, %edx // edx:eax = n370 movl 4+d, %esi // esi:ecx = d371 testl %edx, %edx372 js Lnegate_sign373 374 testl %esi, %esi375 jns Lgoforit376 377 notl 4+d // negate d378 negl d379 sbbl $-1, 4+d380 381 Lgoforit: popl %esi382 jmp ___umoddi3 // Dirty trick, but works383 384 Lnegate_sign: movl n, %eax385 movl d, %ecx386 387 testl %edx, %edx388 jns Ln_pos389 notl %edx390 negl %eax391 sbbl $-1, %edx392 Ln_pos:393 testl %esi, %esi394 jns Ld_pos395 notl %esi396 negl %ecx397 sbbl $-1, %esi398 Ld_pos:399 pushl %esi400 pushl %ecx401 pushl %edx402 pushl %eax403 call ___umoddi3404 addl $2*8, %esp405 406 notl %edx // Negate result407 negl %eax408 sbbl $-1, %edx409 410 popl %esi411 ret412 413 #endif // L_moddi3 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/gcc/gcc/config/i386/t-emx
-
Property cvs2svn:cvs-rev
changed from
1.25
to1.26
r1411 r1412 1 # start-of-file: $Id$ 2 # 3 # InnoTek GCC for OS/2 target stuff. 4 # 5 6 # Native include directory. 7 ifdef PATH_IGCC 8 NATIVE_SYSTEM_HEADER_DIR = $(PATH_IGCC)/include 9 else 10 ifdef PATH_EMXPGCC 11 NATIVE_SYSTEM_HEADER_DIR = $(PATH_EMXPGCC)/include 12 else 13 ifdef PATH_EMX 14 NATIVE_SYSTEM_HEADER_DIR = $(PATH_EMX)/include 15 endif 16 endif 17 endif 18 19 20 # DLL version string. 21 gccdll_version = $(subst .,,$(gcc_version)) 22 1 23 # The command to run REXX scripts (you overload) 2 REXX ?= kRx.exe24 REXX ?= kRx.exe 3 25 4 # EMX target have share libgcc, but the names are release specific and constrained by 8.3 limits. 5 SHLIB_BASENAME = gcc$(gccdll_version) 6 SHLIB_MULTINAME= $(SHLIB_BASENAME) 7 SHLIB_DLLNAME = $(SHLIB_MULTINAME).dll 8 ifdef GCC_OMF 9 SHLIB_BASENAME = gcc$(gccdll_version)o 10 SHLIB_LINK = export DLLAR_CMDLINE="$$(patsubst %.o,%.obj,@shlib_objs@)" \ 11 && emxomf @shlib_objs@ \ 12 && $(REXX) dllar.cmd -o $$(@D)/$(SHLIB_DLLNAME) \ 13 -ordinal @multilib_flags@ -nocrtdll \ 14 -flags "-g -Zomf -Zhigh-mem -v" \ 15 -ex "___main ___do_global_* ___ctordtor* ___eh* _DLL_InitTerm" \ 16 -d "GNU C runtime shared library version $(gcc_version)" \ 17 -libf "INITINSTANCE TERMGLOBAL" -lc_alias -lc_dll \ 18 && realar rs $$(@D)/$(SHLIB_BASENAME).a libgcc/$$(@D)/__main.o libgcc/$$(@D)/emx-ctordtor.o libgcc/$$(@D)/emx-eh.o \ 19 && emxomf -o $$(@D)/$(SHLIB_BASENAME).lib $$(@D)/$(SHLIB_BASENAME).a \ 20 && touch $$@ 21 else 22 SHLIB_LINK = export DLLAR_CMDLINE="@shlib_objs@" && \ 26 # The OS/2 target have shared libgcc, but the names are release specific and constrained by 8.3 limits. 27 SHLIB_BASENAME = gcc$(gccdll_version) 28 SHLIB_MULTINAME = $(SHLIB_BASENAME) 29 SHLIB_DLLNAME = $(SHLIB_MULTINAME).dll 30 SHLIB_LINK = export DLLAR_CMDLINE="@shlib_objs@" && \ 23 31 $(REXX) dllar.cmd -o $$(@D)/$(SHLIB_DLLNAME) \ 24 32 -ordinal @multilib_flags@ -nocrtdll \ 25 33 -flags "-Zhigh-mem -Zomf -g" \ 26 34 -ex "___main ___do_global_* ___ctordtor* ___eh* _DLL_InitTerm" \ 27 -d "GNU C runtime shared library version $(gcc_version)" \35 -d "GNU GCC Runtime Version $(gcc_version)" \ 28 36 -libf "INITINSTANCE TERMGLOBAL" -lc_alias -lc_dll \ 29 37 && ar rs $$(@D)/$(SHLIB_BASENAME).a libgcc/$$(@D)/__main.o libgcc/$$(@D)/emx-ctordtor.o libgcc/$$(@D)/emx-eh.o \ 30 38 && touch $$@ 31 endif 32 SHLIB_SUBDIR = . 33 SHLIB_INSTALL = $$(INSTALL_DATA) $(SHLIB_SUBDIR)/$(SHLIB_DLLNAME) $$(DESTDIR)$$(slibdir)/ \ 39 SHLIB_SUBDIR = . 40 SHLIB_INSTALL = $$(INSTALL_DATA) $(SHLIB_SUBDIR)/$(SHLIB_DLLNAME) $$(DESTDIR)$$(slibdir)/ \ 34 41 && $$(INSTALL_DATA) $(SHLIB_SUBDIR)/$(SHLIB_BASENAME).a $$(DESTDIR)$$(libsubdir)/$(SHLIB_SUBDIR)/ 35 42 36 43 # Dont use collect2 37 USE_COLLECT2 =44 USE_COLLECT2 = 38 45 # Don't run fixproto 39 STMP_FIXPROTO =46 STMP_FIXPROTO = 40 47 # Don't fix includes 41 STMP_FIXINC =48 STMP_FIXINC = 42 49 43 # bird: this is just bs and doesn't belong here at all. 44 ## Override linker flags 45 #LDFLAGS = -Zexe -Zcrtdll -Zstack 1024 46 47 # Add the 's' flag to $AR so that we don't need ranlib 48 AR_FLAGS = rcs 49 50 # We also want epilogues for each function in libgcc 50 # Override libgcc2 C flags to ensure stack probing and epilogues. 51 51 TARGET_LIBGCC2_CFLAGS = -Zaout -O2 -fomit-frame-pointer -Wall -mprobe -mepilogue -DNDEBUG 52 52 53 53 # Provide alternative source code for libgcc1 54 LIBGCC1 = libgcc1-asm.a55 CROSS_LIBGCC1 = libgcc1-asm.a56 LIB1ASMSRC = i386/emx-libgcc1.asm57 LIB1ASMFUNCS = _alloca _udivdi3 _umoddi3 _divdi3 _moddi354 LIBGCC1 = libgcc1-asm.a 55 CROSS_LIBGCC1 = libgcc1-asm.a 56 LIB1ASMSRC = i386/emx-libgcc1.asm 57 LIB1ASMFUNCS = _alloca 58 58 59 # Extra functions to add to libgcc. (bird: don't forget $(srcdir) prefixing!)59 # Extra functions to add to libgcc. 60 60 LIB2FUNCS_EXTRA = $(srcdir)/config/i386/emx-ctordtor.c 61 LIB2ADDEH = $(srcdir)/config/i386/emx-eh.c $(srcdir)/config/i386/emx-dllinit.c \ 62 $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c $(srcdir)/unwind-sjlj.c 61 LIB2ADDEH = \ 62 $(srcdir)/config/i386/emx-eh.c \ 63 $(srcdir)/config/i386/emx-dllinit.c \ 64 $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ 65 $(srcdir)/unwind-sjlj.c 63 66 #LIB2ADDEHDEP 64 67 65 68 66 # EMX include directory67 # /emx/ is not emx here.68 #SYSTEM_HEADER_DIR = /emx/include69 NATIVE_SYSTEM_HEADER_DIR = $(PATH_EMXPGCC)/include70 71 # When compiling libgcc with the fresh xgcc, we still need the system headers72 # bird: this doesn't work for me... What am I doing wrong?73 #LIBGCC2_INCLUDES = -I$(SYSTEM_HEADER_DIR)74 75 # Same when compiling stage 2, 3 etc76 # bird: this doesn't work for me... What am I doing wrong?77 #T_CFLAGS = -I$(SYSTEM_HEADER_DIR)78 # bird: flags for GCC bootstrapping (stage2+)79 80 69 # Copy these files to include/ subdirectory 81 # $(srcdir)/ginclude/stddef.h does not contain emx`s definition of _threadid 82 USER_H = $(srcdir)/ginclude/stdarg.h $(srcdir)/ginclude/varargs.h \ 83 $(srcdir)/ginclude/stdbool.h $(srcdir)/ginclude/iso646.h \ 84 $(EXTRA_HEADERS) 85 86 # Additional dependencies to build gcc.a and gcc_p.a 87 # plus dynamicaly-linked version of libgcc* 88 gccdll_version = $(subst .,,$(gcc_version)) 89 90 # bird (#424): dropping multilibs. Old hacks - START 91 #stage1 stage2 stage3 stage4: 92 # echo "t-emx hacks: $@ starting" 93 # -mv -f *.exe *.ready st mt s-libgcc $@ 94 # -rm -f $@/$(LIBGCC) 95 # echo "t-emx hacks: $@ done" 96 97 ## Some final polishing of libgcc ... 98 ## r=bird: Moved parts of this up to the SHLIB_LINK command. 99 ## Use cp as mv causes recreation of libversions during make install. 100 ## Is there ANY chance we could juse leave them as libgcc*.a? That would've 101 ## been much more convenient... 8.3 isn't an argument. 102 #$(ALL): s-libgcc 103 #s-libgcc: $(LIBGCC) 104 # echo "t-emx hacks: $@ starting" 105 # cp -f st/libgcc.a st/gcc.a 106 # cp -f st/libgcc_eh.a st/gcc_eh.a 107 # cp -f mt/libgcc.a mt/gcc.a 108 # cp -f mt/libgcc_eh.a mt/gcc_eh.a 109 # $(STAMP) s-libgcc 110 # echo "t-emx hacks: $@ done" 111 # bird (#424): dropping multilibs. Old hacks - END 70 # GCC-OS/2: We override this to prevent usage of $(srcdir)/ginclude/stddef.h 71 # and $(srcdir)/ginclude/float.h. 72 # bird: Don't forget to check this when updating the code GCC. 73 USER_H = \ 74 $(srcdir)/ginclude/iso646.h \ 75 $(srcdir)/ginclude/stdarg.h \ 76 $(srcdir)/ginclude/stdbool.h \ 77 \ 78 $(srcdir)/ginclude/varargs.h \ 79 $(srcdir)/unwind.h \ 80 $(EXTRA_HEADERS) 112 81 113 82 # bird (#424): New gcc*dll hacks … … 117 86 echo "t-emx hacks: $@ done" 118 87 88 # how to make the emx.o object. 119 89 emx.o: $(srcdir)/config/i386/emx.c $(RTL_H) $(TREE_H) $(CONFIG_H) 120 90 $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/emx.c 121 91 92 # end-of-file: t-emx 93 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.