Abelian sandpile model/Identity: Difference between revisions

add task to aarch64 assembly
(add task to Arm assembly)
(add task to aarch64 assembly)
Line 57:
* https://www.youtube.com/watch?v=1MtEUErz7Gg
* https://en.wikipedia.org/wiki/Abelian_sandpile_model
 
=={{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 or android 64 bits */
/* program abelianSum64.s */
 
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ MAXI, 3
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessValue: .asciz "@ "
szMessAdd1: .asciz "Add sandpile 1 to sandpile 2 \n"
szMessAdd2: .asciz "Add sandpile 2 to sandpile 1 \n"
szMessAdd2A: .asciz "Add sandpile 2A to sandpile result \n"
szMessAdd3: .asciz "Add sandpile 3 to sandpile 3ID \n"
szMessAdd3ID: .asciz "Add sandpile 3ID to sandpile 3ID \n"
 
szCarriageReturn: .asciz "\n"
 
qSandPile1: .quad 1,2,0
.quad 2,1,1
.quad 0,1,3
qSandPile2: .quad 2,1,3
.quad 1,0,1
.quad 0,1,0
 
qSandPile2A: .quad 1,0,0
.quad 0,0,0
.quad 0,0,0
qSandPile3: .quad 3,3,3
.quad 3,3,3
.quad 3,3,3
qSandPile3ID: .quad 2,1,2
.quad 1,0,1
.quad 2,1,2
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
qSandPilex1: .skip 8 * MAXI * MAXI
qSandPilex2: .skip 8 * MAXI * MAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
 
ldr x0,qAdrqSandPile1 // sandpile1 address
ldr x1,qAdrqSandPile2 // sandpile2 address
ldr x2,qAdrqSandPilex1 // sandpile result address
bl addSandPile
ldr x0,qAdrszMessAdd1 // display message
bl affichageMess
ldr x0,qAdrqSandPilex1 // display sandpile
bl displaySandPile
ldr x0,qAdrqSandPile2 // sandpile2 address
ldr x1,qAdrqSandPile1 // sandpile1 address
ldr x2,qAdrqSandPilex1 // sandpile result address
bl addSandPile
ldr x0,qAdrszMessAdd2
bl affichageMess
ldr x0,qAdrqSandPilex1
bl displaySandPile
ldr x0,qAdrqSandPilex1 // sandpile1 address
ldr x1,qAdrqSandPile2A // sandpile2A address
ldr x2,qAdrqSandPilex2 // sandpile result address
bl addSandPile
ldr x0,qAdrszMessAdd2A
bl affichageMess
ldr x0,qAdrqSandPilex2
bl displaySandPile
ldr x0,qAdrqSandPile3 // sandpile3 address
ldr x1,qAdrqSandPile3ID // sandpile3ID address
ldr x2,qAdrqSandPilex2 // sandpile result address
bl addSandPile
ldr x0,qAdrszMessAdd3
bl affichageMess
ldr x0,qAdrqSandPilex2
bl displaySandPile
ldr x0,qAdrqSandPile3ID // sandpile3 address
ldr x1,qAdrqSandPile3ID // sandpile3ID address
ldr x2,qAdrqSandPilex2 // sandpile result address
bl addSandPile
ldr x0,qAdrszMessAdd3ID
bl affichageMess
ldr x0,qAdrqSandPilex2
bl displaySandPile
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsZoneConv: .quad sZoneConv
qAdrszMessAdd1: .quad szMessAdd1
qAdrszMessAdd2: .quad szMessAdd2
qAdrszMessAdd2A: .quad szMessAdd2A
qAdrszMessAdd3: .quad szMessAdd3
qAdrszMessAdd3ID: .quad szMessAdd3ID
qAdrqSandPile1: .quad qSandPile1
qAdrqSandPilex1: .quad qSandPilex1
qAdrqSandPilex2: .quad qSandPilex2
qAdrqSandPile2: .quad qSandPile2
qAdrqSandPile2A: .quad qSandPile2A
qAdrqSandPile3: .quad qSandPile3
qAdrqSandPile3ID: .quad qSandPile3ID
/***************************************************/
/* add two sandpile */
/***************************************************/
// x0 contains address to sandpile 1
// x1 contains address to sandpile 2
// x2 contains address to sandpile result
addSandPile:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x6,x1 // save addresse sandpile2
mov x1,x2 // and copy sandpile 1 to sandpile result
bl copySandPile
mov x0,x2 // sanspile result
mov x2,#0 // indice y
mov x4,#MAXI
1:
mov x1,#0 // indice x
2:
madd x5,x2,x4,x1 // compute offset
ldr x7,[x0,x5,lsl #3] // load value at pos x,y sanspile result
ldr x3,[x6,x5,lsl #3] // load value at pos x,y sandpile 2
add x7,x7,x3
str x7,[x0,x5,lsl #3] // store sum on sandpile result
bl avalancheRisk
add x1,x1,#1
cmp x1,#MAXI
blt 2b
add x2,x2,#1
cmp x2,#MAXI
blt 1b
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* copy sandpile */
/***************************************************/
// x0 contains address to sandpile
// x1 contains address to sandpile result
copySandPile:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x2,#0 // indice y
mov x3,#MAXI
1:
mov x4,#0 // indice x
2:
madd x5,x2,x3,x4 // compute offset
ldr x6,[x0,x5,lsl #3] // load value at pos x,y sanspile
str x6,[x1,x5,lsl #3] // store value at pos x,y sandpile result
add x4,x4,#1
cmp x4,#MAXI
blt 2b
add x2,x2,#1
cmp x2,#MAXI
blt 1b
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* display sandpile */
/***************************************************/
// x0 contains address to sandpile
displaySandPile:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x6,x0
mov x3,#0 // indice y
mov x4,#MAXI
1:
mov x2,#0 // indice x
2:
madd x5,x3,x4,x2 // compute offset
ldr x0,[x6,x5,lsl #3] // load value at pos x,y
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
add x1,x1,#1
mov x7,#0
strb w7,[x1,x0]
ldr x0,qAdrszMessValue
ldr x1,qAdrsZoneConv // insert value conversion in message
bl strInsertAtCharInc
bl affichageMess
add x2,x2,#1
cmp x2,#MAXI
blt 2b
ldr x0,qAdrszCarriageReturn
bl affichageMess
add x3,x3,#1
cmp x3,#MAXI
blt 1b
 
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrszMessValue: .quad szMessValue
/***************************************************/
/* avalanche risk */
/***************************************************/
// x0 contains address to sanspile
// x1 contains position x
// x2 contains position y
avalancheRisk:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
mov x3,#MAXI
madd x4,x3,x2,x1
ldr x5,[x0,x4,lsl #3]
1:
cmp x5,#4 // 4 grains ?
blt 100f
sub x5,x5,#4 // yes sustract
str x5,[x0,x4,lsl #3]
cmp x1,#MAXI-1 // right position ok ?
beq 2f
add x1,x1,#1 // yes
bl add1Sand // add 1 grain
bl avalancheRisk // and compute new pile
sub x1,x1,#1
2:
cmp x1,#0 // left position ok ?
beq 3f
sub x1,x1,#1
bl add1Sand
bl avalancheRisk
add x1,x1,#1
3:
cmp x2,#0 // higt position ok ?
beq 4f
sub x2,x2,#1
bl add1Sand
bl avalancheRisk
add x2,x2,#1
4:
cmp x2,#MAXI-1 // low position ok ?
beq 5f
add x2,x2,#1
bl add1Sand
bl avalancheRisk
sub x2,x2,#1
5:
ldr x5,[x0,x4,lsl #3] // reload value
b 1b // and loop
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* add 1 grain of sand */
/***************************************************/
// x0 contains address to sanspile
// x1 contains position x
// x2 contains position y
add1Sand:
stp x3,lr,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
mov x3,#MAXI
madd x4,x3,x2,x1
ldr x5,[x0,x4,lsl #3] // load value at pos x,y
add x5,x5,#1
str x5,[x0,x4,lsl #3] // and store
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x3,lr,[sp],16 // restaur des 2 registres
ret
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</lang>
{{Output}}
<pre>
~/.../rosetta/asm1 $ abelianSum64
Add sandpile 1 to sandpile 2
3 3 3
3 1 2
0 2 3
Add sandpile 2 to sandpile 1
3 3 3
3 1 2
0 2 3
Add sandpile 2A to sandpile result
2 1 0
0 3 3
1 2 3
Add sandpile 3 to sandpile 3ID
3 3 3
3 3 3
3 3 3
Add sandpile 3ID to sandpile 3ID
2 1 2
1 0 1
2 1 2
</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}