bALib.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:17k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* bALib.s - i80x86 buffer manipulation library assembly routines */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,22aug01,hdn  added FUNC/FUNC_LABEL, replaced .align with .balign
  7. 01c,01jun93,hdn  updated to 5.1.
  8.   - fixed #else and #endif
  9.   - changed VOID to void
  10.   - changed ASMLANGUAGE to _ASMLANGUAGE
  11.   - changed copyright notice
  12. 01b,13oct92,hdn  debugged.
  13. 01a,07apr92,hdn  written based on TRON version.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains optimized versions of the routines in bLib.c
  18. for manipulating buffers of variable-length byte arrays.
  19. NOMANUAL
  20. INTERNAL
  21. i80386 transfer bus cycles for bytes, words, dwords.
  22.  -------------------------------------+----+----------------+---------------+
  23.   byte length of logical operand        1         2                4
  24.  -------------------------------------+----+----------------+---------------+
  25.   physical byte address in memory       xx   00  01  10  11   00  01  10  11
  26.  -------------------------------------+----+----------------+---------------+
  27.   transfer cycles over 32bits data bus  b    w   w   w  hb    d  hb  hw  h3
  28.                  lb       l3  lw  lb
  29.  -------------------------------------+----+----------------+---------------+
  30.   transfer cycles over 16bits data bus  b    w  lb   w  hb   lw  hb  hw  mw
  31.          hb      lb   hw  lb  lw  hb
  32.     mw      lb
  33.  -------------------------------------+----+----------------+---------------+
  34. b: byte transfer l: low order portion
  35. w: word transfer h: high order portion
  36. 3: 3-byte transfer m: middle order portion
  37. d: dword transfer x: don't care
  38. SEE ALSO: bLib(1), strLib(1)
  39. */
  40. #define _ASMLANGUAGE
  41. #include "vxWorks.h"
  42. #include "asm.h"
  43. .data
  44. .globl  FUNC(copyright_wind_river)
  45. .long   FUNC(copyright_wind_river)
  46. #ifndef PORTABLE
  47. /* internals */
  48. .globl GTEXT(bcopy)
  49. .globl GTEXT(bcopyBytes)
  50. .globl GTEXT(bcopyWords)
  51. .globl GTEXT(bcopyLongs)
  52. .globl GTEXT(bfill)
  53. .globl GTEXT(bfillBytes)
  54. .globl GTEXT(bfillWords)
  55. .globl GTEXT(bfillLongs)
  56. .text
  57. .balign 16
  58. /*******************************************************************************
  59. *
  60. * bcopy - copy one buffer to another
  61. *
  62. * This routine copies the first `nbytes' characters from
  63. * `source' to `destination'.  Overlapping buffers are handled correctly.
  64. * The copy is optimized by copying 4 bytes at a time if possible,
  65. * (see bcopyBytes (2) for copying a byte at a time only).
  66. *
  67. * SEE ALSO: bcopyBytes (2)
  68. *
  69. * NOMANUAL - manual entry in bLib (1)
  70. * void bcopy (source, destination, nbytes)
  71. *     char *source;       /* pointer to source buffer      *
  72. *     char *destination;  /* pointer to destination buffer *
  73. *     int nbytes;         /* number of bytes to copy       *
  74. */
  75. FUNC_LABEL(bcopy)
  76. pushl %ebp
  77. movl %esp,%ebp
  78. pushl %esi
  79. pushl %edi
  80. pushf
  81. /* put src in %esi, dest in %edi, and count in %edx */
  82. movl ARG1(%ebp),%esi /* source */
  83. movl ARG2(%ebp),%edi /* destination */
  84. movl ARG3(%ebp),%edx /* nbytes */
  85. /* Find out if there is an overlap problem.
  86.  * We have to copy backwards if destination lies within source,
  87.  * i.e. ((destination - source) > 0 && < nbytes) */
  88. movl %edi,%eax /* destination */
  89. subl %esi,%eax /* - source */
  90. jle bCopyFwd0 /* <= 0 means copy forward */
  91. cmpl %edx,%eax /* compare to nbytes */
  92. jl bCopyBck0 /* < nbytes means copy backwards */
  93. bCopyFwd0:
  94. cld
  95. /* if length is less than 10, it's cheaper to do a byte copy */
  96. cmpl $10,%edx /* test count */
  97. jl bCopyFwd5 /* do byte copy */
  98. /* If destination and source are not both odd, or both even,
  99.  * we must do a byte copy, rather than a long copy */
  100. movl %edi,%eax
  101. xorl %esi,%eax /* %eax = destination ^ source */
  102. btl $0,%eax
  103. jc bCopyFwd5
  104. /* If the buffers are odd-aligned, copy the first 1 - 3 bytes */
  105. movl %esi,%eax
  106. andl $3,%eax /* %eax has 0 - 3 */
  107. je bCopyFwd1 /* if long-aligned ? */
  108. movl %eax,%ecx /* %ecx has count */
  109. rep
  110. movsb /* copy the bytes */
  111. subl %eax,%edx /* decrement count by %eax */
  112. bCopyFwd1:
  113. /* Since we're copying 4 bytes at a crack, divide count by 4.
  114.  * Keep the remainder in %edx, so we can do those bytes at the 
  115.  * end of the loop. */
  116. movl %edx,%ecx
  117. shrl $2,%ecx /* count /= 4 */
  118. je bCopyFwd2 /* do the test first */
  119. rep
  120. movsl /* copy long by long */
  121. bCopyFwd2:
  122. andl $3,%edx /* remainder in %edx */
  123. /* Copy byte by byte */
  124. bCopyFwd5:
  125. movl %edx,%ecx /* Set up %ecx as the loop ctr */
  126. cmpl $0,%ecx
  127. je bCopy6 /* do the test first */
  128. rep
  129. movsb /* copy byte by byte */
  130. jmp bCopy6
  131. /* ---------------------- copy backwards ---------------------- */
  132. .balign 16,0x90
  133. bCopyBck0:
  134. addl %edx,%esi
  135. addl %edx,%edi
  136. std
  137. /* if length is less than 10, it's cheaper to do a byte copy */
  138. cmpl $10,%edx /* test count */
  139. jl bCopyBck5 /* do byte copy */
  140. /* If destination and source are not both odd, or both even,
  141.  * we must do a byte copy, rather than a long copy */
  142. movl %edi,%eax
  143. xorl %esi,%eax /* %eax = destination ^ source */
  144. btl $0,%eax
  145. jc bCopyBck5
  146. /* If the buffers are odd-aligned, copy the first 1 - 3 bytes */
  147. movl %esi,%eax
  148. andl $3,%eax /* %eax has 0 - 3 */
  149. je bCopyBck1 /* if long-aligned ? */
  150. movl %eax,%ecx /* %ecx has count */
  151. decl %esi
  152. decl %edi
  153. rep
  154. movsb /* copy the bytes */
  155. incl %esi
  156. incl %edi
  157. subl %eax,%edx /* decrement count by %eax */
  158. bCopyBck1:
  159. /* Since we're copying 4 bytes at a crack, divide count by 4.
  160.  * Keep the remainder in %edx, so we can do those bytes at the 
  161.  * end of the loop. */
  162. movl %edx,%ecx
  163. shrl $2,%ecx /* count /= 4 */
  164. je bCopyBck2 /* do the test first */
  165. addl $-4,%esi
  166. addl $-4,%edi
  167. rep
  168. movsl /* copy long by long */
  169. addl $4,%esi
  170. addl $4,%edi
  171. bCopyBck2:
  172. andl $3,%edx /* remainder in %edx */
  173. /* Copy byte by byte */
  174. bCopyBck5:
  175. movl %edx,%ecx /* Set up %ecx as the loop ctr */
  176. cmpl $0,%ecx
  177. je bCopy6 /* do the test first */
  178. decl %esi
  179. decl %edi
  180. rep
  181. movsb /* copy byte by byte */
  182. bCopy6:
  183. popf
  184. popl %edi
  185. popl %esi
  186. leave
  187. ret
  188. /*******************************************************************************
  189. *
  190. * bcopyBytes - copy one buffer to another a byte at a time
  191. *
  192. * This routine copies the first `nbytes' characters from
  193. * `source' to `destination'.
  194. * It is identical to bcopy except that the copy is always performed
  195. * a byte at a time.  This may be desirable if one of the buffers
  196. * can only be accessed with byte instructions, as in certain byte-wide
  197. * memory-mapped peripherals.
  198. *
  199. * SEE ALSO: bcopy (2)
  200. *
  201. * NOMANUAL - manual entry in bLib (1)
  202. * void bcopyBytes (source, destination, nbytes)
  203. *     char *source;       /* pointer to source buffer      *
  204. *     char *destination;  /* pointer to destination buffer *
  205. *     int nbytes;         /* number of bytes to copy       *
  206. */
  207. .balign 16,0x90
  208. FUNC_LABEL(bcopyBytes)
  209. pushl %ebp
  210. movl %esp,%ebp
  211. pushl %esi
  212. pushl %edi
  213. pushf
  214. /* put src in %esi, dest in %edi, and count in %ecx */
  215. movl ARG1(%ebp),%esi /* source */
  216. movl ARG2(%ebp),%edi /* destination */
  217. movl ARG3(%ebp),%ecx /* count */
  218. cmpl $0,%ecx /* if (count==0) */
  219. je bCopyB1 /*   then exit */
  220. /* Find out if there is an overlap problem.
  221.  * We have to copy backwards if destination lies within source,
  222.  * i.e. ((destination - source) > 0 && < nbytes) */
  223. cld
  224. movl %edi,%eax /* destination */
  225. subl %esi,%eax /* - source */
  226. jle bCopyB0 /* <= 0 means copy forward */
  227. cmpl %ecx,%eax /* compare to nbytes */
  228. jge bCopyB0 /* >= nbytes means copy forward */
  229. addl %ecx,%esi
  230. addl %ecx,%edi
  231. decl %esi
  232. decl %edi
  233. std
  234. /* Copy the whole thing, byte by byte */
  235. bCopyB0:
  236. rep
  237. movsb
  238. bCopyB1:
  239. popf
  240. popl %edi
  241. popl %esi
  242. leave
  243. ret
  244. /*******************************************************************************
  245. *
  246. * bcopyWords - copy one buffer to another a word at a time
  247. *
  248. * This routine copies the first `nwords' words from
  249. * `source' to `destination'.
  250. * It is similar to bcopy except that the copy is always performed
  251. * a word at a time.  This may be desirable if one of the buffers
  252. * can only be accessed with word instructions, as in certain word-wide
  253. * memory-mapped peripherals.  The source and destination must be word-aligned.
  254. *
  255. * SEE ALSO: bcopy (2)
  256. *
  257. * NOMANUAL - manual entry in bLib (1)
  258. * void bcopyWords (source, destination, nwords)
  259. *     char *source;       /* pointer to source buffer      *
  260. *     char *destination;  /* pointer to destination buffer *
  261. *     int nwords;         /* number of words to copy       *
  262. */
  263. .balign 16,0x90
  264. FUNC_LABEL(bcopyWords)
  265. pushl %ebp
  266. movl %esp,%ebp
  267. pushl %esi
  268. pushl %edi
  269. pushf
  270. /* put src in %esi, dest in %edi, and count in %ecx */
  271. movl ARG1(%ebp),%esi /* source */
  272. movl ARG2(%ebp),%edi /* destination */
  273. movl ARG3(%ebp),%ecx /* count */
  274. shll $1,%ecx /* convert count to bytes */
  275. /* Find out if there is an overlap problem.
  276.  * We have to copy backwards if destination lies within source,
  277.  * i.e. ((destination - source) > 0 && < nbytes) */
  278. cld
  279. movl %edi,%eax /* destination */
  280. subl %esi,%eax /* - source */
  281. jle bCopyW0 /* <= 0 means copy forward */
  282. cmpl %ecx,%eax /* compare to nbytes */
  283. jge bCopyW0 /* >= nbytes means copy forward */
  284. addl %ecx,%esi
  285. addl %ecx,%edi
  286. subl $2,%esi
  287. subl $2,%edi
  288. std
  289. /* Copy the whole thing, word by word */
  290. bCopyW0:
  291. shrl $1,%ecx /* convert count to words */
  292. je bCopyW1 /* do the test first */
  293. rep
  294. movsw
  295. bCopyW1:
  296. popf
  297. popl %edi
  298. popl %esi
  299. leave
  300. ret
  301. /*******************************************************************************
  302. *
  303. * bcopyLongs - copy one buffer to another a long at a time
  304. *
  305. * This routine copies the first `nlongs' longs from
  306. * `source' to `destination'.
  307. * It is similar to bcopy except that the copy is always performed
  308. * a long at a time.  This may be desirable if one of the buffers
  309. * can only be accessed with long instructions, as in certain long-wide
  310. * memory-mapped peripherals.  The source and destination must be long-aligned.
  311. *
  312. * SEE ALSO: bcopy (2)
  313. *
  314. * NOMANUAL - manual entry in bLib (1)
  315. * void bcopyLongs (source, destination, nlongs)
  316. *     char *source;       /* pointer to source buffer      *
  317. *     char *destination;  /* pointer to destination buffer *
  318. *     int nlongs;         /* number of longs to copy       *
  319. */
  320. .balign 16,0x90
  321. FUNC_LABEL(bcopyLongs)
  322. pushl %ebp
  323. movl %esp,%ebp
  324. pushl %esi
  325. pushl %edi
  326. pushf
  327. /* put src in %esi, dest in %edi, and count in %ecx */
  328. movl ARG1(%ebp),%esi /* source */
  329. movl ARG2(%ebp),%edi /* destination */
  330. movl ARG3(%ebp),%ecx /* count */
  331. shll $2,%ecx /* convert count to bytes */
  332. /* Find out if there is an overlap problem.
  333.  * We have to copy backwards if destination lies within source,
  334.  * i.e. ((destination - source) > 0 && < nbytes) */
  335. cld
  336. movl %edi,%eax /* destination */
  337. subl %esi,%eax /* - source */
  338. jle bCopyL0 /* <= 0 means copy forward */
  339. cmpl %ecx,%eax /* compare to nbytes */
  340. jge bCopyL0 /* >= nbytes means copy forward */
  341. addl %ecx,%esi
  342. addl %ecx,%edi
  343. subl $4,%esi
  344. subl $4,%edi
  345. std
  346. /* Copy the whole thing, long by long */
  347. bCopyL0:
  348. shrl $2,%ecx /* convert count to longs */
  349. je bCopyL1 /* do the test first */
  350. rep
  351. movsl
  352. bCopyL1:
  353. popf
  354. popl %edi
  355. popl %esi
  356. leave
  357. ret
  358. /*******************************************************************************
  359. *
  360. * bfill - fill buffer with character
  361. *
  362. * This routine fills the first `nbytes' characters of the specified buffer
  363. * with the specified character.
  364. * The fill is optimized by filling 4 bytes at a time if possible,
  365. * (see bfillBytes (2) for filling a byte at a time only).
  366. *
  367. * SEE ALSO: bfillBytes (2)
  368. *
  369. * NOMANUAL - manual entry in bLib (1)
  370. * void bfill (buf, nbytes, ch)
  371. *     char *buf; /* pointer to buffer              *
  372. *     int nbytes; /* number of bytes to fill        *
  373. *     char ch; /* char with which to fill buffer *
  374. */
  375. .balign 16,0x90
  376. FUNC_LABEL(bfill)
  377. pushl %ebp
  378. movl %esp,%ebp
  379. pushl %ebx
  380. pushl %edi
  381. pushf
  382. /* put buf in %edi, nbytes in %edx, and ch in %eax */
  383. movl ARG1(%ebp),%edi /* get buf */
  384. movl ARG2(%ebp),%edx /* nbytes */
  385. movl ARG3(%ebp),%eax /* ch */
  386. /* if length is less than 20, cheaper to do a byte fill */
  387. cld
  388. cmpl $20,%edx /* test count */
  389. jl bFill2 /* do byte fill */
  390. /* Put ch in four bytes of %eax, so we can fill 4 bytes at a crack */
  391. movb %al,%ah /* move ch into 2nd byte of %eax */
  392. movzwl %ax,%ecx /* move low-word of %eax into %ecx */
  393. shll $16,%eax /* shift ch into high-word of %eax */
  394. orl %ecx,%eax /* or ch back into low-word of %eax */
  395. /* If the buffer is odd-aligned, copy the first 1 - 3 byte */
  396. movl %edi,%ebx
  397. andl $3,%ebx
  398. movl %ebx,%ecx
  399. cmpl $0,%ecx /* if long-aligned */
  400. je bFill0 /*   then goto bFill0 */
  401. rep /* fill the 1 - 3 byte */
  402. stosb
  403. subl %ebx,%edx /* decrement count by 1 */
  404. /* Since we're copying 4 bytes at a crack, divide count by 4.
  405.  * Keep the remainder in %edx, so we can do those bytes at the
  406.  * end of the loop. */
  407. bFill0:
  408. movl %edx,%ecx
  409. shrl $2,%ecx /* count /= 4 */
  410. je bFill1 /* do the test first */
  411. rep
  412. stosl
  413. bFill1:
  414. andl $3,%edx /* remainder in %edx */
  415. /* do the extras at the end */
  416. bFill2:
  417. movl %edx,%ecx
  418. cmpl $0,%ecx
  419. je bFill3 /* do the test first */
  420. rep
  421. stosb
  422. bFill3:
  423. popf
  424. popl %edi
  425. popl %ebx
  426. leave
  427. ret
  428. /*******************************************************************************
  429. *
  430. * bfillBytes - fill buffer with character a byte at a time
  431. *
  432. * This routine fills the first `nbytes' characters of the
  433. * specified buffer with the specified character.
  434. * It is identical to bfill (2) except that the fill is always performed
  435. * a byte at a time.  This may be desirable if the buffer
  436. * can only be accessed with byte instructions, as in certain byte-wide
  437. * memory-mapped peripherals.
  438. *
  439. * SEE ALSO: bfill (2)
  440. *
  441. * NOMANUAL - manual entry in bLib (1)
  442. * void bfillBytes (buf, nbytes, ch)
  443. *     char *buf; /* pointer to buffer              *
  444. *     int nbytes; /* number of bytes to fill        *
  445. *     char ch; /* char with which to fill buffer *
  446. */
  447. .balign 16,0x90
  448. FUNC_LABEL(bfillBytes)
  449. pushl %ebp
  450. movl %esp,%ebp
  451. pushl %edi
  452. pushf
  453. /* put buf in %edi, nbytes in %ecx, and ch in %eax */
  454. movl ARG1(%ebp),%edi /* get destination */
  455. movl ARG2(%ebp),%ecx /* count */
  456. movl ARG3(%ebp),%eax /* ch */
  457. cmpl $0,%ecx
  458. je bFillB0 /* do the test first */
  459. /* Copy the whole thing, byte by byte */
  460. cld
  461. rep
  462. stosb
  463. bFillB0:
  464. popf
  465. popl %edi
  466. leave
  467. ret
  468. /*******************************************************************************
  469. *
  470. * bfillWords - fill buffer with specified word(2-byte) a word at a time
  471. *
  472. * This routine fills the first `nwords' characters of the specified buffer
  473. * with the specified word.  The fill is optimized by using the stos 
  474. * instruction.
  475. * It is identical to bfill (2) except that the fill is always performed
  476. * a word at a time.  This may be desirable if the buffer
  477. * can only be accessed with word instructions, as in certain 2byte-wide
  478. * memory-mapped peripherals.
  479. *
  480. * SEE ALSO: bfill (2)
  481. *
  482. * NOMANUAL - manual entry in bLib (1)
  483. *
  484. * void bfillWords (buf, nwords, value)
  485. *     char * buf;               /* pointer to buffer              *
  486. *     int nwords;               /* number of words to fill        *
  487. *     short value;              /* short with which to fill buffer *
  488. *
  489. */
  490.         .balign 16,0x90
  491. FUNC_LABEL(bfillWords)
  492.         pushl   %ebp
  493.         movl    %esp,%ebp
  494.         pushl   %edi
  495.         /* put buf in %edi, nlongs in %ecx, and value in %eax */
  496.         movl    ARG1(%ebp),%edi         /* get buf */
  497.         movl    ARG2(%ebp),%ecx         /* get nwords */
  498.         movl    ARG3(%ebp),%eax         /* get value */
  499.         cld
  500. rep
  501.         stosw                              /* fill it, word by word */
  502.         popl    %edi
  503. leave
  504.         ret
  505. /*******************************************************************************
  506. *
  507. * bfillLongs - fill buffer with specified long(4-byte) a long at a time
  508. *
  509. * This routine fills the first `nlongs' characters of the specified buffer
  510. * with the specified long.  The fill is optimized by using the stos 
  511. * instruction.
  512. * It is identical to bfill (2) except that the fill is always performed
  513. * a long at a time.  This may be desirable if the buffer
  514. * can only be accessed with long instructions, as in certain 4byte-wide
  515. * memory-mapped peripherals.
  516. *
  517. * SEE ALSO: bfill (2)
  518. *
  519. * NOMANUAL - manual entry in bLib (1)
  520. *
  521. * void bfillLongs (buf, nlongs, value)
  522. *     char * buf;               /* pointer to buffer              *
  523. *     int nlongs;               /* number of longs to fill        *
  524. *     long value;               /* long with which to fill buffer *
  525. *
  526. */
  527.         .balign 16,0x90
  528. FUNC_LABEL(bfillLongs)
  529.         pushl   %ebp
  530.         movl    %esp,%ebp
  531.         pushl   %edi
  532.         /* put buf in %edi, nlongs in %ecx, and value in %eax */
  533.         movl    ARG1(%ebp),%edi         /* get buf */
  534.         movl    ARG2(%ebp),%ecx         /* get nlongs */
  535.         movl    ARG3(%ebp),%eax         /* get value */
  536.         cld
  537. rep
  538.         stosl                              /* fill it, long by long */
  539.         popl    %edi
  540.         leave
  541.         ret
  542. #endif /* !PORTABLE */