bpf_jit.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * BPF Jit compiler for s390, help functions.
  3. *
  4. * Copyright IBM Corp. 2012
  5. *
  6. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  7. */
  8. #include <linux/linkage.h>
  9. /*
  10. * Calling convention:
  11. * registers %r2, %r6-%r8, %r10-%r11, %r13, %r15 are call saved
  12. * %r2: skb pointer
  13. * %r3: offset parameter
  14. * %r5: BPF A accumulator
  15. * %r8: return address
  16. * %r9: save register for skb pointer
  17. * %r10: skb->data
  18. * %r11: skb->len - skb->data_len (headlen)
  19. * %r12: BPF X accumulator
  20. *
  21. * skb_copy_bits takes 4 parameters:
  22. * %r2 = skb pointer
  23. * %r3 = offset into skb data
  24. * %r4 = pointer to temp buffer
  25. * %r5 = length to copy
  26. */
  27. #define SKBDATA %r8
  28. /* A = *(u32 *) (skb->data+K+X) */
  29. ENTRY(sk_load_word_ind)
  30. ar %r3,%r12 # offset += X
  31. bmr %r8 # < 0 -> return with cc
  32. /* A = *(u32 *) (skb->data+K) */
  33. ENTRY(sk_load_word)
  34. llgfr %r1,%r3 # extend offset
  35. ahi %r3,4 # offset + 4
  36. clr %r11,%r3 # hlen <= offset + 4 ?
  37. jl sk_load_word_slow
  38. l %r5,0(%r1,%r10) # get word from skb
  39. xr %r1,%r1 # set cc to zero
  40. br %r8
  41. sk_load_word_slow:
  42. lgr %r9,%r2 # save %r2
  43. lgr %r3,%r1 # offset
  44. la %r4,160(%r15) # pointer to temp buffer
  45. lghi %r5,4 # 4 bytes
  46. brasl %r14,skb_copy_bits # get data from skb
  47. l %r5,160(%r15) # load result from temp buffer
  48. ltgr %r2,%r2 # set cc to (%r2 != 0)
  49. lgr %r2,%r9 # restore %r2
  50. br %r8
  51. /* A = *(u16 *) (skb->data+K+X) */
  52. ENTRY(sk_load_half_ind)
  53. ar %r3,%r12 # offset += X
  54. bmr %r8 # < 0 -> return with cc
  55. /* A = *(u16 *) (skb->data+K) */
  56. ENTRY(sk_load_half)
  57. llgfr %r1,%r3 # extend offset
  58. ahi %r3,2 # offset + 2
  59. clr %r11,%r3 # hlen <= offset + 2 ?
  60. jl sk_load_half_slow
  61. llgh %r5,0(%r1,%r10) # get half from skb
  62. xr %r1,%r1 # set cc to zero
  63. br %r8
  64. sk_load_half_slow:
  65. lgr %r9,%r2 # save %r2
  66. lgr %r3,%r1 # offset
  67. la %r4,162(%r15) # pointer to temp buffer
  68. lghi %r5,2 # 2 bytes
  69. brasl %r14,skb_copy_bits # get data from skb
  70. xc 160(2,%r15),160(%r15)
  71. l %r5,160(%r15) # load result from temp buffer
  72. ltgr %r2,%r2 # set cc to (%r2 != 0)
  73. lgr %r2,%r9 # restore %r2
  74. br %r8
  75. /* A = *(u8 *) (skb->data+K+X) */
  76. ENTRY(sk_load_byte_ind)
  77. ar %r3,%r12 # offset += X
  78. bmr %r8 # < 0 -> return with cc
  79. /* A = *(u8 *) (skb->data+K) */
  80. ENTRY(sk_load_byte)
  81. llgfr %r1,%r3 # extend offset
  82. clr %r11,%r3 # hlen < offset ?
  83. jle sk_load_byte_slow
  84. lhi %r5,0
  85. ic %r5,0(%r1,%r10) # get byte from skb
  86. xr %r1,%r1 # set cc to zero
  87. br %r8
  88. sk_load_byte_slow:
  89. lgr %r9,%r2 # save %r2
  90. lgr %r3,%r1 # offset
  91. la %r4,163(%r15) # pointer to temp buffer
  92. lghi %r5,1 # 1 byte
  93. brasl %r14,skb_copy_bits # get data from skb
  94. xc 160(3,%r15),160(%r15)
  95. l %r5,160(%r15) # load result from temp buffer
  96. ltgr %r2,%r2 # set cc to (%r2 != 0)
  97. lgr %r2,%r9 # restore %r2
  98. br %r8
  99. /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
  100. ENTRY(sk_load_byte_msh)
  101. llgfr %r1,%r3 # extend offset
  102. clr %r11,%r3 # hlen < offset ?
  103. jle sk_load_byte_msh_slow
  104. lhi %r12,0
  105. ic %r12,0(%r1,%r10) # get byte from skb
  106. nill %r12,0x0f
  107. sll %r12,2
  108. xr %r1,%r1 # set cc to zero
  109. br %r8
  110. sk_load_byte_msh_slow:
  111. lgr %r9,%r2 # save %r2
  112. lgr %r3,%r1 # offset
  113. la %r4,163(%r15) # pointer to temp buffer
  114. lghi %r5,1 # 1 byte
  115. brasl %r14,skb_copy_bits # get data from skb
  116. xc 160(3,%r15),160(%r15)
  117. l %r12,160(%r15) # load result from temp buffer
  118. nill %r12,0x0f
  119. sll %r12,2
  120. ltgr %r2,%r2 # set cc to (%r2 != 0)
  121. lgr %r2,%r9 # restore %r2
  122. br %r8