github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/crypto/md5/md5block_arm.s (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 // 5 // ARM version of md5block.go 6 7 #include "textflag.h" 8 9 // Register definitions 10 table = 0 // Pointer to MD5 constants table 11 data = 1 // Pointer to data to hash 12 a = 2 // MD5 accumulator 13 b = 3 // MD5 accumulator 14 c = 4 // MD5 accumulator 15 d = 5 // MD5 accumulator 16 c0 = 6 // MD5 constant 17 c1 = 7 // MD5 constant 18 c2 = 8 // MD5 constant 19 // r9, r10 are forbidden 20 // r11 is OK provided you check the assembler that no synthetic instructions use it 21 c3 = 11 // MD5 constant 22 t0 = 12 // temporary 23 t1 = 14 // temporary 24 25 // func block(dig *digest, p []byte) 26 // 0(FP) is *digest 27 // 4(FP) is p.array (struct Slice) 28 // 8(FP) is p.len 29 //12(FP) is p.cap 30 // 31 // Stack frame 32 p_end = -4 // -4(SP) pointer to the end of data 33 p_data = -8 // -8(SP) current data pointer 34 buf = -8-4*16 //-72(SP) 16 words temporary buffer 35 // 3 words at 4..12(R13) for called routine parameters 36 37 TEXT ·block(SB), NOSPLIT, $84-16 38 MOVW p+4(FP), R(data) // pointer to the data 39 MOVW p_len+8(FP), R(t0) // number of bytes 40 ADD R(data), R(t0) 41 MOVW R(t0), p_end(SP) // pointer to end of data 42 43 loop: 44 MOVW R(data), p_data(SP) // Save R(data) 45 AND.S $3, R(data), R(t0) // TST $3, R(data) not working see issue 5921 46 BEQ aligned // aligned detected - skip copy 47 48 // Copy the unaligned source data into the aligned temporary buffer 49 // memove(to=4(R13), from=8(R13), n=12(R13)) - Corrupts all registers 50 MOVW $buf(SP), R(table) // to 51 MOVW $64, R(c0) // n 52 MOVM.IB [R(table),R(data),R(c0)], (R13) 53 BL runtime·memmove(SB) 54 55 // Point to the local aligned copy of the data 56 MOVW $buf(SP), R(data) 57 58 aligned: 59 // Point to the table of constants 60 // A PC relative add would be cheaper than this 61 MOVW $·table(SB), R(table) 62 63 // Load up initial MD5 accumulator 64 MOVW dig+0(FP), R(c0) 65 MOVM.IA (R(c0)), [R(a),R(b),R(c),R(d)] 66 67 // a += (((c^d)&b)^d) + X[index] + const 68 // a = a<<shift | a>>(32-shift) + b 69 #define ROUND1(a, b, c, d, index, shift, const) \ 70 EOR R(c), R(d), R(t0) ; \ 71 AND R(b), R(t0) ; \ 72 EOR R(d), R(t0) ; \ 73 MOVW (index<<2)(R(data)), R(t1) ; \ 74 ADD R(t1), R(t0) ; \ 75 ADD R(const), R(t0) ; \ 76 ADD R(t0), R(a) ; \ 77 ADD R(a)@>(32-shift), R(b), R(a) ; 78 79 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 80 ROUND1(a, b, c, d, 0, 7, c0) 81 ROUND1(d, a, b, c, 1, 12, c1) 82 ROUND1(c, d, a, b, 2, 17, c2) 83 ROUND1(b, c, d, a, 3, 22, c3) 84 85 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 86 ROUND1(a, b, c, d, 4, 7, c0) 87 ROUND1(d, a, b, c, 5, 12, c1) 88 ROUND1(c, d, a, b, 6, 17, c2) 89 ROUND1(b, c, d, a, 7, 22, c3) 90 91 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 92 ROUND1(a, b, c, d, 8, 7, c0) 93 ROUND1(d, a, b, c, 9, 12, c1) 94 ROUND1(c, d, a, b, 10, 17, c2) 95 ROUND1(b, c, d, a, 11, 22, c3) 96 97 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 98 ROUND1(a, b, c, d, 12, 7, c0) 99 ROUND1(d, a, b, c, 13, 12, c1) 100 ROUND1(c, d, a, b, 14, 17, c2) 101 ROUND1(b, c, d, a, 15, 22, c3) 102 103 // a += (((b^c)&d)^c) + X[index] + const 104 // a = a<<shift | a>>(32-shift) + b 105 #define ROUND2(a, b, c, d, index, shift, const) \ 106 EOR R(b), R(c), R(t0) ; \ 107 AND R(d), R(t0) ; \ 108 EOR R(c), R(t0) ; \ 109 MOVW (index<<2)(R(data)), R(t1) ; \ 110 ADD R(t1), R(t0) ; \ 111 ADD R(const), R(t0) ; \ 112 ADD R(t0), R(a) ; \ 113 ADD R(a)@>(32-shift), R(b), R(a) ; 114 115 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 116 ROUND2(a, b, c, d, 1, 5, c0) 117 ROUND2(d, a, b, c, 6, 9, c1) 118 ROUND2(c, d, a, b, 11, 14, c2) 119 ROUND2(b, c, d, a, 0, 20, c3) 120 121 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 122 ROUND2(a, b, c, d, 5, 5, c0) 123 ROUND2(d, a, b, c, 10, 9, c1) 124 ROUND2(c, d, a, b, 15, 14, c2) 125 ROUND2(b, c, d, a, 4, 20, c3) 126 127 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 128 ROUND2(a, b, c, d, 9, 5, c0) 129 ROUND2(d, a, b, c, 14, 9, c1) 130 ROUND2(c, d, a, b, 3, 14, c2) 131 ROUND2(b, c, d, a, 8, 20, c3) 132 133 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 134 ROUND2(a, b, c, d, 13, 5, c0) 135 ROUND2(d, a, b, c, 2, 9, c1) 136 ROUND2(c, d, a, b, 7, 14, c2) 137 ROUND2(b, c, d, a, 12, 20, c3) 138 139 // a += (b^c^d) + X[index] + const 140 // a = a<<shift | a>>(32-shift) + b 141 #define ROUND3(a, b, c, d, index, shift, const) \ 142 EOR R(b), R(c), R(t0) ; \ 143 EOR R(d), R(t0) ; \ 144 MOVW (index<<2)(R(data)), R(t1) ; \ 145 ADD R(t1), R(t0) ; \ 146 ADD R(const), R(t0) ; \ 147 ADD R(t0), R(a) ; \ 148 ADD R(a)@>(32-shift), R(b), R(a) ; 149 150 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 151 ROUND3(a, b, c, d, 5, 4, c0) 152 ROUND3(d, a, b, c, 8, 11, c1) 153 ROUND3(c, d, a, b, 11, 16, c2) 154 ROUND3(b, c, d, a, 14, 23, c3) 155 156 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 157 ROUND3(a, b, c, d, 1, 4, c0) 158 ROUND3(d, a, b, c, 4, 11, c1) 159 ROUND3(c, d, a, b, 7, 16, c2) 160 ROUND3(b, c, d, a, 10, 23, c3) 161 162 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 163 ROUND3(a, b, c, d, 13, 4, c0) 164 ROUND3(d, a, b, c, 0, 11, c1) 165 ROUND3(c, d, a, b, 3, 16, c2) 166 ROUND3(b, c, d, a, 6, 23, c3) 167 168 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 169 ROUND3(a, b, c, d, 9, 4, c0) 170 ROUND3(d, a, b, c, 12, 11, c1) 171 ROUND3(c, d, a, b, 15, 16, c2) 172 ROUND3(b, c, d, a, 2, 23, c3) 173 174 // a += (c^(b|^d)) + X[index] + const 175 // a = a<<shift | a>>(32-shift) + b 176 #define ROUND4(a, b, c, d, index, shift, const) \ 177 MVN R(d), R(t0) ; \ 178 ORR R(b), R(t0) ; \ 179 EOR R(c), R(t0) ; \ 180 MOVW (index<<2)(R(data)), R(t1) ; \ 181 ADD R(t1), R(t0) ; \ 182 ADD R(const), R(t0) ; \ 183 ADD R(t0), R(a) ; \ 184 ADD R(a)@>(32-shift), R(b), R(a) ; 185 186 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 187 ROUND4(a, b, c, d, 0, 6, c0) 188 ROUND4(d, a, b, c, 7, 10, c1) 189 ROUND4(c, d, a, b, 14, 15, c2) 190 ROUND4(b, c, d, a, 5, 21, c3) 191 192 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 193 ROUND4(a, b, c, d, 12, 6, c0) 194 ROUND4(d, a, b, c, 3, 10, c1) 195 ROUND4(c, d, a, b, 10, 15, c2) 196 ROUND4(b, c, d, a, 1, 21, c3) 197 198 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 199 ROUND4(a, b, c, d, 8, 6, c0) 200 ROUND4(d, a, b, c, 15, 10, c1) 201 ROUND4(c, d, a, b, 6, 15, c2) 202 ROUND4(b, c, d, a, 13, 21, c3) 203 204 MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)] 205 ROUND4(a, b, c, d, 4, 6, c0) 206 ROUND4(d, a, b, c, 11, 10, c1) 207 ROUND4(c, d, a, b, 2, 15, c2) 208 ROUND4(b, c, d, a, 9, 21, c3) 209 210 MOVW dig+0(FP), R(t0) 211 MOVM.IA (R(t0)), [R(c0),R(c1),R(c2),R(c3)] 212 213 ADD R(c0), R(a) 214 ADD R(c1), R(b) 215 ADD R(c2), R(c) 216 ADD R(c3), R(d) 217 218 MOVM.IA [R(a),R(b),R(c),R(d)], (R(t0)) 219 220 MOVW p_data(SP), R(data) 221 MOVW p_end(SP), R(t0) 222 ADD $64, R(data) 223 CMP R(t0), R(data) 224 BLO loop 225 226 RET 227 228 // MD5 constants table 229 230 // Round 1 231 DATA ·table+0x00(SB)/4, $0xd76aa478 232 DATA ·table+0x04(SB)/4, $0xe8c7b756 233 DATA ·table+0x08(SB)/4, $0x242070db 234 DATA ·table+0x0c(SB)/4, $0xc1bdceee 235 DATA ·table+0x10(SB)/4, $0xf57c0faf 236 DATA ·table+0x14(SB)/4, $0x4787c62a 237 DATA ·table+0x18(SB)/4, $0xa8304613 238 DATA ·table+0x1c(SB)/4, $0xfd469501 239 DATA ·table+0x20(SB)/4, $0x698098d8 240 DATA ·table+0x24(SB)/4, $0x8b44f7af 241 DATA ·table+0x28(SB)/4, $0xffff5bb1 242 DATA ·table+0x2c(SB)/4, $0x895cd7be 243 DATA ·table+0x30(SB)/4, $0x6b901122 244 DATA ·table+0x34(SB)/4, $0xfd987193 245 DATA ·table+0x38(SB)/4, $0xa679438e 246 DATA ·table+0x3c(SB)/4, $0x49b40821 247 // Round 2 248 DATA ·table+0x40(SB)/4, $0xf61e2562 249 DATA ·table+0x44(SB)/4, $0xc040b340 250 DATA ·table+0x48(SB)/4, $0x265e5a51 251 DATA ·table+0x4c(SB)/4, $0xe9b6c7aa 252 DATA ·table+0x50(SB)/4, $0xd62f105d 253 DATA ·table+0x54(SB)/4, $0x02441453 254 DATA ·table+0x58(SB)/4, $0xd8a1e681 255 DATA ·table+0x5c(SB)/4, $0xe7d3fbc8 256 DATA ·table+0x60(SB)/4, $0x21e1cde6 257 DATA ·table+0x64(SB)/4, $0xc33707d6 258 DATA ·table+0x68(SB)/4, $0xf4d50d87 259 DATA ·table+0x6c(SB)/4, $0x455a14ed 260 DATA ·table+0x70(SB)/4, $0xa9e3e905 261 DATA ·table+0x74(SB)/4, $0xfcefa3f8 262 DATA ·table+0x78(SB)/4, $0x676f02d9 263 DATA ·table+0x7c(SB)/4, $0x8d2a4c8a 264 // Round 3 265 DATA ·table+0x80(SB)/4, $0xfffa3942 266 DATA ·table+0x84(SB)/4, $0x8771f681 267 DATA ·table+0x88(SB)/4, $0x6d9d6122 268 DATA ·table+0x8c(SB)/4, $0xfde5380c 269 DATA ·table+0x90(SB)/4, $0xa4beea44 270 DATA ·table+0x94(SB)/4, $0x4bdecfa9 271 DATA ·table+0x98(SB)/4, $0xf6bb4b60 272 DATA ·table+0x9c(SB)/4, $0xbebfbc70 273 DATA ·table+0xa0(SB)/4, $0x289b7ec6 274 DATA ·table+0xa4(SB)/4, $0xeaa127fa 275 DATA ·table+0xa8(SB)/4, $0xd4ef3085 276 DATA ·table+0xac(SB)/4, $0x04881d05 277 DATA ·table+0xb0(SB)/4, $0xd9d4d039 278 DATA ·table+0xb4(SB)/4, $0xe6db99e5 279 DATA ·table+0xb8(SB)/4, $0x1fa27cf8 280 DATA ·table+0xbc(SB)/4, $0xc4ac5665 281 // Round 4 282 DATA ·table+0xc0(SB)/4, $0xf4292244 283 DATA ·table+0xc4(SB)/4, $0x432aff97 284 DATA ·table+0xc8(SB)/4, $0xab9423a7 285 DATA ·table+0xcc(SB)/4, $0xfc93a039 286 DATA ·table+0xd0(SB)/4, $0x655b59c3 287 DATA ·table+0xd4(SB)/4, $0x8f0ccc92 288 DATA ·table+0xd8(SB)/4, $0xffeff47d 289 DATA ·table+0xdc(SB)/4, $0x85845dd1 290 DATA ·table+0xe0(SB)/4, $0x6fa87e4f 291 DATA ·table+0xe4(SB)/4, $0xfe2ce6e0 292 DATA ·table+0xe8(SB)/4, $0xa3014314 293 DATA ·table+0xec(SB)/4, $0x4e0811a1 294 DATA ·table+0xf0(SB)/4, $0xf7537e82 295 DATA ·table+0xf4(SB)/4, $0xbd3af235 296 DATA ·table+0xf8(SB)/4, $0x2ad7d2bb 297 DATA ·table+0xfc(SB)/4, $0xeb86d391 298 // Global definition 299 GLOBL ·table(SB),8,$256