Angle difference between two bearings: Difference between revisions

Content added Content deleted
(add task to arm assembly raspberry pi)
(add task to aarch64 assembly raspberry pi)
Line 132: Line 132:
-78.3251 -159.0360 -80.7109
-78.3251 -159.0360 -80.7109
</pre>
</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 diffAngle64.s */


/************************************/
/* Constantes */
/************************************/
.include "../includeConstantesARM64.inc"

/*********************************/
/* Initialized data */
/*********************************/
.data
szCarriageReturn: .asciz "\n"
szMessResult: .asciz "Difference between @ and @ = @ \n"

.align 8
fB1: .double 0F20.0
fB2: .double 0F45.0
fB3: .double 0F-45.0
fB4: .double 0F-85.0
fB5: .double 90.0
fB6: .double -95.0
fB7: .double 125.0
fB8: .double 145.0
fB9: .double 0F29.4803
fB10: .double 0F-88.6381
fB11: .double 0F-78.3251
fB12: .double 0F-159.036
fB13: .double 0F-70099.74233810938
fB14: .double 0F29840.67437876723

/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main:
ldr x0,qAdrfB1
ldr x1,qAdrfB2
bl testComputeAngle
//b 100f
ldr x0,qAdrfB3
ldr x1,qAdrfB2
bl testComputeAngle
ldr x0,qAdrfB4
ldr x1,qAdrfB5
bl testComputeAngle
ldr x0,qAdrfB6
ldr x1,qAdrfB5
bl testComputeAngle

ldr x0,qAdrfB3
ldr x1,qAdrfB7
bl testComputeAngle
ldr x0,qAdrfB3
ldr x1,qAdrfB8
bl testComputeAngle
ldr x0,qAdrfB9
ldr x1,qAdrfB10
bl testComputeAngle

ldr x0,qAdrfB11
ldr x1,qAdrfB12
bl testComputeAngle

ldr x0,qAdrfB13
ldr x1,qAdrfB14
bl testComputeAngle

100: // standard end of the program
mov x0, #0 // return code
mov x8,EXIT
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsZoneConv: .quad sZoneConv
qAdrfB1: .quad fB1
qAdrfB2: .quad fB2
qAdrfB3: .quad fB3
qAdrfB4: .quad fB4
qAdrfB5: .quad fB5
qAdrfB6: .quad fB6
qAdrfB7: .quad fB7
qAdrfB8: .quad fB8
qAdrfB9: .quad fB9
qAdrfB10: .quad fB10
qAdrfB11: .quad fB11
qAdrfB12: .quad fB12
qAdrfB13: .quad fB13
qAdrfB14: .quad fB14
/******************************************************************/
/* compute difference and display result */
/******************************************************************/
/* s0 contains bearing 1 */
/* s1 contains bearing 2 */
testComputeAngle:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
ldr d0,[x0]
fmov d2,d0
ldr d1,[x1]
bl computeDiffAngle
fmov d3,d0
fmov d0,d2
ldr x0,qAdrsZoneConv
bl convertirFloat
ldr x0,qAdrszMessResult
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc
mov x3,x0
fmov d0,d1
ldr x0,qAdrsZoneConv
bl convertirFloat
mov x0,x3
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc
mov x3,x0
fmov d0,d3
ldr x0,qAdrsZoneConv
bl convertirFloat
mov x0,x3
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc
bl affichageMess
100:
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
qAdrszMessResult: .quad szMessResult
/******************************************************************/
/* compute difference of two bearing */
/******************************************************************/
/* d0 contains bearing 1 */
/* d1 contains bearing 2 */
computeDiffAngle:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp d1,d2,[sp,-16]! // save registres
stp d3,d4,[sp,-16]! // save registres
mov x1,#360
mov x4,#0 // top positive/negative
fcvtzs d4,d0 // conversion.integer
scvtf d2,d4 // conversion float
fsub d2,d0,d2 // partie décimale
fmov x0,d4 // partie entière
cmp x0,#0 // negative ?
bge 1f
neg x0,x0 // yes -> inversion
mov x4,#1
1:
udiv x2,x0,x1 // divide by 360
msub x3,x2,x1,x0
cmp x4,#0 // value negative ?
neg x5,x3
csel x3,x5,x3,ne // inversion remainder
fmov d3,x3
scvtf d3,d3 // and conversion float
fadd d0,d3,d2 // add decimal part
mov x4,#0 // bearing 2
fcvtzs d4,d1 // conversion integer
scvtf d2,d4 // conversion float
fsub d2,d1,d2 // partie décimale
fmov x0,d4
cmp x0,#0
bge 2f
neg x0,x0
mov x4,#1
2:
udiv x2,x0,x1 // divide by 360
msub x3,x2,x1,x0
cmp x4,#0
neg x5,x3
csel x3,x5,x3,ne // inversion remainder
fmov d3,x3
scvtf d3,d3 // conversion float
fadd d1,d3,d2
fsub d0,d1,d0 // calculate the difference between the 2 values
mov x0,180
fmov d3,x0
scvtf d3,d3 // conversion float 180
fmov d4,x1 // 360
scvtf d4,d4 // conversion float 360
fcmp d0,#0.0 // difference is negative ?
blt 2f
// difference is positive
fcmp d0,d4 // difference > 360
ble 3f
fsub d0,d0,d4 // yes -> difference - 360
3:
fcmp d0,d3 // compare difference and 180
ble 100f
fsub d0,d4,d0 // > 180 calculate 360 - difference
fneg d0,d0 // and negate
b 100f

2: // différence is négative
fneg d2,d4 // -360
fcmp d0,d2 // compare différence et - 360
ble 3f
fsub d0,d0,d4 // sub 360 to différence
3:
fneg d3,d3 // -180
fcmp d0,d3 // compare difference and -180
bge 100f
fadd d0,d4,d0 // calculate 360 + différence

100:
ldp d3,d4,[sp],16 // restaur registers
ldp d1,d2,[sp],16 // restaur registers
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret

/******************************************************************/
/* Conversion Float */
/******************************************************************/
/* d0 contains Float */
/* x0 contains address conversion area mini 20 charactèrs */
/* x0 return result length */
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
convertirFloat:
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
stp x8,x9,[sp,-16]! // save registres
stp d1,d2,[sp,-16]! // save registres
mov x6,x0 // save area address
fmov x0,d0
mov x8,#0 // result length
mov x3,#'+'
strb w3,[x6] // signe + forcing
mov x2,x0
tbz x2,63,1f
mov x2,1
lsl x2,x2,63
bic x0,x0,x2
mov x3,#'-' // sign -
strb w3,[x6]
1:
adds x8,x8,#1 // next position
cmp x0,#0 // case 0 positive or negative
bne 2f
mov x3,#'0'
strb w3,[x6,x8] // store character 0
adds x8,x8,#1
strb wzr,[x6,x8] // store 0 final
mov x0,x8 // return length
b 100f
2:
ldr x2,iMaskExposant
mov x1,x0
and x1,x1,x2 // exposant
cmp x1,x2
bne 4f
tbz x0,51,3f // test bit 51 to zéro
mov x2,#'N' // case Nan. store byte no possible store integer
strb w2,[x6] // area no aligned
mov x2,#'a'
strb w2,[x6,#1]
mov x2,#'n'
strb w2,[x6,#2]
mov x2,#0 // 0 final
strb w2,[x6,#3]
mov x0,#3
b 100f
3: // case infini positive or négative
mov x2,#'I'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#'n'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#'f'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#0
strb w2,[x6,x8]
mov x0,x8
b 100f
4:
bl normaliserFloat
mov x5,x0 // save exposant
fcvtzu d2,d0
fmov x0,d2 // part integer
scvtf d1,d2 // conversion float
fsub d1,d0,d1 // extraction part fractional
ldr d2,dConst1
fmul d1,d2,d1 // to crop it in full
fcvtzu d1,d1 // convertion integer
fmov x4,d1 // fract value
// conversion part integer to x0
mov x2,x6 // save address begin area
adds x6,x6,x8
mov x1,x6
bl conversion10
add x6,x6,x0
mov x3,#','
strb w3,[x6]
adds x6,x6,#1
mov x0,x4 // conversion part fractionnaire
mov x1,x6
bl conversion10SP
add x6,x6,x0
sub x6,x6,#1
// remove trailing zeros
5:
ldrb w0,[x6]
cmp w0,#'0'
bne 6f
sub x6,x6,#1
b 5b
6:
cmp w0,#','
bne 7f
sub x6,x6,#1
7:
cmp x5,#0 // if exposant = 0 no display
bne 8f
add x6,x6,#1
b 10f
8:
add x6,x6,#1
mov x3,#'E'
strb w3,[x6]
add x6,x6,#1
mov x0,x5 // conversion exposant
mov x3,x0
tbz x3,63,9f // exposant negative ?
neg x0,x0
mov x3,#'-'
strb w3,[x6]
adds x6,x6,#1
9:
mov x1,x6
bl conversion10
add x6,x6,x0
10:
strb wzr,[x6] // store 0 final
adds x6,x6,#1
mov x0,x6
subs x0,x0,x2 // retour de la longueur de la zone
subs x0,x0,#1 // sans le 0 final

100:
ldp d1,d2,[sp],16 // restaur registres
ldp x8,x9,[sp],16 // restaur registres
ldp x6,x7,[sp],16 // restaur registres
ldp x4,x5,[sp],16 // restaur registres
ldp x2,x3,[sp],16 // restaur registres
ldp x1,lr,[sp],16 // restaur registres
ret
iMaskExposant: .quad 0x7FF<<52
dConst1: .double 0f1E17

/***************************************************/
/* normaliser float */
/***************************************************/
/* x0 contain float value (always positive value and <> Nan) */
/* d0 return new value */
/* x0 return exposant */
normaliserFloat:
stp x1,lr,[sp,-16]! // save registers
fmov d0,x0 // value float
mov x0,#0 // exposant
ldr d1,dConstE7 // no normalisation for value < 1E7
fcmp d0,d1
blo 10f // if d0 < dConstE7
ldr d1,dConstE256
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#256
1:
ldr d1,dConstE128
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#128
1:
ldr d1,dConstE64
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#64
1:
ldr d1,dConstE32
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#32
1:
ldr d1,dConstE16
fcmp d0,d1
blo 2f
fdiv d0,d0,d1
adds x0,x0,#16
2:
ldr d1,dConstE8
fcmp d0,d1
blo 3f
fdiv d0,d0,d1
adds x0,x0,#8
3:
ldr d1,dConstE4
fcmp d0,d1
blo 4f
fdiv d0,d0,d1
adds x0,x0,#4
4:
ldr d1,dConstE2
fcmp d0,d1
blo 5f
fdiv d0,d0,d1
adds x0,x0,#2
5:
ldr d1,dConstE1
fcmp d0,d1
blo 10f
fdiv d0,d0,d1
adds x0,x0,#1

10:
ldr d1,dConstME5 // pas de normalisation pour les valeurs > 1E-5
fcmp d0,d1
bhi 100f // fin
ldr d1,dConstME255
fcmp d0,d1
bhi 11f
ldr d1,dConstE256

fmul d0,d0,d1
subs x0,x0,#256
11:
ldr d1,dConstME127
fcmp d0,d1
bhi 11f
ldr d1,dConstE128

fmul d0,d0,d1
subs x0,x0,#128
11:
ldr d1,dConstME63
fcmp d0,d1
bhi 11f
ldr d1,dConstE64

fmul d0,d0,d1
subs x0,x0,#64
11:
ldr d1,dConstME31
fcmp d0,d1
bhi 11f
ldr d1,dConstE32

fmul d0,d0,d1
subs x0,x0,#32
11:
ldr d1,dConstME15
fcmp d0,d1
bhi 12f
ldr d1,dConstE16
fmul d0,d0,d1
subs x0,x0,#16
12:
ldr d1,dConstME7
fcmp d0,d1
bhi 13f
ldr d1,dConstE8
fmul d0,d0,d1
subs x0,x0,#8
13:
ldr d1,dConstME3
fcmp d0,d1
bhi 14f
ldr d1,dConstE4
fmul d0,d0,d1
subs x0,x0,#4
14:
ldr d1,dConstME1
fcmp d0,d1
bhi 15f
ldr d1,dConstE2
fmul d0,d0,d1
subs x0,x0,#2
15:
ldr d1,dConstE0
fcmp d0,d1
bhi 100f
ldr d1,dConstE1
fmul d0,d0,d1
subs x0,x0,#1

100: // fin standard de la fonction
ldp x1,lr,[sp],16 // restaur registres
ret
.align 2
dConstE7: .double 0f1E7
dConstE256: .double 0f1E256
dConstE128: .double 0f1E128
dConstE64: .double 0f1E64
dConstE32: .double 0f1E32
dConstE16: .double 0f1E16
dConstE8: .double 0f1E8
dConstE4: .double 0f1E4
dConstE2: .double 0f1E2
dConstE1: .double 0f1E1
dConstME5: .double 0f1E-5
dConstME255: .double 0f1E-255
dConstME127: .double 0f1E-127
dConstME63: .double 0f1E-63
dConstME31: .double 0f1E-31
dConstME15: .double 0f1E-15
dConstME7: .double 0f1E-7
dConstME3: .double 0f1E-3
dConstME1: .double 0f1E-1
dConstE0: .double 0f1E0

/******************************************************************/
/* Décimal Conversion */
/******************************************************************/
/* x0 contain value et x1 address conversion area */
conversion10SP:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
mov x5,x1
mov x4,#16
mov x2,x0
mov x1,#10 // décimal conversion
1: // conversion loop
mov x0,x2 // copy begin number or quotient
udiv x2,x0,x1 // division by 10
msub x3,x1,x2,x0 // compute remainder
add x3,x3,#48 // compute digit
strb w3,[x5,x4] // store byte address area (x5) + offset (x4)
subs x4,x4,#1 // position precedente
bge 1b
strb wzr,[x5,16] // 0 final
100:
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../includeARM64.inc"
</lang>
<pre>
Difference between +20 and +45 = +25
Difference between -45 and +45 = +90
Difference between -85 and +90 = +175
Difference between -95 and +90 = -175
Difference between -45 and +125 = +170
Difference between -45 and +145 = -170
Difference between +29,4802 and -88,638099 = -118,1
Difference between -78,325 and -159 = -80,7108999
Difference between -70099,7423381 and +29840,674378 = -139,58328
</pre>
=={{header|Action!}}==
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
{{libheader|Action! Tool Kit}}