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}} |