1160abee0Sda73024#!/usr/bin/perl -w 28de5c4f4SDan OpenSolaris Anderson# 38de5c4f4SDan OpenSolaris Anderson# MD5 optimized for AMD64. 48de5c4f4SDan OpenSolaris Anderson# 58de5c4f4SDan OpenSolaris Anderson# Author: Marc Bevand <bevand_m (at) epita.fr> 68de5c4f4SDan OpenSolaris Anderson# Licence: I hereby disclaim the copyright on this code and place it 78de5c4f4SDan OpenSolaris Anderson# in the public domain. 88de5c4f4SDan OpenSolaris Anderson# 98de5c4f4SDan OpenSolaris Anderson 108de5c4f4SDan OpenSolaris Anderson# 118de5c4f4SDan OpenSolaris Anderson# The following is Marc Bevand's MD5 implementation optimized for 128de5c4f4SDan OpenSolaris Anderson# AMD64. It has been lifted intact, except for changing the comment 138de5c4f4SDan OpenSolaris Anderson# character and adding comments. 148de5c4f4SDan OpenSolaris Anderson# 158de5c4f4SDan OpenSolaris Anderson# typedef struct { 168de5c4f4SDan OpenSolaris Anderson# uint32_t state[4]; /* state (ABCD) */ 178de5c4f4SDan OpenSolaris Anderson# uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ 188de5c4f4SDan OpenSolaris Anderson# union { 198de5c4f4SDan OpenSolaris Anderson# uint8_t buf8[64]; /* undigested input */ 208de5c4f4SDan OpenSolaris Anderson# uint32_t buf32[16]; /* realigned input */ 218de5c4f4SDan OpenSolaris Anderson# } buf_un; 228de5c4f4SDan OpenSolaris Anderson# } MD5_CTX; 238de5c4f4SDan OpenSolaris Anderson# 248de5c4f4SDan OpenSolaris Anderson# void md5_block_asm_host_order(MD5_CTX *ctx, const void *inpp, 258de5c4f4SDan OpenSolaris Anderson# unsigned int input_length_in_blocks); 268de5c4f4SDan OpenSolaris Anderson# 278de5c4f4SDan OpenSolaris Anderson# Registers used: 288de5c4f4SDan OpenSolaris Anderson# rax A r8 old A 298de5c4f4SDan OpenSolaris Anderson# rbx B r9 old B 308de5c4f4SDan OpenSolaris Anderson# rcx C r10 tmp 318de5c4f4SDan OpenSolaris Anderson# rdx D r11 tmp 328de5c4f4SDan OpenSolaris Anderson# rsi ptr r12 tmp 338de5c4f4SDan OpenSolaris Anderson# rdi end r13 - 348de5c4f4SDan OpenSolaris Anderson# rbp - r14 old C 358de5c4f4SDan OpenSolaris Anderson# rsp stack r15 old D 368de5c4f4SDan OpenSolaris Anderson# 378de5c4f4SDan OpenSolaris Anderson 38160abee0Sda73024use strict; 398de5c4f4SDan OpenSolaris Andersonmy $code; 40160abee0Sda73024 41160abee0Sda73024 42160abee0Sda73024# round1_step() does: 43160abee0Sda73024# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) 44160abee0Sda73024# %r10d = X[k_next] 45160abee0Sda73024# %r11d = z' (copy of z for the next step) 46160abee0Sda73024# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC) 47160abee0Sda73024sub round1_step 48160abee0Sda73024{ 49160abee0Sda73024 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 50160abee0Sda73024 $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); 51160abee0Sda73024 $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); 52*9b793925STheo Schlossnagle $T_i = sprintf("-0x%08x", (0xffffffff ^ hex($T_i))+1) 53*9b793925STheo Schlossnagle if (hex($T_i) >= 0x80000000); 548de5c4f4SDan OpenSolaris Anderson 55160abee0Sda73024 $code .= <<EOF; 568de5c4f4SDan OpenSolaris Anderson xor $y, %r11d /* y ^ ... */ 57*9b793925STheo Schlossnagle lea $T_i($dst,%r10d),$dst /* Const + dst + ... r1 */ 58160abee0Sda73024 and $x, %r11d /* x & ... */ 59160abee0Sda73024 xor $z, %r11d /* z ^ ... */ 60160abee0Sda73024 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ 61160abee0Sda73024 add %r11d, $dst /* dst += ... */ 62160abee0Sda73024 rol \$$s, $dst /* dst <<< s */ 63160abee0Sda73024 mov $y, %r11d /* (NEXT STEP) z' = $y */ 64160abee0Sda73024 add $x, $dst /* dst += x */ 65160abee0Sda73024EOF 66160abee0Sda73024} 67160abee0Sda73024 68160abee0Sda73024# round2_step() does: 69160abee0Sda73024# dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s) 70160abee0Sda73024# %r10d = X[k_next] 71160abee0Sda73024# %r11d = z' (copy of z for the next step) 72160abee0Sda73024# %r12d = z' (copy of z for the next step) 73160abee0Sda73024# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC) 74160abee0Sda73024sub round2_step 75160abee0Sda73024{ 76160abee0Sda73024 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 77160abee0Sda73024 $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1); 78160abee0Sda73024 $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); 79160abee0Sda73024 $code .= " mov %edx, %r12d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); 80*9b793925STheo Schlossnagle $T_i = sprintf("-0x%08x", (0xffffffff ^ hex($T_i))+1) 81*9b793925STheo Schlossnagle if (hex($T_i) >= 0x80000000); 828de5c4f4SDan OpenSolaris Anderson 83160abee0Sda73024 $code .= <<EOF; 848de5c4f4SDan OpenSolaris Anderson not %r11d /* not z */ 85*9b793925STheo Schlossnagle lea $T_i($dst,%r10d),$dst /* Const + dst + ... r2 */ 86160abee0Sda73024 and $x, %r12d /* x & z */ 87160abee0Sda73024 and $y, %r11d /* y & (not z) */ 88160abee0Sda73024 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ 89160abee0Sda73024 or %r11d, %r12d /* (y & (not z)) | (x & z) */ 90160abee0Sda73024 mov $y, %r11d /* (NEXT STEP) z' = $y */ 91160abee0Sda73024 add %r12d, $dst /* dst += ... */ 92160abee0Sda73024 mov $y, %r12d /* (NEXT STEP) z' = $y */ 93160abee0Sda73024 rol \$$s, $dst /* dst <<< s */ 94160abee0Sda73024 add $x, $dst /* dst += x */ 95160abee0Sda73024EOF 96160abee0Sda73024} 97160abee0Sda73024 98160abee0Sda73024# round3_step() does: 99160abee0Sda73024# dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s) 100160abee0Sda73024# %r10d = X[k_next] 101160abee0Sda73024# %r11d = y' (copy of y for the next step) 102160abee0Sda73024# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC) 103160abee0Sda73024sub round3_step 104160abee0Sda73024{ 105160abee0Sda73024 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 106160abee0Sda73024 $code .= " mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */\n" if ($pos == -1); 107160abee0Sda73024 $code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1); 108*9b793925STheo Schlossnagle $T_i = sprintf("-0x%08x", (0xffffffff ^ hex($T_i))+1) 109*9b793925STheo Schlossnagle if (hex($T_i) >= 0x80000000); 1108de5c4f4SDan OpenSolaris Anderson 111160abee0Sda73024 $code .= <<EOF; 112*9b793925STheo Schlossnagle lea $T_i($dst,%r10d),$dst /* Const + dst + ... r3 */ 113160abee0Sda73024 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ 114160abee0Sda73024 xor $z, %r11d /* z ^ ... */ 115160abee0Sda73024 xor $x, %r11d /* x ^ ... */ 116160abee0Sda73024 add %r11d, $dst /* dst += ... */ 117160abee0Sda73024 rol \$$s, $dst /* dst <<< s */ 118160abee0Sda73024 mov $x, %r11d /* (NEXT STEP) y' = $x */ 119160abee0Sda73024 add $x, $dst /* dst += x */ 120160abee0Sda73024EOF 121160abee0Sda73024} 122160abee0Sda73024 123160abee0Sda73024# round4_step() does: 124160abee0Sda73024# dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s) 125160abee0Sda73024# %r10d = X[k_next] 126160abee0Sda73024# %r11d = not z' (copy of not z for the next step) 127160abee0Sda73024# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC) 128160abee0Sda73024sub round4_step 129160abee0Sda73024{ 130160abee0Sda73024 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 131160abee0Sda73024 $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); 132160abee0Sda73024 $code .= " mov \$0xffffffff, %r11d\n" if ($pos == -1); 133160abee0Sda73024 $code .= " xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/\n" 134160abee0Sda73024 if ($pos == -1); 135*9b793925STheo Schlossnagle $T_i = sprintf("-0x%08x", (0xffffffff ^ hex($T_i))+1) 136*9b793925STheo Schlossnagle if (hex($T_i) >= 0x80000000); 1378de5c4f4SDan OpenSolaris Anderson 138160abee0Sda73024 $code .= <<EOF; 139*9b793925STheo Schlossnagle lea $T_i($dst,%r10d),$dst /* Const + dst + ... r4 */ 140160abee0Sda73024 or $x, %r11d /* x | ... */ 141160abee0Sda73024 xor $y, %r11d /* y ^ ... */ 142160abee0Sda73024 add %r11d, $dst /* dst += ... */ 143160abee0Sda73024 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ 144160abee0Sda73024 mov \$0xffffffff, %r11d 145160abee0Sda73024 rol \$$s, $dst /* dst <<< s */ 146160abee0Sda73024 xor $y, %r11d /* (NEXT STEP) not z' = not $y */ 147160abee0Sda73024 add $x, $dst /* dst += x */ 148160abee0Sda73024EOF 149160abee0Sda73024} 150160abee0Sda73024 151160abee0Sda73024 152160abee0Sda73024# 153160abee0Sda73024# Execution begins here. 154160abee0Sda73024# 155160abee0Sda73024 156160abee0Sda73024my $output = shift; 157160abee0Sda73024open STDOUT,">$output" or die "can't open $output: $!"; 158160abee0Sda73024 159160abee0Sda73024$code .= <<EOF; 1608de5c4f4SDan OpenSolaris Anderson#if defined(lint) || defined(__lint) 1618de5c4f4SDan OpenSolaris Anderson#include <sys/md5.h> 162160abee0Sda73024 1638de5c4f4SDan OpenSolaris Anderson/* ARGSUSED */ 1648de5c4f4SDan OpenSolaris Andersonvoid md5_block_asm_host_order(MD5_CTX *ctx, const void *inpp, 1658de5c4f4SDan OpenSolaris Anderson unsigned int input_length_in_blocks) 1668de5c4f4SDan OpenSolaris Anderson{ 1678de5c4f4SDan OpenSolaris Anderson} 1688de5c4f4SDan OpenSolaris Anderson 1698de5c4f4SDan OpenSolaris Anderson#else 170160abee0Sda73024#include <sys/asm_linkage.h> 171160abee0Sda73024 172160abee0Sda73024 ENTRY_NP(md5_block_asm_host_order) 173160abee0Sda73024 push %rbp 174160abee0Sda73024 push %rbx 175160abee0Sda73024 push %r12 176160abee0Sda73024 push %r13 177160abee0Sda73024 push %r14 178160abee0Sda73024 push %r15 179160abee0Sda73024 180160abee0Sda73024 / rdi = arg #1 (ctx, MD5_CTX pointer) 181160abee0Sda73024 / rsi = arg #2 (ptr, data pointer) 182160abee0Sda73024 / rdx = arg #3 (nbr, number of 64-byte blocks to process) 183160abee0Sda73024 mov %rdi, %rbp / rbp = ctx 184160abee0Sda73024 shl \$6, %rdx / rdx = nbr in bytes 185160abee0Sda73024 lea (%rsi,%rdx), %rdi / rdi = end 186160abee0Sda73024 mov 0*4(%rbp), %eax / eax = ctx->A 187160abee0Sda73024 mov 1*4(%rbp), %ebx / ebx = ctx->B 188160abee0Sda73024 mov 2*4(%rbp), %ecx / ecx = ctx->C 189160abee0Sda73024 mov 3*4(%rbp), %edx / edx = ctx->D 190160abee0Sda73024 push %rbp / save ctx 191160abee0Sda73024 / end is 'rdi' 192160abee0Sda73024 / ptr is 'rsi' 193160abee0Sda73024 / A is 'eax' 194160abee0Sda73024 / B is 'ebx' 195160abee0Sda73024 / C is 'ecx' 196160abee0Sda73024 / D is 'edx' 197160abee0Sda73024 198160abee0Sda73024 cmp %rdi, %rsi / cmp end with ptr 199160abee0Sda73024 je 1f / jmp if ptr == end 200160abee0Sda73024 201160abee0Sda73024 / BEGIN of loop over 64-byte blocks 202160abee0Sda730242: / save old values of A, B, C, D 203160abee0Sda73024 mov %eax, %r8d 204160abee0Sda73024 mov %ebx, %r9d 205160abee0Sda73024 mov %ecx, %r14d 206160abee0Sda73024 mov %edx, %r15d 207160abee0Sda73024EOF 208160abee0Sda73024round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7'); 209160abee0Sda73024round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12'); 210160abee0Sda73024round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17'); 211160abee0Sda73024round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22'); 212160abee0Sda73024round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7'); 213160abee0Sda73024round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12'); 214160abee0Sda73024round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17'); 215160abee0Sda73024round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22'); 216160abee0Sda73024round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7'); 217160abee0Sda73024round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12'); 218160abee0Sda73024round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17'); 219160abee0Sda73024round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22'); 220160abee0Sda73024round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7'); 221160abee0Sda73024round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12'); 222160abee0Sda73024round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17'); 223160abee0Sda73024round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22'); 224160abee0Sda73024 225160abee0Sda73024round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5'); 226160abee0Sda73024round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9'); 227160abee0Sda73024round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14'); 228160abee0Sda73024round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20'); 229160abee0Sda73024round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5'); 230160abee0Sda73024round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9'); 231160abee0Sda73024round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14'); 232160abee0Sda73024round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20'); 233160abee0Sda73024round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5'); 234160abee0Sda73024round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9'); 235160abee0Sda73024round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14'); 236160abee0Sda73024round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20'); 237160abee0Sda73024round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5'); 238160abee0Sda73024round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9'); 239160abee0Sda73024round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14'); 240160abee0Sda73024round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20'); 241160abee0Sda73024 242160abee0Sda73024round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4'); 243160abee0Sda73024round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11'); 244160abee0Sda73024round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16'); 245160abee0Sda73024round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23'); 246160abee0Sda73024round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4'); 247160abee0Sda73024round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11'); 248160abee0Sda73024round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16'); 249160abee0Sda73024round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23'); 250160abee0Sda73024round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4'); 251160abee0Sda73024round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11'); 252160abee0Sda73024round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16'); 253160abee0Sda73024round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23'); 254160abee0Sda73024round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4'); 255160abee0Sda73024round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11'); 256160abee0Sda73024round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16'); 257160abee0Sda73024round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23'); 258160abee0Sda73024 259160abee0Sda73024round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6'); 260160abee0Sda73024round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10'); 261160abee0Sda73024round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15'); 262160abee0Sda73024round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21'); 263160abee0Sda73024round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6'); 264160abee0Sda73024round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10'); 265160abee0Sda73024round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15'); 266160abee0Sda73024round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21'); 267160abee0Sda73024round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6'); 268160abee0Sda73024round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10'); 269160abee0Sda73024round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15'); 270160abee0Sda73024round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21'); 271160abee0Sda73024round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6'); 272160abee0Sda73024round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10'); 273160abee0Sda73024round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15'); 274160abee0Sda73024round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21'); 275160abee0Sda73024$code .= <<EOF; 276160abee0Sda73024 / add old values of A, B, C, D 277160abee0Sda73024 add %r8d, %eax 278160abee0Sda73024 add %r9d, %ebx 279160abee0Sda73024 add %r14d, %ecx 280160abee0Sda73024 add %r15d, %edx 281160abee0Sda73024 282160abee0Sda73024 / loop control 283160abee0Sda73024 add \$64, %rsi / ptr += 64 284160abee0Sda73024 cmp %rdi, %rsi / cmp end with ptr 285160abee0Sda73024 jb 2b / jmp if ptr < end 286160abee0Sda73024 / END of loop over 64-byte blocks 287160abee0Sda73024 288160abee0Sda730241: pop %rbp / restore ctx 289160abee0Sda73024 mov %eax, 0*4(%rbp) / ctx->A = A 290160abee0Sda73024 mov %ebx, 1*4(%rbp) / ctx->B = B 291160abee0Sda73024 mov %ecx, 2*4(%rbp) / ctx->C = C 292160abee0Sda73024 mov %edx, 3*4(%rbp) / ctx->D = D 293160abee0Sda73024 294160abee0Sda73024 pop %r15 295160abee0Sda73024 pop %r14 296160abee0Sda73024 pop %r13 297160abee0Sda73024 pop %r12 298160abee0Sda73024 pop %rbx 299160abee0Sda73024 pop %rbp 300160abee0Sda73024 ret 301160abee0Sda73024 SET_SIZE(md5_block_asm_host_order) 302160abee0Sda73024 3038de5c4f4SDan OpenSolaris Anderson#endif /* lint || __lint */ 304160abee0Sda73024EOF 305160abee0Sda73024 306160abee0Sda73024print $code; 307