
	.global	has_time_stamp_counter
has_time_stamp_counter:
	push	%ebx
	push	%ecx
	push	%edx

	pushfl
	mov	$0x200000,%eax
	pop	%ebx
	xor	%ebx,%eax
	push	%eax
	popfl
	pushfl
	pop	%eax
	
	xor	%ebx,%eax
	jz	no_cpuid_instruction

	mov	$1,%eax

	.byte	0x0f,0xa2 # cpuid
	
	shr	$4,%edx
	mov	$1,%eax
	and	%edx,%eax

no_cpuid_instruction:
	pop	%edx
	pop	%ecx
	pop	%ebx
	ret

	.global	read_time_stamp_counter
read_time_stamp_counter:
	push	%ecx
	push	%edx
	movl	12(%esp),%ecx

	.byte	0x0f,0x31 # rdtsc

	movl	%eax,0(%ecx)
	movl	%edx,4(%ecx)
	pop	%edx
	pop	%ecx
	ret

	.global	compute_profile_overhead
compute_profile_overhead:
	jmp	compute_profile_overhead_

profile_:
	push	%eax
	push	%edx

	.byte	0x0f,0x31 # rdtsc

	sub	g_time_lo,%eax
	sbb	g_time_hi,%edx
	add	%eax,p_time_lo
	adc	%edx,p_time_hi

	.byte	0x0f,0x31 # rdtsc

	mov	%edx,g_time_hi
	pop	%edx
	mov	%eax,g_time_lo
	pop	%eax
	ret

compute_profile_overhead_:
	mov	4(%esp),%eax
	push	%ebx
	push	%ecx
	push	%edx
	push	%ebp
	
	xor	%ecx,%ecx
	xor	%edx,%edx
	mov	$100000,%ebx
	
	call	profile_
	mov	%ecx,p_time_lo
	mov	%edx,p_time_hi

compute_profile_overhead_lp1:
	lea	p_time_lo,%ebp
	call	profile_

	add	%ecx,%ecx
	add	%edx,%edx
	
	sub	$1,%ebx
	jne	compute_profile_overhead_lp1

	mov	p_time_lo,%ecx
	mov	p_time_hi,%edx
	mov	%ecx,0(%eax)
	mov	%edx,4(%eax)

	xor	%ecx,%ecx
	xor	%edx,%edx
	mov	$100000,%ebx
	
	call	profile_
	mov	%ecx,p_time_lo
	mov	%edx,p_time_hi

compute_profile_overhead_lp2:
	add	%ecx,%ecx
	add	%edx,%edx
	
	sub	$1,%ebx
	jne	compute_profile_overhead_lp2

	call	profile_

	mov	p_time_lo,%ecx
	mov	p_time_hi,%edx
	mov	%ecx,8(%eax)
	mov	%edx,12(%eax)

	pop	%ebp
	pop	%edx
	pop	%ecx
	pop	%ebx
	ret

