Almkvist-Giullera formula for pi: Difference between revisions
Content added Content deleted
(add task to arm assembly raspberry pi) |
(add task to aarch64 assembly raspberry pi) |
||
Line 110: | Line 110: | ||
3.1415926535897932384626433832795028841971693993751058209749445923078164 |
3.1415926535897932384626433832795028841971693993751058209749445923078164 |
||
</pre> |
|||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }} |
|||
<lang AArch64 Assembly> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
|||
/* program calculPi64.s */ |
|||
/* this program use gmp library */ |
|||
/* link with gcc option -lgmp */ |
|||
/*******************************************/ |
|||
/* Constantes file */ |
|||
/*******************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly*/ |
|||
.include "../includeConstantesARM64.inc" |
|||
.equ MAXI, 10 |
|||
.equ SIZEBIG, 100 |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szMessDebutPgm: .asciz "Program 64 bits start. \n" |
|||
szMessPi: .asciz "\nPI = \n" |
|||
szCarriageReturn: .asciz "\n" |
|||
szFormat: .asciz " %Zd\n" |
|||
szFormatFloat: .asciz " %.*Ff\n" |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
Result1: .skip SIZEBIG |
|||
Result2: .skip SIZEBIG |
|||
Result3: .skip SIZEBIG |
|||
Result4: .skip SIZEBIG |
|||
fIntex5: .skip SIZEBIG |
|||
fIntex6: .skip SIZEBIG |
|||
fIntex7: .skip SIZEBIG |
|||
fSum: .skip SIZEBIG |
|||
fSum1: .skip SIZEBIG |
|||
sBuffer: .skip SIZEBIG |
|||
fEpsilon: .skip SIZEBIG |
|||
fPrec: .skip SIZEBIG |
|||
fPI: .skip SIZEBIG |
|||
fTEN: .skip SIZEBIG |
|||
fONE: .skip SIZEBIG |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: // entry of program |
|||
ldr x0,qAdrszMessDebutPgm |
|||
bl affichageMess |
|||
mov x20,#0 // loop indice |
|||
1: |
|||
mov x0,x20 |
|||
bl computeAlmkvist // compute |
|||
mov x1,x0 |
|||
ldr x0,qAdrszFormat // print big integer |
|||
bl __gmp_printf |
|||
add x20,x20,#1 |
|||
cmp x20,#MAXI |
|||
blt 1b // and loop |
|||
mov x0,#560 // float précision in bits |
|||
bl __gmpf_set_default_prec |
|||
mov x19,#0 // compute indice |
|||
ldr x0,qAdrfSum // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfSum1 // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfONE // result address |
|||
mov x1,#1 // init à 1 |
|||
bl __gmpf_init_set_ui |
|||
ldr x0,qAdrfIntex5 // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfIntex6 // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfIntex7 // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfEpsilon // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfPrec // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfPI // init to zéro |
|||
bl __gmpf_init |
|||
ldr x0,qAdrfTEN |
|||
mov x1,#10 // init to 10 |
|||
bl __gmpf_init_set_ui |
|||
ldr x0,qAdrfIntex6 // compute 10 pow 70 |
|||
ldr x1,qAdrfTEN |
|||
mov x2,#70 |
|||
bl __gmpf_pow_ui |
|||
ldr x0,qAdrfEpsilon // divide 1 by 10 pow 70 |
|||
ldr x1,qAdrfONE // dividende |
|||
ldr x2,qAdrfIntex6 // divisor |
|||
bl __gmpf_div |
|||
2: // PI compute loop |
|||
mov x0,x19 |
|||
bl computeAlmkvist |
|||
mov x20,x0 |
|||
mov x1,#6 |
|||
mul x2,x1,x19 |
|||
add x6,x2,#3 // compute 6n + 3 |
|||
ldr x0,qAdrfIntex6 // compute 10 pow (6n+3) |
|||
ldr x1,qAdrfTEN |
|||
mov x2,x6 |
|||
bl __gmpf_pow_ui |
|||
ldr x0,qAdrfIntex7 // compute 1 / 10 pow (6n+3) |
|||
ldr x1,qAdrfONE // dividende |
|||
ldr x2,qAdrfIntex6 // divisor |
|||
bl __gmpf_div |
|||
ldr x0,qAdrfIntex6 // result big float |
|||
mov x1,x20 // big integer Almkvist |
|||
bl __gmpf_set_z // conversion in big float |
|||
ldr x0,qAdrfIntex5 // result Almkvist * 1 / 10 pow (6n+3) |
|||
ldr x1,qAdrfIntex7 // operator 1 |
|||
ldr x2,qAdrfIntex6 // operator 2 |
|||
bl __gmpf_mul |
|||
ldr x0,qAdrfSum1 // terms addition |
|||
ldr x1,qAdrfSum |
|||
ldr x2,qAdrfIntex5 |
|||
bl __gmpf_add |
|||
ldr x0,qAdrfSum // copy terms |
|||
ldr x1,qAdrfSum1 |
|||
bl __gmpf_set |
|||
ldr x0,qAdrfIntex7 // compute 1 / sum |
|||
ldr x1,qAdrfONE // dividende |
|||
ldr x2,qAdrfSum // divisor |
|||
bl __gmpf_div |
|||
ldr x0,qAdrfPI // compute square root (1 / sum ) |
|||
ldr x1,qAdrfIntex7 |
|||
bl __gmpf_sqrt |
|||
ldr x0,qAdrfIntex6 // compute variation PI |
|||
ldr x1,qAdrfPrec |
|||
ldr x2,qAdrfPI |
|||
bl __gmpf_sub |
|||
ldr x0,qAdrfIntex6 // absolue value |
|||
ldr x1,qAdrfIntex5 |
|||
bl __gmpf_abs |
|||
add x19,x19,#1 // increment indice |
|||
ldr x0,qAdrfPrec // copy PI -> prévious |
|||
ldr x1,qAdrfPI |
|||
bl __gmpf_set |
|||
ldr x0,qAdrfIntex6 // compare gap and epsilon |
|||
ldr x1,qAdrfEpsilon |
|||
bl __gmpf_cmp |
|||
cmp w0,#0 // !!! cmp return result on 32 bits |
|||
bgt 2b // if gap is highter -> loop |
|||
ldr x0,qAdrszMessPi // title display |
|||
bl affichageMess |
|||
ldr x2,qAdrfPI // PI display |
|||
ldr x0,qAdrszFormatFloat |
|||
mov x1,#70 |
|||
bl __gmp_printf |
|||
100: // standard end of the program |
|||
mov x0, #0 // return code |
|||
mov x8, #EXIT // request to exit program |
|||
svc #0 // perform the system call |
|||
qAdrszMessDebutPgm: .quad szMessDebutPgm |
|||
qAdrszCarriageReturn: .quad szCarriageReturn |
|||
qAdrfIntex5: .quad fIntex5 |
|||
qAdrfIntex6: .quad fIntex6 |
|||
qAdrfIntex7: .quad fIntex7 |
|||
qAdrfSum: .quad fSum |
|||
qAdrfSum1: .quad fSum1 |
|||
qAdrszFormatFloat: .quad szFormatFloat |
|||
qAdrszMessPi: .quad szMessPi |
|||
qAdrfEpsilon: .quad fEpsilon |
|||
qAdrfPrec: .quad fPrec |
|||
qAdrfPI: .quad fPI |
|||
qAdrfTEN: .quad fTEN |
|||
qAdrfONE: .quad fONE |
|||
/***************************************************/ |
|||
/* compute almkvist_giullera formula */ |
|||
/***************************************************/ |
|||
/* x0 contains the number */ |
|||
computeAlmkvist: |
|||
stp x19,lr,[sp,-16]! // save registers |
|||
mov x19,x0 |
|||
mov x1,#6 |
|||
mul x0,x1,x0 |
|||
ldr x1,qAdrResult1 // result address |
|||
bl computeFactorielle // compute (n*6)! |
|||
mov x1,#532 |
|||
mul x2,x19,x19 |
|||
mul x2,x1,x2 |
|||
mov x1,#126 |
|||
mul x3,x19,x1 |
|||
add x2,x2,x3 |
|||
add x2,x2,#9 |
|||
lsl x2,x2,#5 // * 32 |
|||
ldr x0,qAdrResult2 // result |
|||
ldr x1,qAdrResult1 // operator |
|||
bl __gmpz_mul_ui |
|||
mov x0,x19 |
|||
ldr x1,qAdrResult1 |
|||
bl computeFactorielle |
|||
ldr x0,qAdrResult3 |
|||
bl __gmpz_init // init to 0 |
|||
ldr x0,qAdrResult3 // result |
|||
ldr x1,qAdrResult1 // operator |
|||
mov x2,#6 |
|||
bl __gmpz_pow_ui |
|||
ldr x0,qAdrResult1 // result |
|||
ldr x1,qAdrResult3 // operator |
|||
mov x2,#3 |
|||
bl __gmpz_mul_ui |
|||
ldr x0,qAdrResult3 // result |
|||
ldr x1,qAdrResult2 // operator |
|||
ldr x2,qAdrResult1 // operator |
|||
bl __gmpz_cdiv_q |
|||
ldr x0,qAdrResult3 // return result address |
|||
100: |
|||
ldp x19,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
qAdrszFormat: .quad szFormat |
|||
qAdrResult1: .quad Result1 |
|||
qAdrResult2: .quad Result2 |
|||
qAdrResult3: .quad Result3 |
|||
/***************************************************/ |
|||
/* compute factorielle N */ |
|||
/***************************************************/ |
|||
/* x0 contains the number */ |
|||
/* x1 contains big number result address */ |
|||
computeFactorielle: |
|||
stp x19,lr,[sp,-16]! // save registers |
|||
stp x20,x21,[sp,-16]! // save registers |
|||
mov x19,x0 // save N |
|||
mov x20,x1 // save result address |
|||
mov x0,x1 // result address |
|||
mov x1,#1 // init to 1 |
|||
bl __gmpz_init_set_ui |
|||
ldr x0,qAdrResult4 |
|||
bl __gmpz_init // init to 0 |
|||
mov x21,#1 |
|||
1: // loop |
|||
ldr x0,qAdrResult4 // result |
|||
mov x1,x20 // operator 1 |
|||
mov x2,x21 // operator 2 |
|||
bl __gmpz_mul_ui |
|||
mov x0,x20 // copy result4 -> result |
|||
ldr x1,qAdrResult4 |
|||
bl __gmpz_set |
|||
add x21,x21,#1 // increment indice |
|||
cmp x21,x19 // N ? |
|||
ble 1b // no -> loop |
|||
ldr x0,qAdrResult4 |
|||
ldp x20,x21,[sp],16 // restaur 2 registers |
|||
ldp x19,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
qAdrResult4: .quad Result4 |
|||
/********************************************************/ |
|||
/* File Include fonctions */ |
|||
/********************************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly */ |
|||
.include "../includeARM64.inc" |
|||
</lang> |
|||
<pre> |
|||
Program 64 bits start. |
|||
96 |
|||
5122560 |
|||
190722470400 |
|||
7574824857600000 |
|||
312546150372456000000 |
|||
13207874703225491420651520 |
|||
567273919793089083292259942400 |
|||
24650600248172987140112763715584000 |
|||
1080657854354639453670407474439566400000 |
|||
47701779391594966287470570490839978880000000 |
|||
PI = |
|||
3.1415926535897932384626433832795028841971693993751058209749445923078164 |
|||
</pre> |
</pre> |
||
=={{header|ARM Assembly}}== |
=={{header|ARM Assembly}}== |