| ! Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. | 
 | ! | 
 | ! Licensed under the OpenSSL license (the "License").  You may not use | 
 | ! this file except in compliance with the License.  You can obtain a copy | 
 | ! in the file LICENSE in the source distribution or at | 
 | ! https://www.openssl.org/source/license.html | 
 |  | 
 | #if defined(__SUNPRO_C) && defined(__sparcv9) | 
 | # define ABI64  /* They've said -xarch=v9 at command line */ | 
 | #elif defined(__GNUC__) && defined(__arch64__) | 
 | # define ABI64  /* They've said -m64 at command line */ | 
 | #endif | 
 |  | 
 | #ifdef ABI64 | 
 |   .register	%g2,#scratch | 
 |   .register	%g3,#scratch | 
 | # define	FRAME	-192 | 
 | # define	BIAS	2047 | 
 | #else | 
 | # define	FRAME	-96 | 
 | # define	BIAS	0 | 
 | #endif | 
 |  | 
 | .text | 
 | .align	32 | 
 | .global	OPENSSL_wipe_cpu | 
 | .type	OPENSSL_wipe_cpu,#function | 
 | ! Keep in mind that this does not excuse us from wiping the stack! | 
 | ! This routine wipes registers, but not the backing store [which | 
 | ! resides on the stack, toward lower addresses]. To facilitate for | 
 | ! stack wiping I return pointer to the top of stack of the *caller*. | 
 | OPENSSL_wipe_cpu: | 
 | 	save	%sp,FRAME,%sp | 
 | 	nop | 
 | #ifdef __sun | 
 | #include <sys/trap.h> | 
 | 	ta	ST_CLEAN_WINDOWS | 
 | #else | 
 | 	call	.walk.reg.wins | 
 | #endif | 
 | 	nop | 
 | 	call	.PIC.zero.up | 
 | 	mov	.zero-(.-4),%o0 | 
 | 	ld	[%o0],%f0 | 
 | 	ld	[%o0],%f1 | 
 |  | 
 | 	subcc	%g0,1,%o0 | 
 | 	! Following is V9 "rd %ccr,%o0" instruction. However! V8 | 
 | 	! specification says that it ("rd %asr2,%o0" in V8 terms) does | 
 | 	! not cause illegal_instruction trap. It therefore can be used | 
 | 	! to determine if the CPU the code is executing on is V8- or | 
 | 	! V9-compliant, as V9 returns a distinct value of 0x99, | 
 | 	! "negative" and "borrow" bits set in both %icc and %xcc. | 
 | 	.word	0x91408000	!rd	%ccr,%o0 | 
 | 	cmp	%o0,0x99 | 
 | 	bne	.v8 | 
 | 	nop | 
 | 			! Even though we do not use %fp register bank, | 
 | 			! we wipe it as memcpy might have used it... | 
 | 			.word	0xbfa00040	!fmovd	%f0,%f62 | 
 | 			.word	0xbba00040	!... | 
 | 			.word	0xb7a00040 | 
 | 			.word	0xb3a00040 | 
 | 			.word	0xafa00040 | 
 | 			.word	0xaba00040 | 
 | 			.word	0xa7a00040 | 
 | 			.word	0xa3a00040 | 
 | 			.word	0x9fa00040 | 
 | 			.word	0x9ba00040 | 
 | 			.word	0x97a00040 | 
 | 			.word	0x93a00040 | 
 | 			.word	0x8fa00040 | 
 | 			.word	0x8ba00040 | 
 | 			.word	0x87a00040 | 
 | 			.word	0x83a00040	!fmovd	%f0,%f32 | 
 | .v8:			fmovs	%f1,%f31 | 
 | 	clr	%o0 | 
 | 			fmovs	%f0,%f30 | 
 | 	clr	%o1 | 
 | 			fmovs	%f1,%f29 | 
 | 	clr	%o2 | 
 | 			fmovs	%f0,%f28 | 
 | 	clr	%o3 | 
 | 			fmovs	%f1,%f27 | 
 | 	clr	%o4 | 
 | 			fmovs	%f0,%f26 | 
 | 	clr	%o5 | 
 | 			fmovs	%f1,%f25 | 
 | 	clr	%o7 | 
 | 			fmovs	%f0,%f24 | 
 | 	clr	%l0 | 
 | 			fmovs	%f1,%f23 | 
 | 	clr	%l1 | 
 | 			fmovs	%f0,%f22 | 
 | 	clr	%l2 | 
 | 			fmovs	%f1,%f21 | 
 | 	clr	%l3 | 
 | 			fmovs	%f0,%f20 | 
 | 	clr	%l4 | 
 | 			fmovs	%f1,%f19 | 
 | 	clr	%l5 | 
 | 			fmovs	%f0,%f18 | 
 | 	clr	%l6 | 
 | 			fmovs	%f1,%f17 | 
 | 	clr	%l7 | 
 | 			fmovs	%f0,%f16 | 
 | 	clr	%i0 | 
 | 			fmovs	%f1,%f15 | 
 | 	clr	%i1 | 
 | 			fmovs	%f0,%f14 | 
 | 	clr	%i2 | 
 | 			fmovs	%f1,%f13 | 
 | 	clr	%i3 | 
 | 			fmovs	%f0,%f12 | 
 | 	clr	%i4 | 
 | 			fmovs	%f1,%f11 | 
 | 	clr	%i5 | 
 | 			fmovs	%f0,%f10 | 
 | 	clr	%g1 | 
 | 			fmovs	%f1,%f9 | 
 | 	clr	%g2 | 
 | 			fmovs	%f0,%f8 | 
 | 	clr	%g3 | 
 | 			fmovs	%f1,%f7 | 
 | 	clr	%g4 | 
 | 			fmovs	%f0,%f6 | 
 | 	clr	%g5 | 
 | 			fmovs	%f1,%f5 | 
 | 			fmovs	%f0,%f4 | 
 | 			fmovs	%f1,%f3 | 
 | 			fmovs	%f0,%f2 | 
 |  | 
 | 	add	%fp,BIAS,%i0	! return pointer to caller“s top of stack | 
 |  | 
 | 	ret | 
 | 	restore | 
 |  | 
 | .zero:	.long	0x0,0x0 | 
 | .PIC.zero.up: | 
 | 	retl | 
 | 	add	%o0,%o7,%o0 | 
 | #ifdef DEBUG | 
 | .global	walk_reg_wins | 
 | .type	walk_reg_wins,#function | 
 | walk_reg_wins: | 
 | #endif | 
 | .walk.reg.wins: | 
 | 	save	%sp,FRAME,%sp | 
 | 	cmp	%i7,%o7 | 
 | 	be	2f | 
 | 	clr	%o0 | 
 | 	cmp	%o7,0	! compiler never cleans %o7... | 
 | 	be	1f	! could have been a leaf function... | 
 | 	clr	%o1 | 
 | 	call	.walk.reg.wins | 
 | 	nop | 
 | 1:	clr	%o2 | 
 | 	clr	%o3 | 
 | 	clr	%o4 | 
 | 	clr	%o5 | 
 | 	clr	%o7 | 
 | 	clr	%l0 | 
 | 	clr	%l1 | 
 | 	clr	%l2 | 
 | 	clr	%l3 | 
 | 	clr	%l4 | 
 | 	clr	%l5 | 
 | 	clr	%l6 | 
 | 	clr	%l7 | 
 | 	add	%o0,1,%i0	! used for debugging | 
 | 2:	ret | 
 | 	restore | 
 | .size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu | 
 |  | 
 | .global	OPENSSL_atomic_add | 
 | .type	OPENSSL_atomic_add,#function | 
 | .align	32 | 
 | OPENSSL_atomic_add: | 
 | #ifndef ABI64 | 
 | 	subcc	%g0,1,%o2 | 
 | 	.word	0x95408000	!rd	%ccr,%o2, see comment above | 
 | 	cmp	%o2,0x99 | 
 | 	be	.v9 | 
 | 	nop | 
 | 	save	%sp,FRAME,%sp | 
 | 	ba	.enter | 
 | 	nop | 
 | #ifdef __sun | 
 | ! Note that you do not have to link with libthread to call thr_yield, | 
 | ! as libc provides a stub, which is overloaded the moment you link | 
 | ! with *either* libpthread or libthread... | 
 | #define	YIELD_CPU	thr_yield | 
 | #else | 
 | ! applies at least to Linux and FreeBSD... Feedback expected... | 
 | #define	YIELD_CPU	sched_yield | 
 | #endif | 
 | .spin:	call	YIELD_CPU | 
 | 	nop | 
 | .enter:	ld	[%i0],%i2 | 
 | 	cmp	%i2,-4096 | 
 | 	be	.spin | 
 | 	mov	-1,%i2 | 
 | 	swap	[%i0],%i2 | 
 | 	cmp	%i2,-1 | 
 | 	be	.spin | 
 | 	add	%i2,%i1,%i2 | 
 | 	stbar | 
 | 	st	%i2,[%i0] | 
 | 	sra	%i2,%g0,%i0 | 
 | 	ret | 
 | 	restore | 
 | .v9: | 
 | #endif | 
 | 	ld	[%o0],%o2 | 
 | 1:	add	%o1,%o2,%o3 | 
 | 	.word	0xd7e2100a	!cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3 | 
 | 	cmp	%o2,%o3 | 
 | 	bne	1b | 
 | 	mov	%o3,%o2		! cas is always fetching to dest. register | 
 | 	add	%o1,%o2,%o0	! OpenSSL expects the new value | 
 | 	retl | 
 | 	sra	%o0,%g0,%o0	! we return signed int, remember? | 
 | .size	OPENSSL_atomic_add,.-OPENSSL_atomic_add | 
 |  | 
 | .global	_sparcv9_rdtick | 
 | .align	32 | 
 | _sparcv9_rdtick: | 
 | 	subcc	%g0,1,%o0 | 
 | 	.word	0x91408000	!rd	%ccr,%o0 | 
 | 	cmp	%o0,0x99 | 
 | 	bne	.notick | 
 | 	xor	%o0,%o0,%o0 | 
 | 	.word	0x91410000	!rd	%tick,%o0 | 
 | 	retl | 
 | 	.word	0x93323020	!srlx	%o0,32,%o1 | 
 | .notick: | 
 | 	retl | 
 | 	xor	%o1,%o1,%o1 | 
 | .type	_sparcv9_rdtick,#function | 
 | .size	_sparcv9_rdtick,.-_sparcv9_rdtick | 
 |  | 
 | .global	_sparcv9_vis1_probe | 
 | .align	8 | 
 | _sparcv9_vis1_probe: | 
 | 	add	%sp,BIAS+2,%o1 | 
 | 	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0 | 
 | 	retl | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | .type	_sparcv9_vis1_probe,#function | 
 | .size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe | 
 |  | 
 | ! Probe and instrument VIS1 instruction. Output is number of cycles it | 
 | ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit | 
 | ! is slow (documented to be 6 cycles on T2) and the core is in-order | 
 | ! single-issue, it should be possible to distinguish Tx reliably... | 
 | ! Observed return values are: | 
 | ! | 
 | !	UltraSPARC IIe		7 | 
 | !	UltraSPARC III		7 | 
 | !	UltraSPARC T1		24 | 
 | !	SPARC T4		65(*) | 
 | ! | 
 | ! (*)	result has lesser to do with VIS instruction latencies, rdtick | 
 | !	appears that slow, but it does the trick in sense that FP and | 
 | !	VIS code paths are still slower than integer-only ones. | 
 | ! | 
 | ! Numbers for T2 and SPARC64 V-VII are more than welcomed. | 
 | ! | 
 | ! It would be possible to detect specifically US-T1 by instrumenting | 
 | ! fmul8ulx16, which is emulated on T1 and as such accounts for quite | 
 | ! a lot of %tick-s, couple of thousand on Linux... | 
 | .global	_sparcv9_vis1_instrument | 
 | .align	8 | 
 | _sparcv9_vis1_instrument: | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	.word	0x91410000	!rd	%tick,%o0 | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	.word	0x93410000	!rd	%tick,%o1 | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	.word	0x95410000	!rd	%tick,%o2 | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	.word	0x97410000	!rd	%tick,%o3 | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	.word	0x99410000	!rd	%tick,%o4 | 
 |  | 
 | 	! calculate intervals | 
 | 	sub	%o1,%o0,%o0 | 
 | 	sub	%o2,%o1,%o1 | 
 | 	sub	%o3,%o2,%o2 | 
 | 	sub	%o4,%o3,%o3 | 
 |  | 
 | 	! find minimum value | 
 | 	cmp	%o0,%o1 | 
 | 	.word	0x38680002	!bgu,a	%xcc,.+8 | 
 | 	mov	%o1,%o0 | 
 | 	cmp	%o0,%o2 | 
 | 	.word	0x38680002	!bgu,a	%xcc,.+8 | 
 | 	mov	%o2,%o0 | 
 | 	cmp	%o0,%o3 | 
 | 	.word	0x38680002	!bgu,a	%xcc,.+8 | 
 | 	mov	%o3,%o0 | 
 |  | 
 | 	retl | 
 | 	nop | 
 | .type	_sparcv9_vis1_instrument,#function | 
 | .size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument | 
 |  | 
 | .global	_sparcv9_vis2_probe | 
 | .align	8 | 
 | _sparcv9_vis2_probe: | 
 | 	retl | 
 | 	.word	0x81b00980	!bshuffle	%f0,%f0,%f0 | 
 | .type	_sparcv9_vis2_probe,#function | 
 | .size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe | 
 |  | 
 | .global	_sparcv9_fmadd_probe | 
 | .align	8 | 
 | _sparcv9_fmadd_probe: | 
 | 	.word	0x81b00d80	!fxor	%f0,%f0,%f0 | 
 | 	.word	0x85b08d82	!fxor	%f2,%f2,%f2 | 
 | 	retl | 
 | 	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0 | 
 | .type	_sparcv9_fmadd_probe,#function | 
 | .size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe | 
 |  | 
 | .global	_sparcv9_rdcfr | 
 | .align	8 | 
 | _sparcv9_rdcfr: | 
 | 	retl | 
 | 	.word	0x91468000	!rd	%asr26,%o0 | 
 | .type	_sparcv9_rdcfr,#function | 
 | .size	_sparcv9_rdcfr,.-_sparcv9_rdcfr | 
 |  | 
 | .global	_sparcv9_vis3_probe | 
 | .align	8 | 
 | _sparcv9_vis3_probe: | 
 | 	retl | 
 | 	.word	0x81b022a0	!xmulx	%g0,%g0,%g0 | 
 | .type	_sparcv9_vis3_probe,#function | 
 | .size	_sparcv9_vis3_probe,.-_sparcv9_vis3_probe | 
 |  | 
 | .global	_sparcv9_random | 
 | .align	8 | 
 | _sparcv9_random: | 
 | 	retl | 
 | 	.word	0x91b002a0	!random	%o0 | 
 | .type	_sparcv9_random,#function | 
 | .size	_sparcv9_random,.-_sparcv9_vis3_probe | 
 |  | 
 | .global	_sparcv9_fjaesx_probe | 
 | .align	8 | 
 | _sparcv9_fjaesx_probe: | 
 | 	.word	0x81b09206	!faesencx %f2,%f6,%f0 | 
 | 	retl | 
 | 	nop | 
 | .size	_sparcv9_fjaesx_probe,.-_sparcv9_fjaesx_probe | 
 |  | 
 | .global	OPENSSL_cleanse | 
 | .align	32 | 
 | OPENSSL_cleanse: | 
 | 	cmp	%o1,14 | 
 | 	nop | 
 | #ifdef ABI64 | 
 | 	bgu	%xcc,.Lot | 
 | #else | 
 | 	bgu	.Lot | 
 | #endif | 
 | 	cmp	%o1,0 | 
 | 	bne	.Little | 
 | 	nop | 
 | 	retl | 
 | 	nop | 
 |  | 
 | .Little: | 
 | 	stb	%g0,[%o0] | 
 | 	subcc	%o1,1,%o1 | 
 | 	bnz	.Little | 
 | 	add	%o0,1,%o0 | 
 | 	retl | 
 | 	nop | 
 | .align	32 | 
 | .Lot: | 
 | #ifndef ABI64 | 
 | 	subcc	%g0,1,%g1 | 
 | 	! see above for explanation | 
 | 	.word	0x83408000	!rd	%ccr,%g1 | 
 | 	cmp	%g1,0x99 | 
 | 	bne	.v8lot | 
 | 	nop | 
 | #endif | 
 |  | 
 | .v9lot:	andcc	%o0,7,%g0 | 
 | 	bz	.v9aligned | 
 | 	nop | 
 | 	stb	%g0,[%o0] | 
 | 	sub	%o1,1,%o1 | 
 | 	ba	.v9lot | 
 | 	add	%o0,1,%o0 | 
 | .align	16,0x01000000 | 
 | .v9aligned: | 
 | 	.word	0xc0720000	!stx	%g0,[%o0] | 
 | 	sub	%o1,8,%o1 | 
 | 	andcc	%o1,-8,%g0 | 
 | #ifdef ABI64 | 
 | 	.word	0x126ffffd	!bnz	%xcc,.v9aligned | 
 | #else | 
 | 	.word	0x124ffffd	!bnz	%icc,.v9aligned | 
 | #endif | 
 | 	add	%o0,8,%o0 | 
 |  | 
 | 	cmp	%o1,0 | 
 | 	bne	.Little | 
 | 	nop | 
 | 	retl | 
 | 	nop | 
 | #ifndef ABI64 | 
 | .v8lot:	andcc	%o0,3,%g0 | 
 | 	bz	.v8aligned | 
 | 	nop | 
 | 	stb	%g0,[%o0] | 
 | 	sub	%o1,1,%o1 | 
 | 	ba	.v8lot | 
 | 	add	%o0,1,%o0 | 
 | 	nop | 
 | .v8aligned: | 
 | 	st	%g0,[%o0] | 
 | 	sub	%o1,4,%o1 | 
 | 	andcc	%o1,-4,%g0 | 
 | 	bnz	.v8aligned | 
 | 	add	%o0,4,%o0 | 
 |  | 
 | 	cmp	%o1,0 | 
 | 	bne	.Little | 
 | 	nop | 
 | 	retl | 
 | 	nop | 
 | #endif | 
 | .type	OPENSSL_cleanse,#function | 
 | .size	OPENSSL_cleanse,.-OPENSSL_cleanse | 
 |  | 
 | .global	CRYPTO_memcmp | 
 | .align	16 | 
 | CRYPTO_memcmp: | 
 | 	cmp	%o2,0 | 
 | #ifdef ABI64 | 
 | 	beq,pn	%xcc,.Lno_data | 
 | #else | 
 | 	beq	.Lno_data | 
 | #endif | 
 | 	xor	%g1,%g1,%g1 | 
 | 	nop | 
 |  | 
 | .Loop_cmp: | 
 | 	ldub	[%o0],%o3 | 
 | 	add	%o0,1,%o0 | 
 | 	ldub	[%o1],%o4 | 
 | 	add	%o1,1,%o1 | 
 | 	subcc	%o2,1,%o2 | 
 | 	xor	%o3,%o4,%o4 | 
 | #ifdef ABI64 | 
 | 	bnz	%xcc,.Loop_cmp | 
 | #else | 
 | 	bnz	.Loop_cmp | 
 | #endif | 
 | 	or	%o4,%g1,%g1 | 
 |  | 
 | 	sub	%g0,%g1,%g1 | 
 | 	srl	%g1,31,%g1 | 
 | .Lno_data: | 
 | 	retl | 
 | 	mov	%g1,%o0 | 
 | .type	CRYPTO_memcmp,#function | 
 | .size	CRYPTO_memcmp,.-CRYPTO_memcmp | 
 |  | 
 | .global	_sparcv9_vis1_instrument_bus | 
 | .align	8 | 
 | _sparcv9_vis1_instrument_bus: | 
 | 	mov	%o1,%o3					! save cnt | 
 | 	.word	0x99410000	!rd	%tick,%o4	! tick | 
 | 	mov	%o4,%o5					! lasttick = tick | 
 | 	set	0,%g4					! diff | 
 |  | 
 | 	andn	%o0,63,%g1 | 
 | 	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	ld	[%o0],%o4 | 
 | 	add	%o4,%g4,%g4 | 
 | 	.word	0xc9e2100c	!cas	[%o0],%o4,%g4 | 
 |  | 
 | .Loop:	.word	0x99410000	!rd	%tick,%o4 | 
 | 	sub	%o4,%o5,%g4				! diff=tick-lasttick | 
 | 	mov	%o4,%o5					! lasttick=tick | 
 |  | 
 | 	andn	%o0,63,%g1 | 
 | 	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	ld	[%o0],%o4 | 
 | 	add	%o4,%g4,%g4 | 
 | 	.word	0xc9e2100c	!cas	[%o0],%o4,%g4 | 
 | 	subcc	%o1,1,%o1				! --$cnt | 
 | 	bnz	.Loop | 
 | 	add	%o0,4,%o0				! ++$out | 
 |  | 
 | 	retl | 
 | 	mov	%o3,%o0 | 
 | .type	_sparcv9_vis1_instrument_bus,#function | 
 | .size	_sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus | 
 |  | 
 | .global	_sparcv9_vis1_instrument_bus2 | 
 | .align	8 | 
 | _sparcv9_vis1_instrument_bus2: | 
 | 	mov	%o1,%o3					! save cnt | 
 | 	sll	%o1,2,%o1				! cnt*=4 | 
 |  | 
 | 	.word	0x99410000	!rd	%tick,%o4	! tick | 
 | 	mov	%o4,%o5					! lasttick = tick | 
 | 	set	0,%g4					! diff | 
 |  | 
 | 	andn	%o0,63,%g1 | 
 | 	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	ld	[%o0],%o4 | 
 | 	add	%o4,%g4,%g4 | 
 | 	.word	0xc9e2100c	!cas	[%o0],%o4,%g4 | 
 |  | 
 | 	.word	0x99410000	!rd	%tick,%o4	! tick | 
 | 	sub	%o4,%o5,%g4				! diff=tick-lasttick | 
 | 	mov	%o4,%o5					! lasttick=tick | 
 | 	mov	%g4,%g5					! lastdiff=diff | 
 | .Loop2: | 
 | 	andn	%o0,63,%g1 | 
 | 	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit | 
 | 	.word	0x8143e040	!membar	#Sync | 
 | 	ld	[%o0],%o4 | 
 | 	add	%o4,%g4,%g4 | 
 | 	.word	0xc9e2100c	!cas	[%o0],%o4,%g4 | 
 |  | 
 | 	subcc	%o2,1,%o2				! --max | 
 | 	bz	.Ldone2 | 
 | 	nop | 
 |  | 
 | 	.word	0x99410000	!rd	%tick,%o4	! tick | 
 | 	sub	%o4,%o5,%g4				! diff=tick-lasttick | 
 | 	mov	%o4,%o5					! lasttick=tick | 
 | 	cmp	%g4,%g5 | 
 | 	mov	%g4,%g5					! lastdiff=diff | 
 |  | 
 | 	.word	0x83408000	!rd	%ccr,%g1 | 
 | 	and	%g1,4,%g1				! isolate zero flag | 
 | 	xor	%g1,4,%g1				! flip zero flag | 
 |  | 
 | 	subcc	%o1,%g1,%o1				! conditional --$cnt | 
 | 	bnz	.Loop2 | 
 | 	add	%o0,%g1,%o0				! conditional ++$out | 
 |  | 
 | .Ldone2: | 
 | 	srl	%o1,2,%o1 | 
 | 	retl | 
 | 	sub	%o3,%o1,%o0 | 
 | .type	_sparcv9_vis1_instrument_bus2,#function | 
 | .size	_sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2 | 
 |  | 
 | .section	".init",#alloc,#execinstr | 
 | 	call	OPENSSL_cpuid_setup | 
 | 	nop |