strings.inc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2000 by Jonas Maebe, member of the
  4. Free Pascal development team
  5. Processor dependent part of strings.pp, that can be shared with
  6. sysutils unit.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$if defined(FPC_MM_TINY)}
  14. {$define FPC_X86_CODE_NEAR}
  15. {$define FPC_X86_DATA_NEAR}
  16. {$elseif defined(FPC_MM_SMALL)}
  17. {$define FPC_X86_CODE_NEAR}
  18. {$define FPC_X86_DATA_NEAR}
  19. {$elseif defined(FPC_MM_MEDIUM)}
  20. {$define FPC_X86_CODE_FAR}
  21. {$define FPC_X86_DATA_NEAR}
  22. {$elseif defined(FPC_MM_COMPACT)}
  23. {$define FPC_X86_CODE_NEAR}
  24. {$define FPC_X86_DATA_FAR}
  25. {$elseif defined(FPC_MM_LARGE)}
  26. {$define FPC_X86_CODE_FAR}
  27. {$define FPC_X86_DATA_FAR}
  28. {$elseif defined(FPC_MM_HUGE)}
  29. {$define FPC_X86_CODE_FAR}
  30. {$define FPC_X86_DATA_HUGE}
  31. {$else}
  32. {$fatal No memory model defined}
  33. {$endif}
  34. {$ifndef FPC_UNIT_HAS_STREND}
  35. {$define FPC_UNIT_HAS_STREND}
  36. function strend(p : pchar) : pchar;assembler;nostackframe;
  37. const
  38. { used for an offset fixup for accessing the proc parameters in asm routines
  39. that use nostackframe. We can't use the parameter name directly, because
  40. i8086 doesn't support sp relative addressing. }
  41. {$ifdef FPC_X86_CODE_FAR}
  42. extra_param_offset = 2;
  43. {$else FPC_X86_CODE_FAR}
  44. extra_param_offset = 0;
  45. {$endif FPC_X86_CODE_FAR}
  46. asm
  47. mov bx, sp
  48. xor ax, ax
  49. {$ifdef FPC_X86_DATA_NEAR}
  50. mov dx, ds
  51. mov es, dx
  52. mov di, ss:[bx + 2 + extra_param_offset] // @p
  53. or di, di
  54. jz @@LStrEndNil
  55. {$else FPC_X86_DATA_NEAR}
  56. les di, ss:[bx + 2 + extra_param_offset] // @p
  57. mov dx, es
  58. mov cx, dx
  59. or cx, di
  60. jz @@LStrEndNil
  61. {$endif FPC_X86_DATA_NEAR}
  62. {$ifdef FPC_ENABLED_CLD}
  63. cld
  64. {$endif FPC_ENABLED_CLD}
  65. mov cx, 0ffffh
  66. repne scasb
  67. mov ax, di
  68. dec ax
  69. @@LStrEndNil:
  70. end;
  71. {$endif FPC_UNIT_HAS_STREND}
  72. {$ifndef FPC_UNIT_HAS_STRUPPER}
  73. {$define FPC_UNIT_HAS_STRUPPER}
  74. function strupper(p : pchar) : pchar;assembler;nostackframe;
  75. const
  76. {$ifdef FPC_X86_CODE_FAR}
  77. extra_param_offset = 2;
  78. {$else FPC_X86_CODE_FAR}
  79. extra_param_offset = 0;
  80. {$endif FPC_X86_CODE_FAR}
  81. asm
  82. mov bx, sp
  83. xor ax, ax
  84. {$ifdef FPC_X86_DATA_NEAR}
  85. mov dx, ds
  86. mov es, dx
  87. mov di, ss:[bx + 2 + extra_param_offset] // @p
  88. or di, di
  89. jz @@LStrUpperNil
  90. {$else FPC_X86_DATA_NEAR}
  91. les di, ss:[bx + 2 + extra_param_offset] // @p
  92. mov dx, es
  93. mov cx, dx
  94. or cx, di
  95. jz @@LStrUpperNil
  96. mov cx, ds
  97. mov ds, dx
  98. {$endif FPC_X86_DATA_NEAR}
  99. mov si, di
  100. mov bx, di
  101. {$ifdef FPC_ENABLED_CLD}
  102. cld
  103. {$endif FPC_ENABLED_CLD}
  104. @@LSTRUPPER1:
  105. lodsb
  106. cmp al, 'a'
  107. jb @@LSTRUPPER3
  108. cmp al, 'z'
  109. ja @@LSTRUPPER3
  110. sub al, 20h
  111. @@LSTRUPPER3:
  112. stosb
  113. or al, al
  114. jnz @@LSTRUPPER1
  115. xchg ax, bx { 1 byte shorter than a mov }
  116. {$ifndef FPC_X86_DATA_NEAR}
  117. mov ds, cx
  118. {$endif not FPC_X86_DATA_NEAR}
  119. @@LStrUpperNil:
  120. end;
  121. {$endif FPC_UNIT_HAS_STRUPPER}
  122. {$ifndef FPC_UNIT_HAS_STRLOWER}
  123. {$define FPC_UNIT_HAS_STRLOWER}
  124. function strlower(p : pchar) : pchar;assembler;nostackframe;
  125. const
  126. {$ifdef FPC_X86_CODE_FAR}
  127. extra_param_offset = 2;
  128. {$else FPC_X86_CODE_FAR}
  129. extra_param_offset = 0;
  130. {$endif FPC_X86_CODE_FAR}
  131. asm
  132. mov bx, sp
  133. xor ax, ax
  134. {$ifdef FPC_X86_DATA_NEAR}
  135. mov dx, ds
  136. mov es, dx
  137. mov di, ss:[bx + 2 + extra_param_offset] // @p
  138. or di, di
  139. jz @@LStrLowerNil
  140. {$else FPC_X86_DATA_NEAR}
  141. les di, ss:[bx + 2 + extra_param_offset] // @p
  142. mov dx, es
  143. mov cx, dx
  144. or cx, di
  145. jz @@LStrLowerNil
  146. mov cx, ds
  147. mov ds, dx
  148. {$endif FPC_X86_DATA_NEAR}
  149. mov si, di
  150. mov bx, di
  151. {$ifdef FPC_ENABLED_CLD}
  152. cld
  153. {$endif FPC_ENABLED_CLD}
  154. @@LSTRLOWER1:
  155. lodsb
  156. cmp al, 'A'
  157. jb @@LSTRLOWER3
  158. cmp al, 'Z'
  159. ja @@LSTRLOWER3
  160. add al, 20h
  161. @@LSTRLOWER3:
  162. stosb
  163. or al, al
  164. jnz @@LSTRLOWER1
  165. xchg ax, bx { 1 byte shorter than a mov }
  166. {$ifndef FPC_X86_DATA_NEAR}
  167. mov ds, cx
  168. {$endif not FPC_X86_DATA_NEAR}
  169. @@LStrLowerNil:
  170. end;
  171. {$endif FPC_UNIT_HAS_STRLOWER}