Autor Tema: Assembler en ARM - Probando  (Leído 19849 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #30 en: 12 de Octubre de 2015, 18:30:08 »
Que sería eso del align? Imagino que es para que todas las instrucciones se acomoden en 32 bits, pero prácticamente como sería el tema?

Podrías intentar una función que tome un uint64 e invierta la posición de cada bit? El que esta en la posición 0 va a la pos 64 el del 1 a la pos 63 y así? Si fuese posible invertir la posición de 48 de los 64 bits mejor. Sería para reemplazar los for que tengo para enviar los datos y trabajar directamente con memoria para sacar los datos por spi...

Saludos!
-
Leonardo Garberoglio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #31 en: 12 de Octubre de 2015, 18:56:03 »
el align es ( ya lo dije en el dsPIC xD ) una directiva que sirve para alinear datos/memoria.

Cuando vos haces un .align 2 (siempre potencias de 2 ) lo que estas haciendo es forzar a que lo siguiente se ubique en la posicion de memoria  multiplo de 2. Normalmente en el ARM estamos en presencia siempre de un align 2 (si es que son de 16 bits) si observas la direccion (columna izquierda del codigo que pase)

Código: ASM
  1. 0:   b470            push    {r4, r5, r6}
  2.    2:   4813            ldr     r0, [pc, #76]   ; (50 <Funcion+0x50>)
  3.    4:   2125            movs    r1, #37 ; 0x25
  4.    6:   2208            movs    r2, #8
  5.    8:   2400            movs    r4, #0

Son multiplos de 2, 0000 , 0010 ,0110 , 1000 ( el ultimo bit en 0)
Cuando tenemos un dato de 32 bits, si no alineamos a multiplos de 4, ocurriria esto:

Código: ASM
  1. 50:   46c0            nop                     ; (mov r8, r8)
  2.   52:   4545            .short  0x4545
  3.   54:   00003232        .word   0x00003232
  4.   58:   5fffffe0        .word   0x5fffffe0

Como se ve ahi en ese caso agregue un NOP a proposito y cree un .word al final con el valor 0x32324545 , al menos asi estaba en mi codigo, como no estaba bien alineado termine con mitad por un lado y mitad por el otro. No es lo que yo queria, si yo pongo un .align 4, el programa al ver que estaba en 0x52 ( 0101 0010) hubiera intentado acomodarse a esto buscando la proxima direccion de memoria multiplo de 4, es decir 0x54 ( 0101 0100). Como le respondo a Carl47D aqui no vi todavia instrucciones que especificamente accedan a Words, Half-Words, bytes, pero si en el dsPIC el cual usar una instruccion que esta preparada para un Half-Word y hacerla acceder a una direccion que no es multiplo de 2 ( 16 bits ) termina en una excepcion, o error de direccion. Aqui todavia no prove eso.

Lo que puedo observar es que las instrucciones Thumb2 uno pensaria que es obligacion ponerlas en una alineacion de 32 bits, pero estas  no son de 32, sino que se toman como 2 de 16 bits, por eso mismo hacer esto:

Código: ASM
  1. e:   681e            ldr     r6, [r3, #0]
  2.   10:   ea5f 0131       movs.w  r1, r1, rrx

O ponerle un NOP entre medio quedando asi:

Código: ASM
  1. e:      681e            ldr     r6, [r3, #0]
  2.   10:   46c0            nop                     ; (mov r8, r8)
  3.   12:   ea5f 0131       movs.w  r1, r1, rrx

Sin ningun problema

Citar
Podrías intentar una función que tome un uint64 e invierta la posición de cada bit? El que esta en la posición 0 va a la pos 64 el del 1 a la pos 63 y así? Si fuese posible invertir la posición de 48 de los 64 bits mejor. Sería para reemplazar los for que tengo para enviar los datos y trabajar directamente con memoria para sacar los datos por spi...
OK ahi veo el set de instrucciones como hacerlo

Creo que la instruccion RBIT de Thumb2 es la solucion :P

For (i = 0; i < 32; i++) : Rd = Rm[31– i]

Solo restaria acomodar los valores.
« Última modificación: 12 de Octubre de 2015, 18:59:55 por KILLERJC »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #32 en: 12 de Octubre de 2015, 23:30:28 »
No se que tan errado este en el funcionamiento del programa, eso seria para invertir los bits

Código: ASM
  1. .syntax unified
  2.         .thumb
  3.         .text
  4.         .global Invertir
  5.  
  6.  
  7. ;@Funcion ASM que invierte los 49bits de una variable de 64bits
  8. ;@ Entrada R1:R0
  9. ;@ Salida R1:R0 Variable de 64 bits
  10.  
  11. Invertir:
  12.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  13.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  14.         LSRS    R2, R2, #15             ;@ R2 = Inv(R1) >> 15
  15.         UBFX    R3, R0, #0 ,#14         ;@ R3 = R0[14:0]
  16.         ADD.W   R3, R2, R3, LSL #17     ;@ R3 = R0[14:0] + Inv(R1)>>15 = Bajo Invertido Final
  17.         LSLS    R1, R0, #15             ;@ R1 = R0[31:15]>>15 = Alto invertido Final
  18.         MOVS    R0, R1                  ;@ R0 = Bajo Invertido Final
  19.         BX      LR                      ;@ Voler
  20.         .end
  21.  
  22. ;@ Normal
  23.  
  24. ;@ 0x0001.1234.5678.9ABC ->
  25.  
  26. ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100
  27. ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100
  28.  
  29. ;@ Invertido:
  30.  
  31. ;@ 0x0000.7AB2.3CD4.5891
  32.  
  33. ;@ Alto R1 0000 0000 0000 000,0 0111 1010 1011 0010
  34. ;@ Bajo R0 0011 1100 1101 010,0 0101 1000 1001 0001
  35.  
  36. ;@ Normal invertido pero cada uno Despues del RBIT:
  37.  
  38. ;@ Alto R1 0010 1100 0100 1000 1000 0000 0000 0000
  39. ;@ Bajo R0 0011 1101 0101 1001 0,001 1110 0110 1010
  40.  
  41. ;@ Shift R1>>15
  42. ;@ Alto R1 0000 0000 0000 000,0 0101 1000 1001 0001

Aunque seguro que si uso un par de Rotate sea mas corto... Ya voy a ver si logro hacerlo mas corto aun. lo que si puedo tener errores en el tema de los desplazamientos. esta complicado dividir todo por parte xD
Ahi utilize el Rotate y quedo mas corto. Sigo teniendo problemas para encontrarle la vuelta a esto de las funciones. No son demasiados claros, ni dan ejemplos ni nada, solo te ponen un pseudocodigo que tenes que adivinar que es.

Código: ASM
  1. Invertir:
  2.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  3.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  4.         RORS    R0, R0, #15             ;@ R0 = Inv(R0) >> 15 Wrap
  5.         UBFX    R1, R0, #0 ,#17         ;@ R1f = R0[16:0] = Alto invertido Final
  6.         LSL     R2, R2, #15             ;@ R2 = R2>>15 = R0f[16:0]
  7.         BFI     R0, R2, #0, #17         ;@ R0 = R0f[32:17] + R0f[16:0]
  8.         BX      LR                      ;@ Volver
  9.         .end
  10.  
  11. ;@ Normal
  12.  
  13. ;@ 0x0001.1234.5678.9ABC ->
  14.  
  15. ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100
  16. ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100
  17.  
  18. ;@ Invertido:
  19.  
  20. ;@ 0x0000.7AB2.3CD4.5891
  21.  
  22. ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010
  23. ;@ Bajo R0 0011 1100 1101 0100 0101 1000 1001 0001
  24.  
  25. ;@ Normal invertido pero cada uno Despues del RBIT:
  26.  
  27. ;@ Alto R2 0010 1100 0100 1000 1.000 0000 0000 0000
  28. ;@ Bajo R0 0011 1101 0101 1001 0001 1110 0110 1010
  29.  
  30. ;@ ROR R0>>15 = R0[32:17] + R1
  31. ;@ 0011 1100 1101 010.0 0111 1010 1011 0010
  32.  
  33. ;@ UBFX R1, R0, #0, #16
  34. ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010 - Final
  35.  
  36. ;@ LSL  R2, R2, #15
  37. ;@ R2 = 0000 0000 0000 0000 0101 1000 1001 0001

Sorprendentemente logre que compilara bien al instante, que sea correcto eso SI que no tengo ni idea.
Esto de no tener un maldito simulador de ARM lo estoy odiando. Si hay o son para ASM ARM o para micros de 5mil años atras. Y no tengo ganas de instalar QEMU e.e
« Última modificación: 13 de Octubre de 2015, 00:19:14 por KILLERJC »

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Re:Assembler en ARM - Probando
« Respuesta #33 en: 13 de Octubre de 2015, 00:29:40 »
Lo que queda es simularla en Keil?
En lo que se encuentra algo para el GNU ASM

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #34 en: 13 de Octubre de 2015, 01:09:21 »
Windows XP SP3, Windows Vista or Windows 7

Uff.. adios simulador

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Re:Assembler en ARM - Probando
« Respuesta #35 en: 13 de Octubre de 2015, 01:30:13 »
Olvide que tienes Ubuntu, igual y el link te sirve, algo viejo (2013) pero es lo unico que encontré, igual y Juanjo puede ayudarte, en resumen usa Wine Keil 4 on Ubuntu.

O trato de hacer la prueba en el Keil que tengo, nada mas hago funcionar el codigo del delay xD
Me tira este error
Citar
delay.s(1): error: A1137E: Unexpected characters at end of line


EDIT: Son las directivas de Keil, por ejemplo en GNU es .thumb en Keil THUMB, .end en GNU y END en Keil -.-
« Última modificación: 13 de Octubre de 2015, 01:55:06 por Carl47D »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #36 en: 13 de Octubre de 2015, 02:05:38 »
Pero a keil lo podes hacer funcionar con GCC, busca "GCC Keil" y ahi te aparece donde tildar para que use el toolchain de GCC

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:Assembler en ARM - Probando
« Respuesta #37 en: 13 de Octubre de 2015, 07:35:31 »
Keil? IAR? pffff les puse una cruz hace muchisimo tiempo, por ser de terceros, por ser de pago y en el caso de IAR por ser una mierd@

yo probaría con un IDE propio de un micro para ARM, y lo mas seguro es que tenga simulador y debug como en el caso de microchip.

así de primeras y para linux se me ocurre KDS kinetic desing studio, el IDE GNU  GCCgratuito para los micros ARM de freescale, tiene su versión para linux no lo he probado, pero como pienso migrar dentro de no demasiado tiempo (espero) lo tengo en el tintero, espero que tenga emulador.

o si estamos hablando de ARM por que no acudir a la fuente y instalar su IDE el ARM-DS5 la  "Community Edition" es gratuita, y como el KDS basado en GCC y eclipse, y tambien disponible para linux

también estaría bien el de atmel por que como el de KDS lo mantiene la propia empresa y es gratis, pero los estupi... no sacan la versión para linux


un saludo.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #38 en: 13 de Octubre de 2015, 09:08:20 »
No se que tan errado este en el funcionamiento del programa, eso seria para invertir los bits

Código: ASM
  1. .syntax unified
  2.         .thumb
  3.         .text
  4.         .global Invertir
  5.  
  6.  
  7. ;@Funcion ASM que invierte los 49bits de una variable de 64bits
  8. ;@ Entrada R1:R0
  9. ;@ Salida R1:R0 Variable de 64 bits
  10.  
  11. Invertir:
  12.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  13.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  14.         LSRS    R2, R2, #15             ;@ R2 = Inv(R1) >> 15
  15.         UBFX    R3, R0, #0 ,#14         ;@ R3 = R0[14:0]
  16.         ADD.W   R3, R2, R3, LSL #17     ;@ R3 = R0[14:0] + Inv(R1)>>15 = Bajo Invertido Final
  17.         LSLS    R1, R0, #15             ;@ R1 = R0[31:15]>>15 = Alto invertido Final
  18.         MOVS    R0, R1                  ;@ R0 = Bajo Invertido Final
  19.         BX      LR                      ;@ Voler
  20.         .end
  21.  
  22. ;@ Normal
  23.  
  24. ;@ 0x0001.1234.5678.9ABC ->
  25.  
  26. ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100
  27. ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100
  28.  
  29. ;@ Invertido:
  30.  
  31. ;@ 0x0000.7AB2.3CD4.5891
  32.  
  33. ;@ Alto R1 0000 0000 0000 000,0 0111 1010 1011 0010
  34. ;@ Bajo R0 0011 1100 1101 010,0 0101 1000 1001 0001
  35.  
  36. ;@ Normal invertido pero cada uno Despues del RBIT:
  37.  
  38. ;@ Alto R1 0010 1100 0100 1000 1000 0000 0000 0000
  39. ;@ Bajo R0 0011 1101 0101 1001 0,001 1110 0110 1010
  40.  
  41. ;@ Shift R1>>15
  42. ;@ Alto R1 0000 0000 0000 000,0 0101 1000 1001 0001

Aunque seguro que si uso un par de Rotate sea mas corto... Ya voy a ver si logro hacerlo mas corto aun. lo que si puedo tener errores en el tema de los desplazamientos. esta complicado dividir todo por parte xD
Ahi utilize el Rotate y quedo mas corto. Sigo teniendo problemas para encontrarle la vuelta a esto de las funciones. No son demasiados claros, ni dan ejemplos ni nada, solo te ponen un pseudocodigo que tenes que adivinar que es.

Código: ASM
  1. Invertir:
  2.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  3.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  4.         RORS    R0, R0, #15             ;@ R0 = Inv(R0) >> 15 Wrap
  5.         UBFX    R1, R0, #0 ,#17         ;@ R1f = R0[16:0] = Alto invertido Final
  6.         LSL     R2, R2, #15             ;@ R2 = R2>>15 = R0f[16:0]
  7.         BFI     R0, R2, #0, #17         ;@ R0 = R0f[32:17] + R0f[16:0]
  8.         BX      LR                      ;@ Volver
  9.         .end
  10.  
  11. ;@ Normal
  12.  
  13. ;@ 0x0001.1234.5678.9ABC ->
  14.  
  15. ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100
  16. ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100
  17.  
  18. ;@ Invertido:
  19.  
  20. ;@ 0x0000.7AB2.3CD4.5891
  21.  
  22. ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010
  23. ;@ Bajo R0 0011 1100 1101 0100 0101 1000 1001 0001
  24.  
  25. ;@ Normal invertido pero cada uno Despues del RBIT:
  26.  
  27. ;@ Alto R2 0010 1100 0100 1000 1.000 0000 0000 0000
  28. ;@ Bajo R0 0011 1101 0101 1001 0001 1110 0110 1010
  29.  
  30. ;@ ROR R0>>15 = R0[32:17] + R1
  31. ;@ 0011 1100 1101 010.0 0111 1010 1011 0010
  32.  
  33. ;@ UBFX R1, R0, #0, #16
  34. ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010 - Final
  35.  
  36. ;@ LSL  R2, R2, #15
  37. ;@ R2 = 0000 0000 0000 0000 0101 1000 1001 0001

Sorprendentemente logre que compilara bien al instante, que sea correcto eso SI que no tengo ni idea.
Esto de no tener un maldito simulador de ARM lo estoy odiando. Si hay o son para ASM ARM o para micros de 5mil años atras. Y no tengo ganas de instalar QEMU e.e

Aaaaaaa, que lindo es el Asembler!!!!
RBIT!!!! (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489g/Cihjgdid.html)

a simple vista tiene que funcionar. Lo único es que de los 49 bits solo hay que invertir 48. Los bits 64-49 son siempre 0.
Voy a ver si lo implemento y lo pruebo en el micro.

Saludos!!!!
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #39 en: 13 de Octubre de 2015, 10:31:10 »
Probé el segundo código y obtengo:

Código: [Seleccionar]
MC uint64_t 1100101100000000000000000111111111111111111111011 (Binary)
inv uint64_t 1101111111111111111111110000000000000000000000000 (Binary)

el primer código devuelve:

Código: [Seleccionar]
MC uint64_t 1100101100000000000000000111111111111111111111011 (Binary)
inv uint64_t 1111111110000000000000000000000011111111100000000000000000000000 (Binary)

más tarde hago el step by step a ver si encuentro el error.
En el main.c puse:
extern uint64_t Invertir(uint64_t dato);
inv = Invertir(MC);

Saludos!

PD: Como MC es un comando, el bit 49 es un 1. Tener en cuenta que los bits 64-49 no se deben cambiar de posicion  :?
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #40 en: 13 de Octubre de 2015, 11:43:47 »
Bueno, estoy con step by step.

Cuando entra a la funcion en ASM tengo en R0 y R1 el dato de entrada. Tambien lo tengo en R2-R3. No sé si eso está bien o no.
en R0 tengo:
00000000 11111111 11111111 11111011
y en R1 tengo
00000000 00000001 10010110 00000000

El resultado del RBIT de R1 puesto en R2 es:
Código: [Seleccionar]
R1: 00000000 00000001 10010110 00000000
R2: 00000000 01101001 10000000 00000000

Luego el RBIT de R0 sobre R0 hace:

Código: [Seleccionar]
R0: 00000000111111111111111111111011
R0: 11011111111111111111111100000000

lo cual es correcto.
la siguiente instruccion, la rotate right obtiene

Código: [Seleccionar]
R0: 11111110 00000001 10111111 11111111

la siguiente instruccion cambia R1 a
Código: [Seleccionar]
R1: 00000000 00000001 10111111 11111111

la siguiente modifica R2 a
Código: [Seleccionar]
R2: 11000000 00000000 00000000 00000000

finalmente R0 se modifica a
Código: [Seleccionar]
R0: 11111110 00000000 00000000 00000000

El resultado es entones R0-R1:
Código: [Seleccionar]
00000000 00000001 10111111 11111111 - 11111110 00000000 00000000 00000000

el dato original era:
00000000 00000001 10010110 00000000 - 00000000 11111111 11111111 11111011

el resultado espera sería:
00000000 00000001 11011111 11111111 - 11111111 00000000 00000000 01101001

o sea que del bit 64 al 49 quedan donde están. Pero del 1 al 48 son rotados. Creo que no me había expresado bien en lo que necesitaba.

Despues de comer voy a ver si me sale corregirlo.
Killer, si lo corriges, por favor esperá a que lo intente yo primero para publicar la respuesta :P

Saludos!
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #41 en: 13 de Octubre de 2015, 14:09:17 »
 :-/ :-/ :-/

Prgramé en asembler!!!! jajaja:

Código: ASM
  1. Invertir:
  2.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  3.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  4.         RORS    R0, R0, #16             ;@ R0 = Inv(R0) >> 16 Wrap
  5.         BFI     R1, R0, #0 ,#16         ;@ R1f = R0[16:0] = Alto invertido Final
  6.         RORS    R2, R2, #16             ;@ R0 = Inv(R0) >> 16 Wrap
  7.         BFI     R0, R2, #0, #16         ;@ R0 = R0f[32:17] + R0f[16:0]
  8.         BX      LR                      ;@ Volver
  9.         .end

que buenas instrucciones que tienen estos core!!!

ahora quedaría ver cuantos ciclos tarda y comparar con alguna ruina mas o menos optimizada para C para hacer lo mismo. Acá hay algo interesante https://graphics.stanford.edu/~seander/bithacks.html

Saludos!
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Assembler en ARM - Probando
« Respuesta #42 en: 13 de Octubre de 2015, 14:25:01 »
Bueno, hice esta implementacion del DWT para contar ciclos de instruccion:

Código: C
  1. extern uint64_t Invertir(uint64_t dato);
  2.  
  3. int main(void)
  4. {
  5.         uint64_t MC=0, invertido = 0;
  6. //      uint8_t i;
  7.  
  8.         /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  9.         HAL_Init();
  10.  
  11.         /* Configure the system clock */
  12.         SystemClock_Config();
  13.  
  14.  
  15.         int count = 0;
  16.         volatile unsigned int *DWT_CYCCNT = (unsigned int *)0xE0001004; //address of the register
  17.         volatile unsigned int *DWT_CONTROL = (unsigned int *)0xE0001000; //address of the register
  18.         volatile unsigned int *SCB_DEMCR = (unsigned int *)0xE000EDFC; //address of the register
  19.  
  20.         *SCB_DEMCR = *SCB_DEMCR | 0x01000000;
  21.         *DWT_CYCCNT = 0; // reset the counter
  22.         *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
  23.  
  24.  
  25.         GPIO_Init();
  26.         TIM4_Config();
  27.  
  28.         MC |= 0x03 << 00;                               // MC = 11.6-8.1 mA
  29.         MC |= 0x7F << 03;                               //BC Red = 100%
  30.         MC |= 0x7F << 10;                               //BC Green = 100%
  31.         MC |= 0x7F << 17;                               //BC Blue = 100%
  32.                                                                         //SID = 0; LODVLT=0; LSDVLT=0; PSMODE=0 (no PWS)
  33.         MC |= (uint64_t)0x96 << 40;             //WRITE_CMD: Bits 40 a 47 en 10010110b
  34.         MC |= (uint64_t)0x01 << 48;             //Data Select Bit = 1
  35.  
  36.         *DWT_CYCCNT = 0;
  37.         invertido = Invertir(MC);
  38.         count = *DWT_CYCCNT;
  39.  
  40.         send_config(MC);
  41.         send_config(MC);
  42.  
  43.         while(1)
  44.         {
  45.                 efecto_02(500);
  46.         }
  47. }

Pongo un breack point en count = *DWT_CYCCNT; y le doy run. Cuando el programa se detiene, el contenido de  *DWT_CYCCNT es de 37. No estoy contando los ciclos para asignar el  *DWT_CYCCNT a count ya que me deyuve justo ahí.

Saludos!
-
Leonardo Garberoglio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #43 en: 13 de Octubre de 2015, 18:50:44 »
Como que tome que habia que invertir los 49 no los 48 :P.
Sabes lo que me rompi la cabeza intentando ver ese bit mas xD,, era un dolor de ....
Bueno, parece que ya lo solucionaste.

Lo que me parece raro son esos 37 ciclos. son demasiados.

Hay 6 instrucciones, de 32bits, no se si tomarlas como 12 ciclos o 6,
Supongamos 12, que luego por el pipeline se introduzca algunas bubbles por necesidad de los datos. eso lo aumentaria a cerca de 3 ciclos mas.
Sigiuiendo tenes el CALL y RETURN ( BL y BX ) eso va a depender exactamente del PC a donde se dirija, si es un salto a registro y no un literal, tomaria 3 ciclos, si es un literal 2 ciclos, si es un salto el cual no esta alineado a 32 bits tomaria 4 ciclos. entonces supongamos:
12 + 3 + 4 = 17 maximo.. incluso haciendo el doble en las instrucciones el cual NO deberia.

Esta bien que no contamos con, la asignacion de la variable a 0, la asignacion de los valores a R0 y R1 y finalmente el salto a la funcion pero no creo que en esto se vayan 20 ciclos :P, Aunque todo depende del nivel de optimizacion, si no posee optimizacion lo creo BASTANTE posible xD, como ya demostre antes el cual sin optimizacion era malisimo, utilizaba de R0 a R3, y estaba continuamente cargando R3 con los datos.

Tenemos antes:, Poner a 0 el valor de DWT_CYCCNT es aun mas, son hasta 5 ciclos para acceder a la memoria flash y tomar el dato de la direccion ( supongo no alineado ) mover 0 a un registro , otro ciclo, almacenar el dato unos 3 ciclos mas.  Mover del SP a R0/R1, 4 ciclos ( si es que no hay un double por ahi ). 13 ciclos ya aca , salto puede ser unos 4, 17ciclos y.... casi casi cerca de los 20 :P

Podrias hacer un par de cambios y probar nuevamente con algo asi?

Código: ASM
  1. .align  4
  2. Invertir:
  3.         RBIT    R0, R0                  ;@ R0 = Inv(R0)
  4.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  5.         RORS    R0, R0, #16             ;@ R0 = Inv(R0) >> 16 Wrap
  6.         RORS    R2, R2, #16             ;@ R0 = Inv(R0) >> 16 Wrap
  7.         BFI     R1, R0, #0 ,#16         ;@ R1f = R0[16:0] = Alto invertido Final
  8.         BFI     R0, R2, #0, #16         ;@ R0 = R0f[32:17] + R0f[16:0]
  9.         BX      LR                      ;@ Volver
  10.         .end

Lo que hice fue alinearlo a 32bits asi lo que lo llama va mas rapido.
Intente eliminar las dependencias en las entradas de datos.

        RBIT    R0, R0                  ;@ R0 = Inv(R0)
        RORS    R0, R0, #16             ;@ R0 = Inv(R0) >> 16 Wrap

Antes estaba asi, si en el pipeline entraba R0, para luego RORS usar R0 debia esperar que termine la primera instruccion. Por lo cual posiblemente se agregaba un "bubble" en el pipeline, es decir se retrasaba.
Creo que con el cambio de codigo no hay cambios en el funcionamiento y solo queda probarlo si efectivamente mejoro o no , tambien estaria bueno probar si el align cambia en algo o no la cantidad de ciclos.

PD: Todo esto sin contar si es que tu micro tiene un buffe de prefetch el cual un salto podria darle un miss a este buffer y dejar parado el CPU mientras se carga el buffer con el nuevo contenido. Especialmente en un salto. Lo cual te dejaria con el wait state de la flash + hasta que se cargue todo el pipeline xD

Si podes debuegearlo elgarbe, podes ir posicion por posicion. y podes medir exactamente cuanto mide los ciclos internos. Esa es otra

PD2: Esto de no poder probarlo me mata
PD3:

Ahora que son de 16 bits, te puede llegar a servir otra instruccion:

Pack halfword bottom + top
PKHBT Rd, Rn, Rm{, LSL #<sh>}
Rd[15:0] := Rn[15:0], Rd[31:16] := (Rm LSL sh)[31:16]. sh 0-31.

Pack halfword top + bottom
PKHTB Rd, Rn, Rm{, ASR #<sh>}
Rd[31:16] := Rn[31:16], Rd[15:0] := (Rm ASR sh)[15:0]. sh 1-32.

Especialmente si los pones en R2 y R3  a lo temporal y de ahi lo armas a tu gusto ( quedando creo que solo 4 instrucciones xD ), 2 RBIT y 2 Pack de esos, reduciendolo en 2 a lo que estaba.
Cuando vuelva intento ver si lo puedo escribir con esto.
« Última modificación: 13 de Octubre de 2015, 20:33:51 por KILLERJC »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Assembler en ARM - Probando
« Respuesta #44 en: 13 de Octubre de 2015, 20:54:23 »
Código: ASM
  1. Invertir:
  2.         RBIT    R2, R1                  ;@ R2 = Inv(R1)
  3.         RBIT    R3, R0                  ;@ R0 = Inv(R0)
  4.         LSRS    R2, R2, #16             ;@ R2:    00  : R0f[15:0]
  5.         PKHTB   R1, R1, R3, ASR #16     ;@ R1f[31:16]:R1f[15:0] = R1[31:16]:R3[31:16] = R1
  6.         PKHBT   R0, R2, R3, LSL #16     ;@ R0f[31:16]:R0f[15:0] = R3[15:0]:R2[15:0] = R0  (Aca R2 esta luego del Shift, sino hubiera sido [31:16])
  7.         .end

Una sola instruccion menos .... :/, crei que lo podia hacer con 4 pero no pude...
y 3 bytes menos en memoria de programa, por que el LSRS ocupa 16 bytes

Del analisis de el garbe saque esto, y de alli intente realizarla:

Código: [Seleccionar]
original 00000000 00000001 10010110 00000000 - 00000000 11111111 11111111 11111011
final    00000000 00000001 11011111 11111111 - 11111111 00000000 00000000 01101001
R1 R0

Luego de los RBIT

Código: [Seleccionar]
R1: 00000000 00000001 10010110 00000000   @Valor sin invertir
R2: 00000000 01101001 10000000 00000000   @Invertidos
R3: 11011111 11111111 11111111 00000000

R1:       R1f[31:16] :     XX
R2:       R0f[15:0]  :     XX     
R3:       R1f[15:0]  :     R0f[31:16]

Nuevamente, nada probado
Estoy inseguro en el tema del que posee el ASR ya que solo tomaba valores de 1 a 32, mientras que el LSL de 0 a 31 como uno esperaria :P
« Última modificación: 14 de Octubre de 2015, 05:27:38 por KILLERJC »


 

anything