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