Home | History | Annotate | Line # | Download | only in masmx64
inffasx64.asm revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  pgoyette ; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding
      2  1.1.1.1.2.2  pgoyette ; version for AMD64 on Windows using Microsoft C compiler
      3  1.1.1.1.2.2  pgoyette ;
      4  1.1.1.1.2.2  pgoyette ; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
      5  1.1.1.1.2.2  pgoyette ; inffasx64.asm is called by inffas8664.c, which contain more info.
      6  1.1.1.1.2.2  pgoyette 
      7  1.1.1.1.2.2  pgoyette 
      8  1.1.1.1.2.2  pgoyette ; to compile this file, I use option
      9  1.1.1.1.2.2  pgoyette ;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
     10  1.1.1.1.2.2  pgoyette ;   with Microsoft Macro Assembler (x64) for AMD64
     11  1.1.1.1.2.2  pgoyette ;
     12  1.1.1.1.2.2  pgoyette 
     13  1.1.1.1.2.2  pgoyette ; This file compile with Microsoft Macro Assembler (x64) for AMD64
     14  1.1.1.1.2.2  pgoyette ;
     15  1.1.1.1.2.2  pgoyette ;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
     16  1.1.1.1.2.2  pgoyette ;
     17  1.1.1.1.2.2  pgoyette ;   (you can get Windows WDK with ml64 for AMD64 from
     18  1.1.1.1.2.2  pgoyette ;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
     19  1.1.1.1.2.2  pgoyette ;
     20  1.1.1.1.2.2  pgoyette 
     21  1.1.1.1.2.2  pgoyette 
     22  1.1.1.1.2.2  pgoyette .code
     23  1.1.1.1.2.2  pgoyette inffas8664fnc PROC
     24  1.1.1.1.2.2  pgoyette 
     25  1.1.1.1.2.2  pgoyette ; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
     26  1.1.1.1.2.2  pgoyette ; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
     27  1.1.1.1.2.2  pgoyette ;
     28  1.1.1.1.2.2  pgoyette ; All registers must be preserved across the call, except for
     29  1.1.1.1.2.2  pgoyette ;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
     30  1.1.1.1.2.2  pgoyette 
     31  1.1.1.1.2.2  pgoyette 
     32  1.1.1.1.2.2  pgoyette 	mov [rsp-8],rsi
     33  1.1.1.1.2.2  pgoyette 	mov [rsp-16],rdi
     34  1.1.1.1.2.2  pgoyette 	mov [rsp-24],r12
     35  1.1.1.1.2.2  pgoyette 	mov [rsp-32],r13
     36  1.1.1.1.2.2  pgoyette 	mov [rsp-40],r14
     37  1.1.1.1.2.2  pgoyette 	mov [rsp-48],r15
     38  1.1.1.1.2.2  pgoyette 	mov [rsp-56],rbx
     39  1.1.1.1.2.2  pgoyette 
     40  1.1.1.1.2.2  pgoyette 	mov rax,rcx
     41  1.1.1.1.2.2  pgoyette 
     42  1.1.1.1.2.2  pgoyette 	mov	[rax+8], rbp       ; /* save regs rbp and rsp */
     43  1.1.1.1.2.2  pgoyette 	mov	[rax], rsp
     44  1.1.1.1.2.2  pgoyette 
     45  1.1.1.1.2.2  pgoyette 	mov	rsp, rax          ; /* make rsp point to &ar */
     46  1.1.1.1.2.2  pgoyette 
     47  1.1.1.1.2.2  pgoyette 	mov	rsi, [rsp+16]      ; /* rsi  = in */
     48  1.1.1.1.2.2  pgoyette 	mov	rdi, [rsp+32]      ; /* rdi  = out */
     49  1.1.1.1.2.2  pgoyette 	mov	r9, [rsp+24]       ; /* r9   = last */
     50  1.1.1.1.2.2  pgoyette 	mov	r10, [rsp+48]      ; /* r10  = end */
     51  1.1.1.1.2.2  pgoyette 	mov	rbp, [rsp+64]      ; /* rbp  = lcode */
     52  1.1.1.1.2.2  pgoyette 	mov	r11, [rsp+72]      ; /* r11  = dcode */
     53  1.1.1.1.2.2  pgoyette 	mov	rdx, [rsp+80]      ; /* rdx  = hold */
     54  1.1.1.1.2.2  pgoyette 	mov	ebx, [rsp+88]      ; /* ebx  = bits */
     55  1.1.1.1.2.2  pgoyette 	mov	r12d, [rsp+100]    ; /* r12d = lmask */
     56  1.1.1.1.2.2  pgoyette 	mov	r13d, [rsp+104]    ; /* r13d = dmask */
     57  1.1.1.1.2.2  pgoyette                                           ; /* r14d = len */
     58  1.1.1.1.2.2  pgoyette                                           ; /* r15d = dist */
     59  1.1.1.1.2.2  pgoyette 
     60  1.1.1.1.2.2  pgoyette 
     61  1.1.1.1.2.2  pgoyette 	cld
     62  1.1.1.1.2.2  pgoyette 	cmp	r10, rdi
     63  1.1.1.1.2.2  pgoyette 	je	L_one_time           ; /* if only one decode left */
     64  1.1.1.1.2.2  pgoyette 	cmp	r9, rsi
     65  1.1.1.1.2.2  pgoyette 
     66  1.1.1.1.2.2  pgoyette     jne L_do_loop
     67  1.1.1.1.2.2  pgoyette 
     68  1.1.1.1.2.2  pgoyette 
     69  1.1.1.1.2.2  pgoyette L_one_time:
     70  1.1.1.1.2.2  pgoyette 	mov	r8, r12           ; /* r8 = lmask */
     71  1.1.1.1.2.2  pgoyette 	cmp	bl, 32
     72  1.1.1.1.2.2  pgoyette 	ja	L_get_length_code_one_time
     73  1.1.1.1.2.2  pgoyette 
     74  1.1.1.1.2.2  pgoyette 	lodsd                         ; /* eax = *(uint *)in++ */
     75  1.1.1.1.2.2  pgoyette 	mov	cl, bl            ; /* cl = bits, needs it for shifting */
     76  1.1.1.1.2.2  pgoyette 	add	bl, 32             ; /* bits += 32 */
     77  1.1.1.1.2.2  pgoyette 	shl	rax, cl
     78  1.1.1.1.2.2  pgoyette 	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
     79  1.1.1.1.2.2  pgoyette 	jmp	L_get_length_code_one_time
     80  1.1.1.1.2.2  pgoyette 
     81  1.1.1.1.2.2  pgoyette ALIGN 4
     82  1.1.1.1.2.2  pgoyette L_while_test:
     83  1.1.1.1.2.2  pgoyette 	cmp	r10, rdi
     84  1.1.1.1.2.2  pgoyette 	jbe	L_break_loop
     85  1.1.1.1.2.2  pgoyette 	cmp	r9, rsi
     86  1.1.1.1.2.2  pgoyette 	jbe	L_break_loop
     87  1.1.1.1.2.2  pgoyette 
     88  1.1.1.1.2.2  pgoyette L_do_loop:
     89  1.1.1.1.2.2  pgoyette 	mov	r8, r12           ; /* r8 = lmask */
     90  1.1.1.1.2.2  pgoyette 	cmp	bl, 32
     91  1.1.1.1.2.2  pgoyette 	ja	L_get_length_code    ; /* if (32 < bits) */
     92  1.1.1.1.2.2  pgoyette 
     93  1.1.1.1.2.2  pgoyette 	lodsd                         ; /* eax = *(uint *)in++ */
     94  1.1.1.1.2.2  pgoyette 	mov	cl, bl            ; /* cl = bits, needs it for shifting */
     95  1.1.1.1.2.2  pgoyette 	add	bl, 32             ; /* bits += 32 */
     96  1.1.1.1.2.2  pgoyette 	shl	rax, cl
     97  1.1.1.1.2.2  pgoyette 	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
     98  1.1.1.1.2.2  pgoyette 
     99  1.1.1.1.2.2  pgoyette L_get_length_code:
    100  1.1.1.1.2.2  pgoyette 	and	r8, rdx            ; /* r8 &= hold */
    101  1.1.1.1.2.2  pgoyette 	mov	eax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */
    102  1.1.1.1.2.2  pgoyette 
    103  1.1.1.1.2.2  pgoyette 	mov	cl, ah            ; /* cl = this.bits */
    104  1.1.1.1.2.2  pgoyette 	sub	bl, ah            ; /* bits -= this.bits */
    105  1.1.1.1.2.2  pgoyette 	shr	rdx, cl           ; /* hold >>= this.bits */
    106  1.1.1.1.2.2  pgoyette 
    107  1.1.1.1.2.2  pgoyette 	test	al, al
    108  1.1.1.1.2.2  pgoyette 	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
    109  1.1.1.1.2.2  pgoyette 
    110  1.1.1.1.2.2  pgoyette 	mov	r8, r12            ; /* r8 = lmask */
    111  1.1.1.1.2.2  pgoyette 	shr	eax, 16            ; /* output this.val char */
    112  1.1.1.1.2.2  pgoyette 	stosb
    113  1.1.1.1.2.2  pgoyette 
    114  1.1.1.1.2.2  pgoyette L_get_length_code_one_time:
    115  1.1.1.1.2.2  pgoyette 	and	r8, rdx            ; /* r8 &= hold */
    116  1.1.1.1.2.2  pgoyette 	mov	eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
    117  1.1.1.1.2.2  pgoyette 
    118  1.1.1.1.2.2  pgoyette L_dolen:
    119  1.1.1.1.2.2  pgoyette 	mov	cl, ah            ; /* cl = this.bits */
    120  1.1.1.1.2.2  pgoyette 	sub	bl, ah            ; /* bits -= this.bits */
    121  1.1.1.1.2.2  pgoyette 	shr	rdx, cl           ; /* hold >>= this.bits */
    122  1.1.1.1.2.2  pgoyette 
    123  1.1.1.1.2.2  pgoyette 	test	al, al
    124  1.1.1.1.2.2  pgoyette 	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
    125  1.1.1.1.2.2  pgoyette 
    126  1.1.1.1.2.2  pgoyette 	shr	eax, 16            ; /* output this.val char */
    127  1.1.1.1.2.2  pgoyette 	stosb
    128  1.1.1.1.2.2  pgoyette 	jmp	L_while_test
    129  1.1.1.1.2.2  pgoyette 
    130  1.1.1.1.2.2  pgoyette ALIGN 4
    131  1.1.1.1.2.2  pgoyette L_test_for_length_base:
    132  1.1.1.1.2.2  pgoyette 	mov	r14d, eax         ; /* len = this */
    133  1.1.1.1.2.2  pgoyette 	shr	r14d, 16           ; /* len = this.val */
    134  1.1.1.1.2.2  pgoyette 	mov	cl, al
    135  1.1.1.1.2.2  pgoyette 
    136  1.1.1.1.2.2  pgoyette 	test	al, 16
    137  1.1.1.1.2.2  pgoyette 	jz	L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */
    138  1.1.1.1.2.2  pgoyette 	and	cl, 15             ; /* op &= 15 */
    139  1.1.1.1.2.2  pgoyette 	jz	L_decode_distance    ; /* if (!op) */
    140  1.1.1.1.2.2  pgoyette 
    141  1.1.1.1.2.2  pgoyette L_add_bits_to_len:
    142  1.1.1.1.2.2  pgoyette 	sub	bl, cl
    143  1.1.1.1.2.2  pgoyette 	xor	eax, eax
    144  1.1.1.1.2.2  pgoyette 	inc	eax
    145  1.1.1.1.2.2  pgoyette 	shl	eax, cl
    146  1.1.1.1.2.2  pgoyette 	dec	eax
    147  1.1.1.1.2.2  pgoyette 	and	eax, edx          ; /* eax &= hold */
    148  1.1.1.1.2.2  pgoyette 	shr	rdx, cl
    149  1.1.1.1.2.2  pgoyette 	add	r14d, eax         ; /* len += hold & mask[op] */
    150  1.1.1.1.2.2  pgoyette 
    151  1.1.1.1.2.2  pgoyette L_decode_distance:
    152  1.1.1.1.2.2  pgoyette 	mov	r8, r13           ; /* r8 = dmask */
    153  1.1.1.1.2.2  pgoyette 	cmp	bl, 32
    154  1.1.1.1.2.2  pgoyette 	ja	L_get_distance_code  ; /* if (32 < bits) */
    155  1.1.1.1.2.2  pgoyette 
    156  1.1.1.1.2.2  pgoyette 	lodsd                         ; /* eax = *(uint *)in++ */
    157  1.1.1.1.2.2  pgoyette 	mov	cl, bl            ; /* cl = bits, needs it for shifting */
    158  1.1.1.1.2.2  pgoyette 	add	bl, 32             ; /* bits += 32 */
    159  1.1.1.1.2.2  pgoyette 	shl	rax, cl
    160  1.1.1.1.2.2  pgoyette 	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
    161  1.1.1.1.2.2  pgoyette 
    162  1.1.1.1.2.2  pgoyette L_get_distance_code:
    163  1.1.1.1.2.2  pgoyette 	and	r8, rdx           ; /* r8 &= hold */
    164  1.1.1.1.2.2  pgoyette 	mov	eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */
    165  1.1.1.1.2.2  pgoyette 
    166  1.1.1.1.2.2  pgoyette L_dodist:
    167  1.1.1.1.2.2  pgoyette 	mov	r15d, eax         ; /* dist = this */
    168  1.1.1.1.2.2  pgoyette 	shr	r15d, 16           ; /* dist = this.val */
    169  1.1.1.1.2.2  pgoyette 	mov	cl, ah
    170  1.1.1.1.2.2  pgoyette 	sub	bl, ah            ; /* bits -= this.bits */
    171  1.1.1.1.2.2  pgoyette 	shr	rdx, cl           ; /* hold >>= this.bits */
    172  1.1.1.1.2.2  pgoyette 	mov	cl, al            ; /* cl = this.op */
    173  1.1.1.1.2.2  pgoyette 
    174  1.1.1.1.2.2  pgoyette 	test	al, 16             ; /* if ((op & 16) == 0) */
    175  1.1.1.1.2.2  pgoyette 	jz	L_test_for_second_level_dist
    176  1.1.1.1.2.2  pgoyette 	and	cl, 15             ; /* op &= 15 */
    177  1.1.1.1.2.2  pgoyette 	jz	L_check_dist_one
    178  1.1.1.1.2.2  pgoyette 
    179  1.1.1.1.2.2  pgoyette L_add_bits_to_dist:
    180  1.1.1.1.2.2  pgoyette 	sub	bl, cl
    181  1.1.1.1.2.2  pgoyette 	xor	eax, eax
    182  1.1.1.1.2.2  pgoyette 	inc	eax
    183  1.1.1.1.2.2  pgoyette 	shl	eax, cl
    184  1.1.1.1.2.2  pgoyette 	dec	eax                 ; /* (1 << op) - 1 */
    185  1.1.1.1.2.2  pgoyette 	and	eax, edx          ; /* eax &= hold */
    186  1.1.1.1.2.2  pgoyette 	shr	rdx, cl
    187  1.1.1.1.2.2  pgoyette 	add	r15d, eax         ; /* dist += hold & ((1 << op) - 1) */
    188  1.1.1.1.2.2  pgoyette 
    189  1.1.1.1.2.2  pgoyette L_check_window:
    190  1.1.1.1.2.2  pgoyette 	mov	r8, rsi           ; /* save in so from can use it's reg */
    191  1.1.1.1.2.2  pgoyette 	mov	rax, rdi
    192  1.1.1.1.2.2  pgoyette 	sub	rax, [rsp+40]      ; /* nbytes = out - beg */
    193  1.1.1.1.2.2  pgoyette 
    194  1.1.1.1.2.2  pgoyette 	cmp	eax, r15d
    195  1.1.1.1.2.2  pgoyette 	jb	L_clip_window        ; /* if (dist > nbytes) 4.2% */
    196  1.1.1.1.2.2  pgoyette 
    197  1.1.1.1.2.2  pgoyette 	mov	ecx, r14d         ; /* ecx = len */
    198  1.1.1.1.2.2  pgoyette 	mov	rsi, rdi
    199  1.1.1.1.2.2  pgoyette 	sub	rsi, r15          ; /* from = out - dist */
    200  1.1.1.1.2.2  pgoyette 
    201  1.1.1.1.2.2  pgoyette 	sar	ecx, 1
    202  1.1.1.1.2.2  pgoyette 	jnc	L_copy_two           ; /* if len % 2 == 0 */
    203  1.1.1.1.2.2  pgoyette 
    204  1.1.1.1.2.2  pgoyette 	rep     movsw
    205  1.1.1.1.2.2  pgoyette 	mov	al, [rsi]
    206  1.1.1.1.2.2  pgoyette 	mov	[rdi], al
    207  1.1.1.1.2.2  pgoyette 	inc	rdi
    208  1.1.1.1.2.2  pgoyette 
    209  1.1.1.1.2.2  pgoyette 	mov	rsi, r8           ; /* move in back to %rsi, toss from */
    210  1.1.1.1.2.2  pgoyette 	jmp	L_while_test
    211  1.1.1.1.2.2  pgoyette 
    212  1.1.1.1.2.2  pgoyette L_copy_two:
    213  1.1.1.1.2.2  pgoyette 	rep     movsw
    214  1.1.1.1.2.2  pgoyette 	mov	rsi, r8           ; /* move in back to %rsi, toss from */
    215  1.1.1.1.2.2  pgoyette 	jmp	L_while_test
    216  1.1.1.1.2.2  pgoyette 
    217  1.1.1.1.2.2  pgoyette ALIGN 4
    218  1.1.1.1.2.2  pgoyette L_check_dist_one:
    219  1.1.1.1.2.2  pgoyette 	cmp	r15d, 1            ; /* if dist 1, is a memset */
    220  1.1.1.1.2.2  pgoyette 	jne	L_check_window
    221  1.1.1.1.2.2  pgoyette 	cmp	[rsp+40], rdi      ; /* if out == beg, outside window */
    222  1.1.1.1.2.2  pgoyette 	je	L_check_window
    223  1.1.1.1.2.2  pgoyette 
    224  1.1.1.1.2.2  pgoyette 	mov	ecx, r14d         ; /* ecx = len */
    225  1.1.1.1.2.2  pgoyette 	mov	al, [rdi-1]
    226  1.1.1.1.2.2  pgoyette 	mov	ah, al
    227  1.1.1.1.2.2  pgoyette 
    228  1.1.1.1.2.2  pgoyette 	sar	ecx, 1
    229  1.1.1.1.2.2  pgoyette 	jnc	L_set_two
    230  1.1.1.1.2.2  pgoyette 	mov	[rdi], al
    231  1.1.1.1.2.2  pgoyette 	inc	rdi
    232  1.1.1.1.2.2  pgoyette 
    233  1.1.1.1.2.2  pgoyette L_set_two:
    234  1.1.1.1.2.2  pgoyette 	rep     stosw
    235  1.1.1.1.2.2  pgoyette 	jmp	L_while_test
    236  1.1.1.1.2.2  pgoyette 
    237  1.1.1.1.2.2  pgoyette ALIGN 4
    238  1.1.1.1.2.2  pgoyette L_test_for_second_level_length:
    239  1.1.1.1.2.2  pgoyette 	test	al, 64
    240  1.1.1.1.2.2  pgoyette 	jnz	L_test_for_end_of_block ; /* if ((op & 64) != 0) */
    241  1.1.1.1.2.2  pgoyette 
    242  1.1.1.1.2.2  pgoyette 	xor	eax, eax
    243  1.1.1.1.2.2  pgoyette 	inc	eax
    244  1.1.1.1.2.2  pgoyette 	shl	eax, cl
    245  1.1.1.1.2.2  pgoyette 	dec	eax
    246  1.1.1.1.2.2  pgoyette 	and	eax, edx         ; /* eax &= hold */
    247  1.1.1.1.2.2  pgoyette 	add	eax, r14d        ; /* eax += len */
    248  1.1.1.1.2.2  pgoyette 	mov	eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/
    249  1.1.1.1.2.2  pgoyette 	jmp	L_dolen
    250  1.1.1.1.2.2  pgoyette 
    251  1.1.1.1.2.2  pgoyette ALIGN 4
    252  1.1.1.1.2.2  pgoyette L_test_for_second_level_dist:
    253  1.1.1.1.2.2  pgoyette 	test	al, 64
    254  1.1.1.1.2.2  pgoyette 	jnz	L_invalid_distance_code ; /* if ((op & 64) != 0) */
    255  1.1.1.1.2.2  pgoyette 
    256  1.1.1.1.2.2  pgoyette 	xor	eax, eax
    257  1.1.1.1.2.2  pgoyette 	inc	eax
    258  1.1.1.1.2.2  pgoyette 	shl	eax, cl
    259  1.1.1.1.2.2  pgoyette 	dec	eax
    260  1.1.1.1.2.2  pgoyette 	and	eax, edx         ; /* eax &= hold */
    261  1.1.1.1.2.2  pgoyette 	add	eax, r15d        ; /* eax += dist */
    262  1.1.1.1.2.2  pgoyette 	mov	eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/
    263  1.1.1.1.2.2  pgoyette 	jmp	L_dodist
    264  1.1.1.1.2.2  pgoyette 
    265  1.1.1.1.2.2  pgoyette ALIGN 4
    266  1.1.1.1.2.2  pgoyette L_clip_window:
    267  1.1.1.1.2.2  pgoyette 	mov	ecx, eax         ; /* ecx = nbytes */
    268  1.1.1.1.2.2  pgoyette 	mov	eax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */
    269  1.1.1.1.2.2  pgoyette 	neg	ecx                ; /* nbytes = -nbytes */
    270  1.1.1.1.2.2  pgoyette 
    271  1.1.1.1.2.2  pgoyette 	cmp	eax, r15d
    272  1.1.1.1.2.2  pgoyette 	jb	L_invalid_distance_too_far ; /* if (dist > wsize) */
    273  1.1.1.1.2.2  pgoyette 
    274  1.1.1.1.2.2  pgoyette 	add	ecx, r15d         ; /* nbytes = dist - nbytes */
    275  1.1.1.1.2.2  pgoyette 	cmp	dword ptr [rsp+96], 0
    276  1.1.1.1.2.2  pgoyette 	jne	L_wrap_around_window ; /* if (write != 0) */
    277  1.1.1.1.2.2  pgoyette 
    278  1.1.1.1.2.2  pgoyette 	mov	rsi, [rsp+56]     ; /* from  = window */
    279  1.1.1.1.2.2  pgoyette 	sub	eax, ecx         ; /* eax  -= nbytes */
    280  1.1.1.1.2.2  pgoyette 	add	rsi, rax         ; /* from += wsize - nbytes */
    281  1.1.1.1.2.2  pgoyette 
    282  1.1.1.1.2.2  pgoyette 	mov	eax, r14d        ; /* eax = len */
    283  1.1.1.1.2.2  pgoyette 	cmp	r14d, ecx
    284  1.1.1.1.2.2  pgoyette 	jbe	L_do_copy           ; /* if (nbytes >= len) */
    285  1.1.1.1.2.2  pgoyette 
    286  1.1.1.1.2.2  pgoyette 	sub	eax, ecx         ; /* eax -= nbytes */
    287  1.1.1.1.2.2  pgoyette 	rep     movsb
    288  1.1.1.1.2.2  pgoyette 	mov	rsi, rdi
    289  1.1.1.1.2.2  pgoyette 	sub	rsi, r15         ; /* from = &out[ -dist ] */
    290  1.1.1.1.2.2  pgoyette 	jmp	L_do_copy
    291  1.1.1.1.2.2  pgoyette 
    292  1.1.1.1.2.2  pgoyette ALIGN 4
    293  1.1.1.1.2.2  pgoyette L_wrap_around_window:
    294  1.1.1.1.2.2  pgoyette 	mov	eax, [rsp+96]     ; /* eax = write */
    295  1.1.1.1.2.2  pgoyette 	cmp	ecx, eax
    296  1.1.1.1.2.2  pgoyette 	jbe	L_contiguous_in_window ; /* if (write >= nbytes) */
    297  1.1.1.1.2.2  pgoyette 
    298  1.1.1.1.2.2  pgoyette 	mov	esi, [rsp+92]     ; /* from  = wsize */
    299  1.1.1.1.2.2  pgoyette 	add	rsi, [rsp+56]     ; /* from += window */
    300  1.1.1.1.2.2  pgoyette 	add	rsi, rax         ; /* from += write */
    301  1.1.1.1.2.2  pgoyette 	sub	rsi, rcx         ; /* from -= nbytes */
    302  1.1.1.1.2.2  pgoyette 	sub	ecx, eax         ; /* nbytes -= write */
    303  1.1.1.1.2.2  pgoyette 
    304  1.1.1.1.2.2  pgoyette 	mov	eax, r14d        ; /* eax = len */
    305  1.1.1.1.2.2  pgoyette 	cmp	eax, ecx
    306  1.1.1.1.2.2  pgoyette 	jbe	L_do_copy           ; /* if (nbytes >= len) */
    307  1.1.1.1.2.2  pgoyette 
    308  1.1.1.1.2.2  pgoyette 	sub	eax, ecx         ; /* len -= nbytes */
    309  1.1.1.1.2.2  pgoyette 	rep     movsb
    310  1.1.1.1.2.2  pgoyette 	mov	rsi, [rsp+56]     ; /* from = window */
    311  1.1.1.1.2.2  pgoyette 	mov	ecx, [rsp+96]     ; /* nbytes = write */
    312  1.1.1.1.2.2  pgoyette 	cmp	eax, ecx
    313  1.1.1.1.2.2  pgoyette 	jbe	L_do_copy           ; /* if (nbytes >= len) */
    314  1.1.1.1.2.2  pgoyette 
    315  1.1.1.1.2.2  pgoyette 	sub	eax, ecx         ; /* len -= nbytes */
    316  1.1.1.1.2.2  pgoyette 	rep     movsb
    317  1.1.1.1.2.2  pgoyette 	mov	rsi, rdi
    318  1.1.1.1.2.2  pgoyette 	sub	rsi, r15         ; /* from = out - dist */
    319  1.1.1.1.2.2  pgoyette 	jmp	L_do_copy
    320  1.1.1.1.2.2  pgoyette 
    321  1.1.1.1.2.2  pgoyette ALIGN 4
    322  1.1.1.1.2.2  pgoyette L_contiguous_in_window:
    323  1.1.1.1.2.2  pgoyette 	mov	rsi, [rsp+56]     ; /* rsi = window */
    324  1.1.1.1.2.2  pgoyette 	add	rsi, rax
    325  1.1.1.1.2.2  pgoyette 	sub	rsi, rcx         ; /* from += write - nbytes */
    326  1.1.1.1.2.2  pgoyette 
    327  1.1.1.1.2.2  pgoyette 	mov	eax, r14d        ; /* eax = len */
    328  1.1.1.1.2.2  pgoyette 	cmp	eax, ecx
    329  1.1.1.1.2.2  pgoyette 	jbe	L_do_copy           ; /* if (nbytes >= len) */
    330  1.1.1.1.2.2  pgoyette 
    331  1.1.1.1.2.2  pgoyette 	sub	eax, ecx         ; /* len -= nbytes */
    332  1.1.1.1.2.2  pgoyette 	rep     movsb
    333  1.1.1.1.2.2  pgoyette 	mov	rsi, rdi
    334  1.1.1.1.2.2  pgoyette 	sub	rsi, r15         ; /* from = out - dist */
    335  1.1.1.1.2.2  pgoyette 	jmp	L_do_copy           ; /* if (nbytes >= len) */
    336  1.1.1.1.2.2  pgoyette 
    337  1.1.1.1.2.2  pgoyette ALIGN 4
    338  1.1.1.1.2.2  pgoyette L_do_copy:
    339  1.1.1.1.2.2  pgoyette 	mov	ecx, eax         ; /* ecx = len */
    340  1.1.1.1.2.2  pgoyette 	rep     movsb
    341  1.1.1.1.2.2  pgoyette 
    342  1.1.1.1.2.2  pgoyette 	mov	rsi, r8          ; /* move in back to %esi, toss from */
    343  1.1.1.1.2.2  pgoyette 	jmp	L_while_test
    344  1.1.1.1.2.2  pgoyette 
    345  1.1.1.1.2.2  pgoyette L_test_for_end_of_block:
    346  1.1.1.1.2.2  pgoyette 	test	al, 32
    347  1.1.1.1.2.2  pgoyette 	jz	L_invalid_literal_length_code
    348  1.1.1.1.2.2  pgoyette 	mov	dword ptr [rsp+116], 1
    349  1.1.1.1.2.2  pgoyette 	jmp	L_break_loop_with_status
    350  1.1.1.1.2.2  pgoyette 
    351  1.1.1.1.2.2  pgoyette L_invalid_literal_length_code:
    352  1.1.1.1.2.2  pgoyette 	mov	dword ptr [rsp+116], 2
    353  1.1.1.1.2.2  pgoyette 	jmp	L_break_loop_with_status
    354  1.1.1.1.2.2  pgoyette 
    355  1.1.1.1.2.2  pgoyette L_invalid_distance_code:
    356  1.1.1.1.2.2  pgoyette 	mov	dword ptr [rsp+116], 3
    357  1.1.1.1.2.2  pgoyette 	jmp	L_break_loop_with_status
    358  1.1.1.1.2.2  pgoyette 
    359  1.1.1.1.2.2  pgoyette L_invalid_distance_too_far:
    360  1.1.1.1.2.2  pgoyette 	mov	dword ptr [rsp+116], 4
    361  1.1.1.1.2.2  pgoyette 	jmp	L_break_loop_with_status
    362  1.1.1.1.2.2  pgoyette 
    363  1.1.1.1.2.2  pgoyette L_break_loop:
    364  1.1.1.1.2.2  pgoyette 	mov	dword ptr [rsp+116], 0
    365  1.1.1.1.2.2  pgoyette 
    366  1.1.1.1.2.2  pgoyette L_break_loop_with_status:
    367  1.1.1.1.2.2  pgoyette ; /* put in, out, bits, and hold back into ar and pop esp */
    368  1.1.1.1.2.2  pgoyette 	mov	[rsp+16], rsi     ; /* in */
    369  1.1.1.1.2.2  pgoyette 	mov	[rsp+32], rdi     ; /* out */
    370  1.1.1.1.2.2  pgoyette 	mov	[rsp+88], ebx     ; /* bits */
    371  1.1.1.1.2.2  pgoyette 	mov	[rsp+80], rdx     ; /* hold */
    372  1.1.1.1.2.2  pgoyette 
    373  1.1.1.1.2.2  pgoyette 	mov	rax, [rsp]       ; /* restore rbp and rsp */
    374  1.1.1.1.2.2  pgoyette 	mov	rbp, [rsp+8]
    375  1.1.1.1.2.2  pgoyette 	mov	rsp, rax
    376  1.1.1.1.2.2  pgoyette 
    377  1.1.1.1.2.2  pgoyette 
    378  1.1.1.1.2.2  pgoyette 
    379  1.1.1.1.2.2  pgoyette 	mov rsi,[rsp-8]
    380  1.1.1.1.2.2  pgoyette 	mov rdi,[rsp-16]
    381  1.1.1.1.2.2  pgoyette 	mov r12,[rsp-24]
    382  1.1.1.1.2.2  pgoyette 	mov r13,[rsp-32]
    383  1.1.1.1.2.2  pgoyette 	mov r14,[rsp-40]
    384  1.1.1.1.2.2  pgoyette 	mov r15,[rsp-48]
    385  1.1.1.1.2.2  pgoyette 	mov rbx,[rsp-56]
    386  1.1.1.1.2.2  pgoyette 
    387  1.1.1.1.2.2  pgoyette     ret 0
    388  1.1.1.1.2.2  pgoyette ;          :
    389  1.1.1.1.2.2  pgoyette ;          : "m" (ar)
    390  1.1.1.1.2.2  pgoyette ;          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
    391  1.1.1.1.2.2  pgoyette ;            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
    392  1.1.1.1.2.2  pgoyette ;    );
    393  1.1.1.1.2.2  pgoyette 
    394  1.1.1.1.2.2  pgoyette inffas8664fnc 	ENDP
    395  1.1.1.1.2.2  pgoyette ;_TEXT	ENDS
    396  1.1.1.1.2.2  pgoyette END
    397