bpf_jit.S 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 = length to copy
  25. * %r5 = pointer to temp buffer
  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. lhi %r4,4 # 4 bytes
  44. la %r5,160(%r15) # pointer to temp buffer
  45. brasl %r14,skb_copy_bits # get data from skb
  46. l %r5,160(%r15) # load result from temp buffer
  47. ltgr %r2,%r2 # set cc to (%r2 != 0)
  48. lgr %r2,%r9 # restore %r2
  49. br %r8
  50. /* A = *(u16 *) (skb->data+K+X) */
  51. ENTRY(sk_load_half_ind)
  52. ar %r3,%r12 # offset += X
  53. bmr %r8 # < 0 -> return with cc
  54. /* A = *(u16 *) (skb->data+K) */
  55. ENTRY(sk_load_half)
  56. llgfr %r1,%r3 # extend offset
  57. ahi %r3,2 # offset + 2
  58. clr %r11,%r3 # hlen <= offset + 2 ?
  59. jl sk_load_half_slow
  60. llgh %r5,0(%r1,%r10) # get half from skb
  61. xr %r1,%r1 # set cc to zero
  62. br %r8
  63. sk_load_half_slow:
  64. lgr %r9,%r2 # save %r2
  65. lhi %r4,2 # 2 bytes
  66. la %r5,162(%r15) # pointer to temp buffer
  67. brasl %r14,skb_copy_bits # get data from skb
  68. xc 160(2,%r15),160(%r15)
  69. l %r5,160(%r15) # load result from temp buffer
  70. ltgr %r2,%r2 # set cc to (%r2 != 0)
  71. lgr %r2,%r9 # restore %r2
  72. br %r8
  73. /* A = *(u8 *) (skb->data+K+X) */
  74. ENTRY(sk_load_byte_ind)
  75. ar %r3,%r12 # offset += X
  76. bmr %r8 # < 0 -> return with cc
  77. /* A = *(u8 *) (skb->data+K) */
  78. ENTRY(sk_load_byte)
  79. llgfr %r1,%r3 # extend offset
  80. clr %r11,%r3 # hlen < offset ?
  81. jle sk_load_byte_slow
  82. lhi %r5,0
  83. ic %r5,0(%r1,%r10) # get byte from skb
  84. xr %r1,%r1 # set cc to zero
  85. br %r8
  86. sk_load_byte_slow:
  87. lgr %r9,%r2 # save %r2
  88. lhi %r4,1 # 1 bytes
  89. la %r5,163(%r15) # pointer to temp buffer
  90. brasl %r14,skb_copy_bits # get data from skb
  91. xc 160(3,%r15),160(%r15)
  92. l %r5,160(%r15) # load result from temp buffer
  93. ltgr %r2,%r2 # set cc to (%r2 != 0)
  94. lgr %r2,%r9 # restore %r2
  95. br %r8
  96. /* A = (*(u8 *)(skb->data+K) & 0xf) << 2 */
  97. ENTRY(sk_load_byte_msh)
  98. llgfr %r1,%r3 # extend offset
  99. clr %r11,%r3 # hlen < offset ?
  100. jle sk_load_byte_slow
  101. lhi %r12,0
  102. ic %r12,0(%r1,%r10) # get byte from skb
  103. nill %r12,0x0f
  104. sll %r12,2
  105. xr %r1,%r1 # set cc to zero
  106. br %r8
  107. sk_load_byte_msh_slow:
  108. lgr %r9,%r2 # save %r2
  109. lhi %r4,2 # 2 bytes
  110. la %r5,162(%r15) # pointer to temp buffer
  111. brasl %r14,skb_copy_bits # get data from skb
  112. xc 160(3,%r15),160(%r15)
  113. l %r12,160(%r15) # load result from temp buffer
  114. nill %r12,0x0f
  115. sll %r12,2
  116. ltgr %r2,%r2 # set cc to (%r2 != 0)
  117. lgr %r2,%r9 # restore %r2
  118. br %r8