A fim de futuramente criar uma aplicação voltada a eventos e localização.
Tentei fazer o uso do NEON, para que fosse mais performático, utilizei IA para ajudar no desenvolvimento mas ainda não tive a oportunidade de testar.
Se não me engano será compatível com qualquer armv8 em diante. Isso inclui raspberry pi 3 e acima.
// +build arm64
#include "textflag.h"
// func EncodeInt(lat, lng float64) uint64
TEXT ·EncodeInt(SB), NOSPLIT, $0-24
// Verifica se devemos usar o assembly
LDRB R0, ·useAsm(SB)
CMP R0, #1
BNE fallback
// Definições
#define V_LATLNG V0 // vetor com lat, lng
#define V_SCALE V1 // vetor com fatores de escala
#define V_ADD V2 // vetor com fatores de adição
#define V_TMP V3
#define V_INT V4
// Carrega lat e lng para V0 (D0 e D1)
LDR D0, lat+0(FP)
LDR D1, lng+8(FP)
// Prepara os vetores escala e soma
MOVI V1.2D, #0
FMOV D2, #0.005555555555555556
INS V1.D[0], D2
FMOV D2, #0.002777777777777778
INS V1.D[1], D2
MOVI V2.2D, #0
FMOV D3, #1.5
INS V2.D[0], D3
INS V2.D[1], D3
// Multiplica lat/lng por fator de escala
FMUL V0.2D, V0.2D, V1.2D
// Soma fator de adição
FADD V0.2D, V0.2D, V2.2D
// Converte para inteiros
FCVTZS V4.2D, V0.2D
// Agora R1 = LATI, R2 = LNGI
MOV R1, V4.D[0]
MOV R2, V4.D[1]
// Shift right 20 bits
LSR R1, R1, #20
LSR R2, R2, #20
// Agora vamos entrelaçar os bits de forma manual
// (Interleaving bits entre LATI e LNGI)
MOV R3, R1
MOV R4, R2
// Entrelaçamento manual
MOV R5, $0
MOV R6, $0
MOV R7, $0
MOV R8, $0
// Loop de intercalamento dos bits (não muito bonito mas eficiente)
MOV R9, $0
interleave_loop:
CMP R9, #32
BGE interleave_done
// Pega 1 bit de LATI
ANDS R10, R3, $1
LSL R10, R10, R9
ORR R5, R5, R10
// Pega 1 bit de LNGI
ANDS R10, R4, $1
LSL R10, R10, R9
LSL R10, R10, #1
ORR R6, R6, R10
// Avança bits
LSR R3, R3, #1
LSR R4, R4, #1
ADD R9, R9, #2
B interleave_loop
interleave_done:
// Resultado
EOR R0, R5, R6
// Salva
STR R0, ret+16(FP)
RET
fallback:
B ·encodeInt(SB)
#Go #Geohash #ASM