1 import Base 2 import ./types.bend as T 3 4 def xor(a: T.Lane, b: T.Lane) -> T.Lane: 5 match a b: 6 case T.W{al,ah} T.W{bl,bh}: T.W{U32.xor(al,bl),U32.xor(ah,bh)} 7 8 def chi(a: T.Lane, b: T.Lane, c: T.Lane) -> T.Lane: 9 match a b c: 10 case T.W{al,ah} T.W{bl,bh} T.W{cl,ch}: 11 T.W{U32.xor(al,U32.and(U32.xor(bl,4294967295),cl)),U32.xor(ah,U32.and(U32.xor(bh,4294967295),ch))} 12 13 def small(+lo: U32, +hi: U32, +n: Nat) -> T.Lane: 14 T.W{U32.or(U32.shln(lo,n),U32.shrn(hi,Nat.sub(32n,n))),U32.or(U32.shln(hi,n),U32.shrn(lo,Nat.sub(32n,n)))} 15 16 def rotate_if(lo: U32, hi: U32, +n: Nat, b: Bool) -> T.Lane: 17 match b: 18 case True{}: small(lo,hi,n) 19 case False{}: small(hi,lo,Nat.sub(n,32n)) 20 21 def rotate(s: T.Lane, +n: Nat) -> T.Lane: 22 match s n: 23 case T.W{lo,hi} 0n: T.W{lo,hi} 24 case T.W{lo,hi} 32n: T.W{hi,lo} 25 case T.W{lo,hi} n: 26 rotate_if(lo,hi,n,Nat.is_lt(n,32n)) 27 28 29 # Fixed rotations make constant shifts visible to the native compiler. 30 def rol0(a: T.Lane) -> T.Lane: 31 match a: 32 case T.W{+lo,+hi}: 33 T.W{lo,hi} 34 35 def rol1(a: T.Lane) -> T.Lane: 36 match a: 37 case T.W{+lo,+hi}: 38 T.W{U32.or(U32.shln(lo,1n),U32.shrn(hi,31n)),U32.or(U32.shln(hi,1n),U32.shrn(lo,31n))} 39 40 def rol2(a: T.Lane) -> T.Lane: 41 match a: 42 case T.W{+lo,+hi}: 43 T.W{U32.or(U32.shln(lo,2n),U32.shrn(hi,30n)),U32.or(U32.shln(hi,2n),U32.shrn(lo,30n))} 44 45 def rol3(a: T.Lane) -> T.Lane: 46 match a: 47 case T.W{+lo,+hi}: 48 T.W{U32.or(U32.shln(lo,3n),U32.shrn(hi,29n)),U32.or(U32.shln(hi,3n),U32.shrn(lo,29n))} 49 50 def rol6(a: T.Lane) -> T.Lane: 51 match a: 52 case T.W{+lo,+hi}: 53 T.W{U32.or(U32.shln(lo,6n),U32.shrn(hi,26n)),U32.or(U32.shln(hi,6n),U32.shrn(lo,26n))} 54 55 def rol8(a: T.Lane) -> T.Lane: 56 match a: 57 case T.W{+lo,+hi}: 58 T.W{U32.or(U32.shln(lo,8n),U32.shrn(hi,24n)),U32.or(U32.shln(hi,8n),U32.shrn(lo,24n))} 59 60 def rol10(a: T.Lane) -> T.Lane: 61 match a: 62 case T.W{+lo,+hi}: 63 T.W{U32.or(U32.shln(lo,10n),U32.shrn(hi,22n)),U32.or(U32.shln(hi,10n),U32.shrn(lo,22n))} 64 65 def rol14(a: T.Lane) -> T.Lane: 66 match a: 67 case T.W{+lo,+hi}: 68 T.W{U32.or(U32.shln(lo,14n),U32.shrn(hi,18n)),U32.or(U32.shln(hi,14n),U32.shrn(lo,18n))} 69 70 def rol15(a: T.Lane) -> T.Lane: 71 match a: 72 case T.W{+lo,+hi}: 73 T.W{U32.or(U32.shln(lo,15n),U32.shrn(hi,17n)),U32.or(U32.shln(hi,15n),U32.shrn(lo,17n))} 74 75 def rol18(a: T.Lane) -> T.Lane: 76 match a: 77 case T.W{+lo,+hi}: 78 T.W{U32.or(U32.shln(lo,18n),U32.shrn(hi,14n)),U32.or(U32.shln(hi,18n),U32.shrn(lo,14n))} 79 80 def rol20(a: T.Lane) -> T.Lane: 81 match a: 82 case T.W{+lo,+hi}: 83 T.W{U32.or(U32.shln(lo,20n),U32.shrn(hi,12n)),U32.or(U32.shln(hi,20n),U32.shrn(lo,12n))} 84 85 def rol21(a: T.Lane) -> T.Lane: 86 match a: 87 case T.W{+lo,+hi}: 88 T.W{U32.or(U32.shln(lo,21n),U32.shrn(hi,11n)),U32.or(U32.shln(hi,21n),U32.shrn(lo,11n))} 89 90 def rol25(a: T.Lane) -> T.Lane: 91 match a: 92 case T.W{+lo,+hi}: 93 T.W{U32.or(U32.shln(lo,25n),U32.shrn(hi,7n)),U32.or(U32.shln(hi,25n),U32.shrn(lo,7n))} 94 95 def rol27(a: T.Lane) -> T.Lane: 96 match a: 97 case T.W{+lo,+hi}: 98 T.W{U32.or(U32.shln(lo,27n),U32.shrn(hi,5n)),U32.or(U32.shln(hi,27n),U32.shrn(lo,5n))} 99 100 def rol28(a: T.Lane) -> T.Lane: 101 match a: 102 case T.W{+lo,+hi}: 103 T.W{U32.or(U32.shln(lo,28n),U32.shrn(hi,4n)),U32.or(U32.shln(hi,28n),U32.shrn(lo,4n))} 104 105 def rol36(a: T.Lane) -> T.Lane: 106 match a: 107 case T.W{+lo,+hi}: 108 T.W{U32.or(U32.shln(hi,4n),U32.shrn(lo,28n)),U32.or(U32.shln(lo,4n),U32.shrn(hi,28n))} 109 110 def rol39(a: T.Lane) -> T.Lane: 111 match a: 112 case T.W{+lo,+hi}: 113 T.W{U32.or(U32.shln(hi,7n),U32.shrn(lo,25n)),U32.or(U32.shln(lo,7n),U32.shrn(hi,25n))} 114 115 def rol41(a: T.Lane) -> T.Lane: 116 match a: 117 case T.W{+lo,+hi}: 118 T.W{U32.or(U32.shln(hi,9n),U32.shrn(lo,23n)),U32.or(U32.shln(lo,9n),U32.shrn(hi,23n))} 119 120 def rol43(a: T.Lane) -> T.Lane: 121 match a: 122 case T.W{+lo,+hi}: 123 T.W{U32.or(U32.shln(hi,11n),U32.shrn(lo,21n)),U32.or(U32.shln(lo,11n),U32.shrn(hi,21n))} 124 125 def rol44(a: T.Lane) -> T.Lane: 126 match a: 127 case T.W{+lo,+hi}: 128 T.W{U32.or(U32.shln(hi,12n),U32.shrn(lo,20n)),U32.or(U32.shln(lo,12n),U32.shrn(hi,20n))} 129 130 def rol45(a: T.Lane) -> T.Lane: 131 match a: 132 case T.W{+lo,+hi}: 133 T.W{U32.or(U32.shln(hi,13n),U32.shrn(lo,19n)),U32.or(U32.shln(lo,13n),U32.shrn(hi,19n))} 134 135 def rol55(a: T.Lane) -> T.Lane: 136 match a: 137 case T.W{+lo,+hi}: 138 T.W{U32.or(U32.shln(hi,23n),U32.shrn(lo,9n)),U32.or(U32.shln(lo,23n),U32.shrn(hi,9n))} 139 140 def rol56(a: T.Lane) -> T.Lane: 141 match a: 142 case T.W{+lo,+hi}: 143 T.W{U32.or(U32.shln(hi,24n),U32.shrn(lo,8n)),U32.or(U32.shln(lo,24n),U32.shrn(hi,8n))} 144 145 def rol61(a: T.Lane) -> T.Lane: 146 match a: 147 case T.W{+lo,+hi}: 148 T.W{U32.or(U32.shln(hi,29n),U32.shrn(lo,3n)),U32.or(U32.shln(lo,29n),U32.shrn(hi,3n))} 149 150 def rol62(a: T.Lane) -> T.Lane: 151 match a: 152 case T.W{+lo,+hi}: 153 T.W{U32.or(U32.shln(hi,30n),U32.shrn(lo,2n)),U32.or(U32.shln(lo,30n),U32.shrn(hi,2n))} 154