Approximating Pi Using x86-64:

;;;
;;; group3.s
;;; Compute Pi
;;;
;;; Note: I am still working of getting the limit part of this
;;;       program correct.
;;;


section .data

zero:		dq		0.0
one:		dq		1.0
two:		dq		2.0
four:		dq		4.0
negone:		dq		-1.0
limit:		dq		0.000001 


;;; Test
SYS_WRITE:		equ			1			
SYS_READ:		equ			0
STDOUT:			equ			1
STDIN:			equ			0
SYS_EXIT:		equ			60

prompt:			db			"How many digits of precision would you like (0-9)? "
prompt_len:		equ			$-prompt

buffer:			db          1




format		db		"%f", 10, 0

section .text

extern printf

global main
main:

	push	rbp
	mov		rbp,		rsp

	;; Compute pi
	movsd	xmm0,		qword [limit]
	call 	compute_pi
	; Return value in xmm0

	;; Print result
	mov 	rdi,		format
	mov 	al,			1
	call 	printf

	mov 	rax,		0
	pop		rbp
	ret

compute_pi:
	push	rbp
	mov 	rbp,		rsp

	; xmm0 = Approximation limit
	; Return result in xmm0

	; YOUR CODE HERE


	mov			rax,		SYS_WRITE			; Prompt
	mov			rdi,		STDOUT
	mov			rsi,		prompt
	mov			rdx,		prompt_len
	Syscall

	mov			rax,		SYS_READ			; Receiving input
	mov			rdi,		STDIN
	mov			rsi,		buffer
	mov			rdx,		buffer
	Syscall


	mov r15, [buffer]
	sub r15, 0x000000000a660a30


	; Initializing registers
	movsd		xmm1,	qword[one]		; xmm1 = 1
	movsd		xmm2,	qword[two]		; xmm2 = 2
	
	movsd		xmm4,	qword[four]		; xmm4 = 4
	movsd		xmm5,	qword[zero]		; xmm5 = 0
	movsd		xmm6,	qword[negone]  	; xmm6 = -1

	movsd		xmm3,	qword[four]
	addsd		xmm3,	xmm6			; xmm3 = 3

	movsd 		xmm0,	xmm3			; starts off with a three
	movsd		xmm11,	xmm6			; Needs to be negative initially

	movsd		xmm15,  xmm4
	mulsd		xmm15,  xmm4
	mulsd		xmm15,	xmm4
	mulsd		xmm15,  xmm4
	mulsd		xmm15,  xmm4			
	mulsd		xmm15,  xmm4			; xmm15 now contains 1024
	

	; Begin loop
	loop1:
	; Setting up the i part
	movsd	xmm8,	xmm5
	movsd	xmm9,	xmm5
	movsd	xmm10,  xmm5

	; Setting up the 2i part
	mulsd	xmm8,	xmm2
	mulsd	xmm9,	xmm2
	mulsd	xmm10,  xmm2

	; Incrementing appropriately
	addsd	xmm8,	xmm2
	addsd	xmm9,	xmm3
	addsd	xmm10,  xmm4

	; Getting the product into xmm8
	mulsd	xmm8,	xmm9
	mulsd	xmm8,	xmm10

	; Performing division
	movsd	xmm14,	xmm4
	divsd	xmm14,	xmm8

	; Doing the negative part
	mulsd	xmm11,  xmm6
	mulsd	xmm14,	xmm11

	; Add to total
	addsd	xmm0,	xmm14

	; increment i
	addsd	xmm5,	xmm1

	ucomisd	xmm5,	xmm15
	jne loop1

	
	
	xor rax, rax
	xor r14, r14
	
	
	mov rax, 0x00000a66302e3025 ;0
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14

	mov rax, 0x000a6631302e3025 ;1
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6632302e3025 ;2
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
				
	mov rax, 0x000a6633302e3025 ;3
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6634302e3025 ;4
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6635302e3025 ;5
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6636302e3025 ;6
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6637302e3025 ;7
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6638302e3025 ;8
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14
		
	mov rax, 0x000a6639302e3025 ;9
		mov [format], rax
		cmp r14, r15
		je .done
		inc r14

;;; Unfortunately, I have run out of time, and was not able to get
;;; this working past 9 digits of precision.
	
.done:

	pop 	rbp
	ret