Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.3 KiB

4 years ago
  1. #++
  2. # Copyright 1991, Digital Equipment Corporation
  3. #
  4. # int ots_extzv_vol(char *addr, int position, unsigned size)
  5. #
  6. # Arbitrary unsigned bitfield extraction for volatile cases
  7. #
  8. # Special conventions: No stack space, r0, r16-r18 and r26-r28 ONLY,
  9. # no linkage pointer required.
  10. # (Warning: The auto-loader potentially takes some regs across
  11. # the call if this is being used in a shared lib. environment.)
  12. #
  13. # See also: ots_extv_vol (just uses sra in place of srl in some cases...)
  14. #
  15. # 001 16 Aug 1991 KDG Initial version
  16. #
  17. # 002 4 Sep 1991 KDG Bugfix/improvements
  18. #
  19. # 003 19 May 1992 KDG Changes for common VMS/OSF sources
  20. #
  21. # 004 6 Oct 1992 KDG Initial volatile version (just add longword
  22. # test)
  23. #
  24. # 005 10 Oct 1992 KDG Case-sensitive name
  25. #
  26. # 006 26 Jan 1993 KDG Add underscore
  27. #
  28. # 007 1 Sep 1994 RBG Fix aligned longword case
  29. # check for bit 0 within byte GEM_BUGS #3545
  30. #include "ots_defs.hs"
  31. #
  32. # Totally general field extract - arbitrary run-time field of 0-64 bits
  33. # at an unknown alignment target.
  34. #
  35. # This volatile version always uses exactly LDL for aligned 32 bit field
  36. # extracts, and quadword operations for all other.
  37. #
  38. # Conceptually, this operation takes a 67 bit bit-address, which is the sum
  39. # of a byte-aligned memory address and the bit offset (which is signed).
  40. #
  41. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  42. # | | | | | | | | | | | | | | | | | | | | | | | | | |.|.|.|Q|L|W|B|
  43. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  44. # | | | | | | | | | | | | | | | | | | | | | | | | | | |.|.|.|b|b|b|
  45. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  46. #
  47. # Inputs:
  48. # r16 - input address
  49. # r17 - input bit offset
  50. # r18 - input size
  51. #
  52. # This is based on the code GEM generates when not using an out-of-line
  53. # routine.
  54. #
  55. .globl _OtsFieldExtractUnsignedVolatile
  56. .ent _OtsFieldExtractUnsignedVolatile
  57. _OtsFieldExtractUnsignedVolatile:
  58. .set noat
  59. .set noreorder
  60. .frame sp,0,r26
  61. .prologue 0
  62. sra r17, 3, r27 # get byte part of bit offset (signed!)
  63. ble r18, zero # check for zero size - no memory access
  64. cmpeq r17, 32, r0 # exactly longword size?
  65. addq r16, r27, r16 # add to initial base addr.
  66. and r16, 3, r28 # aligned longword?
  67. cmpult r28, r0, r28 # true if ((addr & 3) == 0) && (size == 32) && ...
  68. and r17, 7, r17 # get bit-in-byte from bit offset
  69. cmpult r17, r28, r28 # ... && (bit_in_byte == 0)
  70. bne r28, longwd # go handle longword case specially
  71. ldq_u r0, (r16) # start load first or only quadword
  72. and r16, 7, r27 # get byte-in-quadword of first bit
  73. s8addq r27, r17, r17 # form the true bit offset in the quadword
  74. addq r17, r18, r27 # get bit offset of bit following field
  75. cmpule r27, 64, r28 # if <=64, field is contained in 1 quadword
  76. beq r28, double # handle double case if not
  77. # common case - fall through, load result hopefully already available
  78. single: negq r27, r27 # <5:0> = bits for right shift
  79. sll r0, r27, r0 # move to high bits
  80. addq r27, r17, r27 # bits for left shift
  81. srl r0, r27, r0 # and shift into final position
  82. ret r31, (r26)
  83. double: ldq_u r28, 8(r16) # load second quadword
  84. srl r0, r27, r0 # move top piece over
  85. negq r27, r27 # get shift bits for piece in 2nd word
  86. sll r28, r27, r28 # move field in 2nd lw to high bits
  87. bis r0, r28, r0 # form final value
  88. negq r18, r27 # <5:0> = bits for right shift
  89. srl r0, r27, r0 # and shift into final position
  90. ret r31, (r26)
  91. zero: mov 0, r0 # zero-sized field extracts return 0
  92. ret r31, (r26)
  93. longwd: ldl r0, (r16) # load sign-extended aligned longword
  94. zapnot r0, 15, r0
  95. ret r31, (r26)
  96. .set at
  97. .set reorder
  98. .end _OtsFieldExtractUnsignedVolatile