README
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:18k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
  2. This file is part of the GNU MP Library.
  3. The GNU MP Library is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or (at your
  6. option) any later version.
  7. The GNU MP Library is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  9. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  10. License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  13.                       X86 MPN SUBROUTINES
  14. This directory contains mpn functions for various 80x86 chips.
  15. CODE ORGANIZATION
  16. x86               i386, generic
  17. x86/i486          i486
  18. x86/pentium       Intel Pentium (P5, P54)
  19. x86/pentium/mmx   Intel Pentium with MMX (P55)
  20. x86/p6            Intel Pentium Pro
  21. x86/p6/mmx        Intel Pentium II, III
  22. x86/p6/p3mmx      Intel Pentium III
  23. x86/k6             AMD K6
  24. x86/k6/mmx        /
  25. x86/k6/k62mmx     AMD K6-2
  26. x86/k7             AMD Athlon
  27. x86/k7/mmx        /
  28. x86/pentium4      
  29. x86/pentium4/mmx  | Intel Pentium 4
  30. x86/pentium4/sse2 /
  31. The top-level x86 directory contains blended style code, meant to be
  32. reasonable on all x86s.
  33. STATUS
  34. The code is well-optimized for AMD and Intel chips, but there's nothing
  35. specific for Cyrix chips, nor for actual 80386 and 80486 chips.
  36. ASM FILES
  37. The x86 .asm files are BSD style assembler code, first put through m4 for
  38. macro processing.  The generic mpn/asm-defs.m4 is used, together with
  39. mpn/x86/x86-defs.m4.  See comments in those files.
  40. The code is meant for use with GNU "gas" or a system "as".  There's no
  41. support for assemblers that demand Intel style code.
  42. STACK FRAME
  43. m4 macros are used to define the parameters passed on the stack, and these
  44. act like comments on what the stack frame looks like too.  For example,
  45. mpn_mul_1() has the following.
  46.         defframe(PARAM_MULTIPLIER, 16)
  47.         defframe(PARAM_SIZE,       12)
  48.         defframe(PARAM_SRC,         8)
  49.         defframe(PARAM_DST,         4)
  50. PARAM_MULTIPLIER becomes `FRAME+16(%esp)', and the others similarly.  The
  51. return address is at offset 0, but there's not normally any need to access
  52. that.
  53. FRAME is redefined as necessary through the code so it's the number of bytes
  54. pushed on the stack, and hence the offsets in the parameter macros stay
  55. correct.  At the start of a routine FRAME should be zero.
  56.         deflit(`FRAME',0)
  57. ...
  58. deflit(`FRAME',4)
  59. ...
  60. deflit(`FRAME',8)
  61. ...
  62. Helper macros FRAME_pushl(), FRAME_popl(), FRAME_addl_esp() and
  63. FRAME_subl_esp() exist to adjust FRAME for the effect of those instructions,
  64. and can be used instead of explicit definitions if preferred.
  65. defframe_pushl() is a combination FRAME_pushl() and defframe().
  66. There's generally some slackness in redefining FRAME.  If new values aren't
  67. going to get used then the redefinitions are omitted to keep from cluttering
  68. up the code.  This happens for instance at the end of a routine, where there
  69. might be just four pops and then a ret, so FRAME isn't getting used.
  70. Local variables and saved registers can be similarly defined, with negative
  71. offsets representing stack space below the initial stack pointer.  For
  72. example,
  73. defframe(SAVE_ESI,   -4)
  74. defframe(SAVE_EDI,   -8)
  75. defframe(VAR_COUNTER,-12)
  76. deflit(STACK_SPACE, 12)
  77. Here STACK_SPACE gets used in a "subl $STACK_SPACE, %esp" to allocate the
  78. space, and that instruction must be followed by a redefinition of FRAME
  79. (setting it equal to STACK_SPACE) to reflect the change in %esp.
  80. Definitions for pushed registers are only put in when they're going to be
  81. used.  If registers are just saved and restored with pushes and pops then
  82. definitions aren't made.
  83. ASSEMBLER EXPRESSIONS
  84. Only addition and subtraction seem to be universally available, certainly
  85. that's all the Solaris 8 "as" seems to accept.  If expressions are wanted
  86. then m4 eval() should be used.
  87. In particular note that a "/" anywhere in a line starts a comment in Solaris
  88. "as", and in some configurations of gas too.
  89. addl $32/2, %eax           <-- wrong
  90. addl $eval(32/2), %eax     <-- right
  91. Binutils gas/config/tc-i386.c has a choice between "/" being a comment
  92. anywhere in a line, or only at the start.  FreeBSD patches 2.9.1 to select
  93. the latter, and from 2.9.5 it's the default for GNU/Linux too.
  94. ASSEMBLER COMMENTS
  95. Solaris "as" doesn't support "#" commenting, using /* */ instead.  For that
  96. reason "C" commenting is used (see asm-defs.m4) and the intermediate ".s"
  97. files have no comments.
  98. Any comments before include(`../config.m4') must use m4 "dnl", since it's
  99. only after the include that "C" is available.  By convention "dnl" is also
  100. used for comments about m4 macros.
  101. TEMPORARY LABELS
  102. Temporary numbered labels like "1:" used as "1f" or "1b" are available in
  103. "gas" and Solaris "as", but not in SCO "as".  Normal L() labels should be
  104. used instead, possibly with a counter to make them unique, see jadcl0() in
  105. x86-defs.m4 for instance.  A separate counter for each macro makes it
  106. possible to nest them, for instance movl_text_address() can be used within
  107. an ASSERT().
  108. "1:" etc must be avoided in gcc __asm__ blocks too.  "%=" for generating a
  109. unique number looks like a good alternative, but is that actually a
  110. documented feature?  In any case this problem doesn't currently arise.
  111. ZERO DISPLACEMENTS
  112. In a couple of places addressing modes like 0(%ebx) with a byte-sized zero
  113. displacement are wanted, rather than (%ebx) with no displacement.  These are
  114. either for computed jumps or to get desirable code alignment.  Explicit
  115. .byte sequences are used to ensure the assembler doesn't turn 0(%ebx) into
  116. (%ebx).  The Zdisp() macro in x86-defs.m4 is used for this.
  117. Current gas 2.9.5 or recent 2.9.1 leave 0(%ebx) as written, but old gas
  118. 1.92.3 changes it.  In general changing would be the sort of "optimization"
  119. an assembler might perform, hence explicit ".byte"s are used where
  120. necessary.
  121. SHLD/SHRD INSTRUCTIONS
  122. The %cl count forms of double shift instructions like "shldl %cl,%eax,%ebx"
  123. must be written "shldl %eax,%ebx" for some assemblers.  gas takes either,
  124. Solaris "as" doesn't allow %cl, gcc generates %cl for gas and NeXT (which is
  125. gas), and omits %cl elsewhere.
  126. For GMP an autoconf test GMP_ASM_X86_SHLDL_CL is used to determine whether
  127. %cl should be used, and the macros shldl, shrdl, shldw and shrdw in
  128. mpn/x86/x86-defs.m4 pass through or omit %cl as necessary.  See the comments
  129. with those macros for usage.
  130. IMUL INSTRUCTION
  131. GCC config/i386/i386.md (cvs rev 1.187, 21 Oct 00) under *mulsi3_1 notes
  132. that the following two forms produce identical object code
  133. imul $12, %eax
  134. imul $12, %eax, %eax
  135. but that the former isn't accepted by some assemblers, in particular the SCO
  136. OSR5 COFF assembler.  GMP follows GCC and uses only the latter form.
  137. (This applies only to immediate operands, the three operand form is only
  138. valid with an immediate.)
  139. DIRECTION FLAG
  140. The x86 calling conventions say that the direction flag should be clear at
  141. function entry and exit.  (See iBCS2 and SVR4 ABI books, references below.)
  142. Although this has been so since the year dot, it's not absolutely clear
  143. whether it's universally respected.  Since it's better to be safe than
  144. sorry, GMP follows glibc and does a "cld" if it depends on the direction
  145. flag being clear.  This happens only in a few places.
  146. POSITION INDEPENDENT CODE
  147.   Coding Style
  148.     Defining the symbol PIC in m4 processing selects SVR4 / ELF style
  149.     position independent code.  This is necessary for shared libraries
  150.     because they can be mapped into different processes at different virtual
  151.     addresses.  Actually, relocations are allowed but text pages with
  152.     relocations aren't shared, defeating the purpose of a shared library.
  153.     The GOT is used to access global data, and the PLT is used for
  154.     functions.  The use of the PLT adds a fixed cost to every function call,
  155.     and the GOT adds a cost to any function accessing global variables.
  156.     These are small but might be noticeable when working with small
  157.     operands.
  158.   Scope
  159.     It's intended, as a matter of policy, that references within libgmp are
  160.     resolved within libgmp.  Certainly there's no need for an application to
  161.     replace any internals, and we take the view that there's no value in an
  162.     application subverting anything documented either.
  163.     Resolving references within libgmp in theory means calls can be made with a
  164.     plain PC-relative call instruction, which is faster and smaller than going
  165.     through the PLT, and data references can be similarly PC-relative, saving a
  166.     GOT entry and fetch from there.  Unfortunately the normal linker behaviour
  167.     doesn't allow us to do this.
  168.     By default an R_386_PC32 PC-relative reference, either for a call or for
  169.     data, is left in libgmp.so by the linker so that it can be resolved at
  170.     runtime to a location in the application or another shared library.  This
  171.     means a text segment relocation which we don't want.
  172.   -Bsymbolic
  173.     Under the "-Bsymbolic" option, the linker resolves references to symbols
  174.     within libgmp.so.  This gives us the desired effect for R_386_PC32,
  175.     ie. it's resolved at link time.  It also resolves R_386_PLT32 calls
  176.     directly to their target without creating a PLT entry (though if this is
  177.     done to normal compiler-generated code it still leaves a setup of %ebx
  178.     to _GLOBAL_OFFSET_TABLE_ which may then be unnecessary).
  179.     Unfortunately -Bsymbolic does bad things to global variables defined in
  180.     a shared library but accessed by non-PIC code from the mainline (or a
  181.     static library).
  182.     The problem is that the mainline needs a fixed data address to avoid
  183.     text segment relocations, so space is allocated in its data segment and
  184.     the value from the variable is copied from the shared library's data
  185.     segment when the library is loaded.  Under -Bsymbolic, however,
  186.     references in the shared library are then resolved still to the shared
  187.     library data area.  Not surprisingly it bombs badly to have mainline
  188.     code and library code accessing different locations for what should be
  189.     one variable.
  190.     Note that this -Bsymbolic effect for the shared library is not just for
  191.     R_386_PC32 offsets which might have been cooked up in assembler, but is
  192.     done also for the contents of GOT entries.  -Bsymbolic simply applies a
  193.     general rule that symbols are resolved first from the local module.
  194.   Visibility Attributes
  195.     GCC __attribute__ ((visibility ("protected"))), which is available in
  196.     recent versions, eg. 3.3, is probably what we'd like to use.  It makes
  197.     gcc generate plain PC-relative calls to indicated functions, and directs
  198.     the linker to resolve references to the given function within the link
  199.     module.
  200.     Unfortunately, as of debian binutils 2.13.90.0.16 at least, the
  201.     resulting libgmp.so comes out with text segment relocations, references
  202.     are not resolved at link time.  If the gcc description is to be believed
  203.     this is this not how it should work.  If a symbol cannot be overridden
  204.     by another module then surely references within that module can be
  205.     resolved immediately (ie. at link time).
  206.   Present
  207.     In any case, all this means that we have no optimizations we can
  208.     usefully make to function or variable usages, neither for assembler nor
  209.     C code.  Perhaps in the future the visibility attribute will work as
  210.     we'd like.
  211. GLOBAL OFFSET TABLE
  212. The magic _GLOBAL_OFFSET_TABLE_ used by code establishing the address of the
  213. GOT sometimes requires an extra underscore prefix.  SVR4 systems and NetBSD
  214. don't need a prefix, OpenBSD does need one.  Note that NetBSD and OpenBSD
  215. are both a.out underscore systems, so the prefix for _GLOBAL_OFFSET_TABLE_
  216. is not simply the same as the prefix for ordinary globals.
  217. In any case in the asm code we write _GLOBAL_OFFSET_TABLE_ and let a macro
  218. in x86-defs.m4 add an extra underscore if required (according to a configure
  219. test).
  220. Old gas 1.92.3 which comes with FreeBSD 2.2.8 gets a segmentation fault when
  221. asked to assemble the following,
  222.         L1:
  223.             addl  $_GLOBAL_OFFSET_TABLE_+[.-L1], %ebx
  224. It seems that using the label in the same instruction it refers to is the
  225. problem, since a nop in between works.  But the simplest workaround is to
  226. follow gcc and omit the +[.-L1] since it does nothing,
  227.             addl  $_GLOBAL_OFFSET_TABLE_, %ebx
  228. Current gas 2.10 generates incorrect object code when %eax is used in such a
  229. construction (with or without +[.-L1]),
  230.             addl  $_GLOBAL_OFFSET_TABLE_, %eax
  231. The R_386_GOTPC gets a displacement of 2 rather than the 1 appropriate for
  232. the 1 byte opcode of "addl $n,%eax".  The best workaround is just to use any
  233. other register, since then it's a two byte opcode+mod/rm.  GCC for example
  234. always uses %ebx (which is needed for calls through the PLT).
  235. A similar problem occurs in an leal (again with or without a +[.-L1]),
  236.             leal  _GLOBAL_OFFSET_TABLE_(%edi), %ebx
  237. This time the R_386_GOTPC gets a displacement of 0 rather than the 2
  238. appropriate for the opcode and mod/rm, making this form unusable.
  239. SIMPLE LOOPS
  240. The overheads in setting up for an unrolled loop can mean that at small
  241. sizes a simple loop is faster.  Making small sizes go fast is important,
  242. even if it adds a cycle or two to bigger sizes.  To this end various
  243. routines choose between a simple loop and an unrolled loop according to
  244. operand size.  The path to the simple loop, or to special case code for
  245. small sizes, is always as fast as possible.
  246. Adding a simple loop requires a conditional jump to choose between the
  247. simple and unrolled code.  The size of a branch misprediction penalty
  248. affects whether a simple loop is worthwhile.
  249. The convention is for an m4 definition UNROLL_THRESHOLD to set the crossover
  250. point, with sizes < UNROLL_THRESHOLD using the simple loop, sizes >=
  251. UNROLL_THRESHOLD using the unrolled loop.  If position independent code adds
  252. a couple of cycles to an unrolled loop setup, the threshold will vary with
  253. PIC or non-PIC.  Something like the following is typical.
  254. deflit(UNROLL_THRESHOLD, ifdef(`PIC',10,8))
  255. There's no automated way to determine the threshold.  Setting it to a small
  256. value and then to a big value makes it possible to measure the simple and
  257. unrolled loops each over a range of sizes, from which the crossover point
  258. can be determined.  Alternately, just adjust the threshold up or down until
  259. there's no more speedups.
  260. UNROLLED LOOP CODING
  261. The x86 addressing modes allow a byte displacement of -128 to +127, making
  262. it possible to access 256 bytes, which is 64 limbs, without adjusting
  263. pointer registers within the loop.  Dword sized displacements can be used
  264. too, but they increase code size, and unrolling to 64 ought to be enough.
  265. When unrolling to the full 64 limbs/loop, the limb at the top of the loop
  266. will have a displacement of -128, so pointers have to have a corresponding
  267. +128 added before entering the loop.  When unrolling to 32 limbs/loop
  268. displacements 0 to 127 can be used with 0 at the top of the loop and no
  269. adjustment needed to the pointers.
  270. Where 64 limbs/loop is supported, the +128 adjustment is done only when 64
  271. limbs/loop is selected.  Usually the gain in speed using 64 instead of 32 or
  272. 16 is small, so support for 64 limbs/loop is generally only for comparison.
  273. COMPUTED JUMPS
  274. When working from least significant limb to most significant limb (most
  275. routines) the computed jump and pointer calculations in preparation for an
  276. unrolled loop are as follows.
  277. S = operand size in limbs
  278. N = number of limbs per loop (UNROLL_COUNT)
  279. L = log2 of unrolling (UNROLL_LOG2)
  280. M = mask for unrolling (UNROLL_MASK)
  281. C = code bytes per limb in the loop
  282. B = bytes per limb (4 for x86)
  283. computed jump            (-S & M) * C + entrypoint
  284. subtract from pointers   (-S & M) * B
  285. initial loop counter     (S-1) >> L
  286. displacements            0 to B*(N-1)
  287. The loop counter is decremented at the end of each loop, and the looping
  288. stops when the decrement takes the counter to -1.  The displacements are for
  289. the addressing accessing each limb, eg. a load with "movl disp(%ebx), %eax".
  290. Usually the multiply by "C" can be handled without an imul, using instead an
  291. leal, or a shift and subtract.
  292. When working from most significant to least significant limb (eg. mpn_lshift
  293. and mpn_copyd), the calculations change as follows.
  294. add to pointers          (-S & M) * B
  295. displacements            0 to -B*(N-1)
  296. OLD GAS 1.92.3
  297. This version comes with FreeBSD 2.2.8 and has a couple of gremlins that
  298. affect GMP code.
  299. Firstly, an expression involving two forward references to labels comes out
  300. as zero.  For example,
  301. addl $bar-foo, %eax
  302. foo:
  303. nop
  304. bar:
  305. This should lead to "addl $1, %eax", but it comes out as "addl $0, %eax".
  306. When only one forward reference is involved, it works correctly, as for
  307. example,
  308. foo:
  309. addl $bar-foo, %eax
  310. nop
  311. bar:
  312. Secondly, an expression involving two labels can't be used as the
  313. displacement for an leal.  For example,
  314. foo:
  315. nop
  316. bar:
  317. leal bar-foo(%eax,%ebx,8), %ecx
  318. A slightly cryptic error is given, "Unimplemented segment type 0 in
  319. parse_operand".  When only one label is used it's ok, and the label can be a
  320. forward reference too, as for example,
  321. leal foo(%eax,%ebx,8), %ecx
  322. nop
  323. foo:
  324. These problems only affect PIC computed jump calculations.  The workarounds
  325. are just to do an leal without a displacement and then an addl, and to make
  326. sure the code is placed so that there's at most one forward reference in the
  327. addl.
  328. REFERENCES
  329. "Intel Architecture Software Developer's Manual", volumes 1, 2a, 2b, 3a, 3b,
  330. 2006, order numbers 253665 through 253669.  Available on-line,
  331. ftp://download.intel.com/design/Pentium4/manuals/25366518.pdf
  332. ftp://download.intel.com/design/Pentium4/manuals/25366618.pdf
  333. ftp://download.intel.com/design/Pentium4/manuals/25366718.pdf
  334. ftp://download.intel.com/design/Pentium4/manuals/25366818.pdf
  335. ftp://download.intel.com/design/Pentium4/manuals/25366918.pdf
  336. "System V Application Binary Interface", Unix System Laboratories Inc, 1992,
  337. published by Prentice Hall, ISBN 0-13-880410-9.  And the "Intel386 Processor
  338. Supplement", AT&T, 1991, ISBN 0-13-877689-X.  These have details of calling
  339. conventions and ELF shared library PIC coding.  Versions of both available
  340. on-line,
  341. http://www.sco.com/developer/devspecs
  342. "Intel386 Family Binary Compatibility Specification 2", Intel Corporation,
  343. published by McGraw-Hill, 1991, ISBN 0-07-031219-2.  (Same as the above 386
  344. ABI supplement.)
  345. ----------------
  346. Local variables:
  347. mode: text
  348. fill-column: 76
  349. End: