Skip to content

Instantly share code, notes, and snippets.

@pabigot
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pabigot/290a3930f5e41c29c690 to your computer and use it in GitHub Desktop.
Save pabigot/290a3930f5e41c29c690 to your computer and use it in GitHub Desktop.
The Effect of the ARM Cortex-M NOP Instruction
/* ARM Cortex-M instruction delay experiment
*
* Copyright 2014, Peter A. Bigot
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the software nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bspacm/utility/led.h>
#include <bspacm/newlib/ioctl.h>
#include <stdio.h>
#include <string.h>
#define MAX_EXPERIMENTS 10
#define DELAY_INSN_NOP() do { __asm__ __volatile__("nop"); } while (0)
#define DELAY_INSN_MOV() do { __asm__ __volatile__("mov r8, r8"); } while (0)
#define CONTEXT_INSN_NULL() do { } while (0)
#define CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 1; } while (0)
#define RESTORE_CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 0; } while (0)
unsigned int *
nop_null (volatile unsigned int * dp)
{
unsigned int t0;
t0 = BSPACM_CORE_CYCCNT();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
return (unsigned int *)dp;
}
unsigned int *
mov_null (volatile unsigned int * dp)
{
unsigned int t0;
t0 = BSPACM_CORE_CYCCNT();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
t0 = BSPACM_CORE_CYCCNT();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
return (unsigned int *)dp;
}
unsigned int *
nop_gpio (volatile unsigned int * dp)
{
unsigned int t0;
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
return (unsigned int *)dp;
}
unsigned int *
mov_gpio (volatile unsigned int * dp)
{
unsigned int t0;
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
t0 = BSPACM_CORE_CYCCNT();
CONTEXT_INSN_GPIO();
*dp++ = BSPACM_CORE_CYCCNT() - t0;
RESTORE_CONTEXT_INSN_GPIO();
return (unsigned int *)dp;
}
void
display_results (const char * tag,
const unsigned int * dp,
const unsigned int * edp)
{
printf("%s:", tag);
while (dp < edp) {
printf(" %u", *dp++);
}
putchar('\n');
}
void main ()
{
union {
volatile unsigned int v[MAX_EXPERIMENTS];
unsigned int u[MAX_EXPERIMENTS];
} duration;
vBSPACMledConfigure();
BSPACM_CORE_ENABLE_CYCCNT();
BSPACM_CORE_ENABLE_INTERRUPT();
printf("\n" __DATE__ " " __TIME__ "\n");
printf("System clock %lu Hz\n", SystemCoreClock);
printf("Before GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
CONTEXT_INSN_GPIO();
printf("After GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
RESTORE_CONTEXT_INSN_GPIO();
printf("After GPIO context restored: %lx\n", SYSCTL->RCGCGPIO);
memset(duration.u, 0, sizeof(duration));
display_results("Null context, NOP", duration.u, nop_null(duration.v));
memset(duration.u, 0, sizeof(duration));
display_results("Null context, MOV", duration.u, mov_null(duration.v));
memset(duration.u, 0, sizeof(duration));
display_results("GPIO context, NOP", duration.u, nop_gpio(duration.v));
memset(duration.u, 0, sizeof(duration));
display_results("GPIO context, MOV", duration.u, mov_gpio(duration.v));
}
1:main.c **** /* BSPACM - instruction delay experiment
2:main.c **** *
3:main.c **** * Written in 2014 by Peter A. Bigot <http://pabigot.github.io/bspacm/>
4:main.c **** *
5:main.c **** * To the extent possible under law, the author(s) have dedicated all
6:main.c **** * copyright and related and neighboring rights to this software to
7:main.c **** * the public domain worldwide. This software is distributed without
8:main.c **** * any warranty.
9:main.c **** *
10:main.c **** * You should have received a copy of the CC0 Public Domain Dedication
11:main.c **** * along with this software. If not, see
12:main.c **** * <http://creativecommons.org/publicdomain/zero/1.0/>.
13:main.c **** *
14:main.c **** * This code implements the experimental design outlined in: http://forum.stellarisiti.com/topic/19
15:main.c **** */
17:main.c **** #include <bspacm/utility/led.h>
18:main.c **** #include <bspacm/newlib/ioctl.h>
19:main.c **** #include <stdio.h>
20:main.c **** #include <string.h>
22:main.c **** #define MAX_EXPERIMENTS 10
24:main.c **** #define DELAY_INSN_NOP() do { __asm__ __volatile__("nop"); } while (0)
25:main.c **** #define DELAY_INSN_MOV() do { __asm__ __volatile__("mov r8, r8"); } while (0)
26:main.c **** #define CONTEXT_INSN_NULL() do { } while (0)
27:main.c **** #define CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 1; } while (0)
28:main.c **** #define RESTORE_CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 0; } whi
30:main.c **** unsigned int *
31:main.c **** nop_null (volatile unsigned int * dp)
32:main.c **** {
33:main.c **** unsigned int t0;
35:main.c **** t0 = BSPACM_CORE_CYCCNT();
35 0000 214B ldr r3, .L2
36 0002 5A68 ldr r2, [r3, #4]
36:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
39 0004 5968 ldr r1, [r3, #4]
41 0006 8A1A subs r2, r1, r2
43 0008 0260 str r2, [r0]
38:main.c **** t0 = BSPACM_CORE_CYCCNT();
45 000a 5A68 ldr r2, [r3, #4]
39:main.c **** DELAY_INSN_NOP();
49 000c 00BF nop
40:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
54 000e 5968 ldr r1, [r3, #4]
55 0010 8A1A subs r2, r1, r2
57 0012 4260 str r2, [r0, #4]
42:main.c **** t0 = BSPACM_CORE_CYCCNT();
59 0014 5A68 ldr r2, [r3, #4]
43:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
63 0016 00BF nop
66 0018 00BF nop
44:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
71 001a 5968 ldr r1, [r3, #4]
72 001c 8A1A subs r2, r1, r2
74 001e 8260 str r2, [r0, #8]
46:main.c **** t0 = BSPACM_CORE_CYCCNT();
76 0020 5A68 ldr r2, [r3, #4]
47:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
80 0022 00BF nop
83 0024 00BF nop
86 0026 00BF nop
48:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
91 0028 5968 ldr r1, [r3, #4]
92 002a 8A1A subs r2, r1, r2
94 002c C260 str r2, [r0, #12]
50:main.c **** t0 = BSPACM_CORE_CYCCNT();
96 002e 5A68 ldr r2, [r3, #4]
51:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
100 0030 00BF nop
103 0032 00BF nop
106 0034 00BF nop
109 0036 00BF nop
52:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
114 0038 5968 ldr r1, [r3, #4]
115 003a 8A1A subs r2, r1, r2
117 003c 0261 str r2, [r0, #16]
54:main.c **** t0 = BSPACM_CORE_CYCCNT();
119 003e 5A68 ldr r2, [r3, #4]
55:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
123 0040 00BF nop
126 0042 00BF nop
129 0044 00BF nop
132 0046 00BF nop
56:main.c **** DELAY_INSN_NOP();
136 0048 00BF nop
57:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
141 004a 5968 ldr r1, [r3, #4]
142 004c 8A1A subs r2, r1, r2
144 004e 4261 str r2, [r0, #20]
59:main.c **** t0 = BSPACM_CORE_CYCCNT();
146 0050 5A68 ldr r2, [r3, #4]
60:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
150 0052 00BF nop
153 0054 00BF nop
156 0056 00BF nop
159 0058 00BF nop
61:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
163 005a 00BF nop
166 005c 00BF nop
62:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
171 005e 5968 ldr r1, [r3, #4]
172 0060 8A1A subs r2, r1, r2
174 0062 8261 str r2, [r0, #24]
64:main.c **** t0 = BSPACM_CORE_CYCCNT();
176 0064 5A68 ldr r2, [r3, #4]
65:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
180 0066 00BF nop
183 0068 00BF nop
186 006a 00BF nop
189 006c 00BF nop
66:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
193 006e 00BF nop
196 0070 00BF nop
199 0072 00BF nop
67:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
204 0074 5968 ldr r1, [r3, #4]
205 0076 8A1A subs r2, r1, r2
207 0078 C261 str r2, [r0, #28]
69:main.c **** t0 = BSPACM_CORE_CYCCNT();
209 007a 5A68 ldr r2, [r3, #4]
70:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
212 007c 5B68 ldr r3, [r3, #4]
213 007e 9B1A subs r3, r3, r2
214 0080 0362 str r3, [r0, #32]
72:main.c **** return (unsigned int *)dp;
73:main.c **** }
216 0082 2430 adds r0, r0, #36
218 0084 7047 bx lr
220 0086 00BF .align 2
222 0088 001000E0 .word -536866816
75:main.c **** unsigned int *
76:main.c **** mov_null (volatile unsigned int * dp)
77:main.c **** {
78:main.c **** unsigned int t0;
80:main.c **** t0 = BSPACM_CORE_CYCCNT();
241 0000 214B ldr r3, .L5
242 0002 5A68 ldr r2, [r3, #4]
81:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
245 0004 5968 ldr r1, [r3, #4]
247 0006 8A1A subs r2, r1, r2
249 0008 0260 str r2, [r0]
83:main.c **** t0 = BSPACM_CORE_CYCCNT();
251 000a 5A68 ldr r2, [r3, #4]
84:main.c **** DELAY_INSN_MOV();
255 000c C046 mov r8, r8
85:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
260 000e 5968 ldr r1, [r3, #4]
261 0010 8A1A subs r2, r1, r2
263 0012 4260 str r2, [r0, #4]
87:main.c **** t0 = BSPACM_CORE_CYCCNT();
265 0014 5A68 ldr r2, [r3, #4]
88:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
269 0016 C046 mov r8, r8
272 0018 C046 mov r8, r8
89:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
277 001a 5968 ldr r1, [r3, #4]
278 001c 8A1A subs r2, r1, r2
280 001e 8260 str r2, [r0, #8]
91:main.c **** t0 = BSPACM_CORE_CYCCNT();
282 0020 5A68 ldr r2, [r3, #4]
92:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
286 0022 C046 mov r8, r8
289 0024 C046 mov r8, r8
292 0026 C046 mov r8, r8
93:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
297 0028 5968 ldr r1, [r3, #4]
298 002a 8A1A subs r2, r1, r2
300 002c C260 str r2, [r0, #12]
95:main.c **** t0 = BSPACM_CORE_CYCCNT();
302 002e 5A68 ldr r2, [r3, #4]
96:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
306 0030 C046 mov r8, r8
309 0032 C046 mov r8, r8
312 0034 C046 mov r8, r8
315 0036 C046 mov r8, r8
97:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
320 0038 5968 ldr r1, [r3, #4]
321 003a 8A1A subs r2, r1, r2
323 003c 0261 str r2, [r0, #16]
99:main.c **** t0 = BSPACM_CORE_CYCCNT();
325 003e 5A68 ldr r2, [r3, #4]
100:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
329 0040 C046 mov r8, r8
332 0042 C046 mov r8, r8
335 0044 C046 mov r8, r8
338 0046 C046 mov r8, r8
101:main.c **** DELAY_INSN_MOV();
342 0048 C046 mov r8, r8
102:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
347 004a 5968 ldr r1, [r3, #4]
348 004c 8A1A subs r2, r1, r2
350 004e 4261 str r2, [r0, #20]
104:main.c **** t0 = BSPACM_CORE_CYCCNT();
352 0050 5A68 ldr r2, [r3, #4]
105:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
356 0052 C046 mov r8, r8
359 0054 C046 mov r8, r8
362 0056 C046 mov r8, r8
365 0058 C046 mov r8, r8
106:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
369 005a C046 mov r8, r8
372 005c C046 mov r8, r8
107:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
377 005e 5968 ldr r1, [r3, #4]
378 0060 8A1A subs r2, r1, r2
380 0062 8261 str r2, [r0, #24]
109:main.c **** t0 = BSPACM_CORE_CYCCNT();
382 0064 5A68 ldr r2, [r3, #4]
110:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
386 0066 C046 mov r8, r8
389 0068 C046 mov r8, r8
392 006a C046 mov r8, r8
395 006c C046 mov r8, r8
111:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
399 006e C046 mov r8, r8
402 0070 C046 mov r8, r8
405 0072 C046 mov r8, r8
112:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
410 0074 5968 ldr r1, [r3, #4]
411 0076 8A1A subs r2, r1, r2
413 0078 C261 str r2, [r0, #28]
114:main.c **** t0 = BSPACM_CORE_CYCCNT();
415 007a 5A68 ldr r2, [r3, #4]
115:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
418 007c 5B68 ldr r3, [r3, #4]
419 007e 9B1A subs r3, r3, r2
420 0080 0362 str r3, [r0, #32]
117:main.c **** return (unsigned int *)dp;
118:main.c **** }
422 0082 2430 adds r0, r0, #36
424 0084 7047 bx lr
426 0086 00BF .align 2
428 0088 001000E0 .word -536866816
120:main.c **** unsigned int *
121:main.c **** nop_gpio (volatile unsigned int * dp)
122:main.c **** {
123:main.c **** unsigned int t0;
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
447 0000 334A ldr r2, .L8
126:main.c **** CONTEXT_INSN_GPIO();
449 0002 344B ldr r3, .L8+4
450 0004 0121 movs r1, #1
122:main.c **** {
452 0006 70B4 push {r4, r5, r6}
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
458 0008 5468 ldr r4, [r2, #4]
461 000a 1960 str r1, [r3]
127:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
463 000c 5568 ldr r5, [r2, #4]
128:main.c **** RESTORE_CONTEXT_INSN_GPIO();
466 000e 0026 movs r6, #0
127:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
468 0010 2C1B subs r4, r5, r4
470 0012 0460 str r4, [r0]
472 0014 1E60 str r6, [r3]
130:main.c **** t0 = BSPACM_CORE_CYCCNT();
474 0016 5468 ldr r4, [r2, #4]
131:main.c **** CONTEXT_INSN_GPIO();
477 0018 1960 str r1, [r3]
132:main.c **** DELAY_INSN_NOP();
480 001a 00BF nop
133:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
485 001c 5568 ldr r5, [r2, #4]
134:main.c **** RESTORE_CONTEXT_INSN_GPIO();
487 001e 0021 movs r1, #0
133:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
489 0020 2C1B subs r4, r5, r4
491 0022 4460 str r4, [r0, #4]
493 0024 1960 str r1, [r3]
136:main.c **** t0 = BSPACM_CORE_CYCCNT();
137:main.c **** CONTEXT_INSN_GPIO();
495 0026 0124 movs r4, #1
136:main.c **** t0 = BSPACM_CORE_CYCCNT();
497 0028 5168 ldr r1, [r2, #4]
500 002a 1C60 str r4, [r3]
138:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
503 002c 00BF nop
506 002e 00BF nop
139:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
511 0030 5568 ldr r5, [r2, #4]
140:main.c **** RESTORE_CONTEXT_INSN_GPIO();
513 0032 0024 movs r4, #0
139:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
515 0034 691A subs r1, r5, r1
517 0036 8160 str r1, [r0, #8]
519 0038 1C60 str r4, [r3]
142:main.c **** t0 = BSPACM_CORE_CYCCNT();
143:main.c **** CONTEXT_INSN_GPIO();
521 003a 0121 movs r1, #1
142:main.c **** t0 = BSPACM_CORE_CYCCNT();
523 003c 5468 ldr r4, [r2, #4]
526 003e 1960 str r1, [r3]
144:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
529 0040 00BF nop
532 0042 00BF nop
535 0044 00BF nop
145:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
540 0046 5568 ldr r5, [r2, #4]
146:main.c **** RESTORE_CONTEXT_INSN_GPIO();
542 0048 0021 movs r1, #0
145:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
544 004a 2C1B subs r4, r5, r4
546 004c C460 str r4, [r0, #12]
548 004e 1960 str r1, [r3]
148:main.c **** t0 = BSPACM_CORE_CYCCNT();
149:main.c **** CONTEXT_INSN_GPIO();
550 0050 0124 movs r4, #1
148:main.c **** t0 = BSPACM_CORE_CYCCNT();
552 0052 5168 ldr r1, [r2, #4]
555 0054 1C60 str r4, [r3]
150:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
558 0056 00BF nop
561 0058 00BF nop
564 005a 00BF nop
567 005c 00BF nop
151:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
572 005e 5568 ldr r5, [r2, #4]
152:main.c **** RESTORE_CONTEXT_INSN_GPIO();
574 0060 0024 movs r4, #0
151:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
576 0062 691A subs r1, r5, r1
578 0064 0161 str r1, [r0, #16]
580 0066 1C60 str r4, [r3]
154:main.c **** t0 = BSPACM_CORE_CYCCNT();
155:main.c **** CONTEXT_INSN_GPIO();
582 0068 0121 movs r1, #1
154:main.c **** t0 = BSPACM_CORE_CYCCNT();
584 006a 5468 ldr r4, [r2, #4]
587 006c 1960 str r1, [r3]
156:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
590 006e 00BF nop
593 0070 00BF nop
596 0072 00BF nop
599 0074 00BF nop
157:main.c **** DELAY_INSN_NOP();
603 0076 00BF nop
158:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
608 0078 5568 ldr r5, [r2, #4]
159:main.c **** RESTORE_CONTEXT_INSN_GPIO();
610 007a 0021 movs r1, #0
158:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
612 007c 2C1B subs r4, r5, r4
614 007e 4461 str r4, [r0, #20]
616 0080 1960 str r1, [r3]
161:main.c **** t0 = BSPACM_CORE_CYCCNT();
162:main.c **** CONTEXT_INSN_GPIO();
618 0082 0124 movs r4, #1
161:main.c **** t0 = BSPACM_CORE_CYCCNT();
620 0084 5168 ldr r1, [r2, #4]
623 0086 1C60 str r4, [r3]
163:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
626 0088 00BF nop
629 008a 00BF nop
632 008c 00BF nop
635 008e 00BF nop
164:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
639 0090 00BF nop
642 0092 00BF nop
165:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
647 0094 5568 ldr r5, [r2, #4]
166:main.c **** RESTORE_CONTEXT_INSN_GPIO();
649 0096 0024 movs r4, #0
165:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
651 0098 691A subs r1, r5, r1
653 009a 8161 str r1, [r0, #24]
655 009c 1C60 str r4, [r3]
168:main.c **** t0 = BSPACM_CORE_CYCCNT();
169:main.c **** CONTEXT_INSN_GPIO();
657 009e 0121 movs r1, #1
168:main.c **** t0 = BSPACM_CORE_CYCCNT();
659 00a0 5468 ldr r4, [r2, #4]
662 00a2 1960 str r1, [r3]
170:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
665 00a4 00BF nop
668 00a6 00BF nop
671 00a8 00BF nop
674 00aa 00BF nop
171:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
678 00ac 00BF nop
681 00ae 00BF nop
684 00b0 00BF nop
172:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
689 00b2 5568 ldr r5, [r2, #4]
173:main.c **** RESTORE_CONTEXT_INSN_GPIO();
691 00b4 0021 movs r1, #0
172:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
693 00b6 2C1B subs r4, r5, r4
695 00b8 C461 str r4, [r0, #28]
175:main.c **** t0 = BSPACM_CORE_CYCCNT();
176:main.c **** CONTEXT_INSN_GPIO();
697 00ba 0125 movs r5, #1
173:main.c **** RESTORE_CONTEXT_INSN_GPIO();
699 00bc 1960 str r1, [r3]
175:main.c **** t0 = BSPACM_CORE_CYCCNT();
701 00be 5468 ldr r4, [r2, #4]
704 00c0 1D60 str r5, [r3]
177:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
707 00c2 5268 ldr r2, [r2, #4]
708 00c4 121B subs r2, r2, r4
709 00c6 0262 str r2, [r0, #32]
178:main.c **** RESTORE_CONTEXT_INSN_GPIO();
180:main.c **** return (unsigned int *)dp;
181:main.c **** }
711 00c8 70BC pop {r4, r5, r6}
713 00ca 2430 adds r0, r0, #36
178:main.c **** RESTORE_CONTEXT_INSN_GPIO();
716 00cc 1960 str r1, [r3]
718 00ce 7047 bx lr
722 00d0 001000E0 .word -536866816
723 00d4 04C1FC43 .word 1140637956
183:main.c **** unsigned int *
184:main.c **** mov_gpio (volatile unsigned int * dp)
185:main.c **** {
186:main.c **** unsigned int t0;
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
742 0000 334A ldr r2, .L11
189:main.c **** CONTEXT_INSN_GPIO();
744 0002 344B ldr r3, .L11+4
745 0004 0121 movs r1, #1
185:main.c **** {
747 0006 70B4 push {r4, r5, r6}
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
753 0008 5468 ldr r4, [r2, #4]
756 000a 1960 str r1, [r3]
190:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
758 000c 5568 ldr r5, [r2, #4]
191:main.c **** RESTORE_CONTEXT_INSN_GPIO();
761 000e 0026 movs r6, #0
190:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
763 0010 2C1B subs r4, r5, r4
765 0012 0460 str r4, [r0]
767 0014 1E60 str r6, [r3]
193:main.c **** t0 = BSPACM_CORE_CYCCNT();
769 0016 5468 ldr r4, [r2, #4]
194:main.c **** CONTEXT_INSN_GPIO();
772 0018 1960 str r1, [r3]
195:main.c **** DELAY_INSN_MOV();
775 001a C046 mov r8, r8
196:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
780 001c 5568 ldr r5, [r2, #4]
197:main.c **** RESTORE_CONTEXT_INSN_GPIO();
782 001e 0021 movs r1, #0
196:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
784 0020 2C1B subs r4, r5, r4
786 0022 4460 str r4, [r0, #4]
788 0024 1960 str r1, [r3]
199:main.c **** t0 = BSPACM_CORE_CYCCNT();
200:main.c **** CONTEXT_INSN_GPIO();
790 0026 0124 movs r4, #1
199:main.c **** t0 = BSPACM_CORE_CYCCNT();
792 0028 5168 ldr r1, [r2, #4]
795 002a 1C60 str r4, [r3]
201:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
798 002c C046 mov r8, r8
801 002e C046 mov r8, r8
202:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
806 0030 5568 ldr r5, [r2, #4]
203:main.c **** RESTORE_CONTEXT_INSN_GPIO();
808 0032 0024 movs r4, #0
202:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
810 0034 691A subs r1, r5, r1
812 0036 8160 str r1, [r0, #8]
814 0038 1C60 str r4, [r3]
205:main.c **** t0 = BSPACM_CORE_CYCCNT();
206:main.c **** CONTEXT_INSN_GPIO();
816 003a 0121 movs r1, #1
205:main.c **** t0 = BSPACM_CORE_CYCCNT();
818 003c 5468 ldr r4, [r2, #4]
821 003e 1960 str r1, [r3]
207:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
824 0040 C046 mov r8, r8
827 0042 C046 mov r8, r8
830 0044 C046 mov r8, r8
208:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
835 0046 5568 ldr r5, [r2, #4]
209:main.c **** RESTORE_CONTEXT_INSN_GPIO();
837 0048 0021 movs r1, #0
208:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
839 004a 2C1B subs r4, r5, r4
841 004c C460 str r4, [r0, #12]
843 004e 1960 str r1, [r3]
211:main.c **** t0 = BSPACM_CORE_CYCCNT();
212:main.c **** CONTEXT_INSN_GPIO();
845 0050 0124 movs r4, #1
211:main.c **** t0 = BSPACM_CORE_CYCCNT();
847 0052 5168 ldr r1, [r2, #4]
850 0054 1C60 str r4, [r3]
213:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
853 0056 C046 mov r8, r8
856 0058 C046 mov r8, r8
859 005a C046 mov r8, r8
862 005c C046 mov r8, r8
214:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
867 005e 5568 ldr r5, [r2, #4]
215:main.c **** RESTORE_CONTEXT_INSN_GPIO();
869 0060 0024 movs r4, #0
214:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
871 0062 691A subs r1, r5, r1
873 0064 0161 str r1, [r0, #16]
875 0066 1C60 str r4, [r3]
217:main.c **** t0 = BSPACM_CORE_CYCCNT();
218:main.c **** CONTEXT_INSN_GPIO();
877 0068 0121 movs r1, #1
217:main.c **** t0 = BSPACM_CORE_CYCCNT();
879 006a 5468 ldr r4, [r2, #4]
882 006c 1960 str r1, [r3]
219:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
885 006e C046 mov r8, r8
888 0070 C046 mov r8, r8
891 0072 C046 mov r8, r8
894 0074 C046 mov r8, r8
220:main.c **** DELAY_INSN_MOV();
898 0076 C046 mov r8, r8
221:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
903 0078 5568 ldr r5, [r2, #4]
222:main.c **** RESTORE_CONTEXT_INSN_GPIO();
905 007a 0021 movs r1, #0
221:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
907 007c 2C1B subs r4, r5, r4
909 007e 4461 str r4, [r0, #20]
911 0080 1960 str r1, [r3]
224:main.c **** t0 = BSPACM_CORE_CYCCNT();
225:main.c **** CONTEXT_INSN_GPIO();
913 0082 0124 movs r4, #1
224:main.c **** t0 = BSPACM_CORE_CYCCNT();
915 0084 5168 ldr r1, [r2, #4]
918 0086 1C60 str r4, [r3]
226:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
921 0088 C046 mov r8, r8
924 008a C046 mov r8, r8
927 008c C046 mov r8, r8
930 008e C046 mov r8, r8
227:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
934 0090 C046 mov r8, r8
937 0092 C046 mov r8, r8
228:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
942 0094 5568 ldr r5, [r2, #4]
229:main.c **** RESTORE_CONTEXT_INSN_GPIO();
944 0096 0024 movs r4, #0
228:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
946 0098 691A subs r1, r5, r1
948 009a 8161 str r1, [r0, #24]
950 009c 1C60 str r4, [r3]
231:main.c **** t0 = BSPACM_CORE_CYCCNT();
232:main.c **** CONTEXT_INSN_GPIO();
952 009e 0121 movs r1, #1
231:main.c **** t0 = BSPACM_CORE_CYCCNT();
954 00a0 5468 ldr r4, [r2, #4]
957 00a2 1960 str r1, [r3]
233:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
960 00a4 C046 mov r8, r8
963 00a6 C046 mov r8, r8
966 00a8 C046 mov r8, r8
969 00aa C046 mov r8, r8
234:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
973 00ac C046 mov r8, r8
976 00ae C046 mov r8, r8
979 00b0 C046 mov r8, r8
235:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
984 00b2 5568 ldr r5, [r2, #4]
236:main.c **** RESTORE_CONTEXT_INSN_GPIO();
986 00b4 0021 movs r1, #0
235:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
988 00b6 2C1B subs r4, r5, r4
990 00b8 C461 str r4, [r0, #28]
238:main.c **** t0 = BSPACM_CORE_CYCCNT();
239:main.c **** CONTEXT_INSN_GPIO();
992 00ba 0125 movs r5, #1
236:main.c **** RESTORE_CONTEXT_INSN_GPIO();
994 00bc 1960 str r1, [r3]
238:main.c **** t0 = BSPACM_CORE_CYCCNT();
996 00be 5468 ldr r4, [r2, #4]
999 00c0 1D60 str r5, [r3]
240:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
241:main.c **** RESTORE_CONTEXT_INSN_GPIO();
243:main.c **** return (unsigned int *)dp;
244:main.c **** }
241:main.c **** RESTORE_CONTEXT_INSN_GPIO();
246:main.c **** void
247:main.c **** display_results (const char * tag,
248:main.c **** const unsigned int * dp,
249:main.c **** const unsigned int * edp)
250:main.c **** {
251:main.c **** printf("%s:", tag);
252:main.c **** while (dp < edp) {
253:main.c **** printf(" %u", *dp++);
252:main.c **** while (dp < edp) {
254:main.c **** }
255:main.c **** putchar('\n');
256:main.c **** }
255:main.c **** putchar('\n');
258:main.c **** void main ()
259:main.c **** {
260:main.c **** union {
261:main.c **** volatile unsigned int v[MAX_EXPERIMENTS];
262:main.c **** unsigned int u[MAX_EXPERIMENTS];
263:main.c **** } duration;
265:main.c **** vBSPACMledConfigure();
266:main.c **** BSPACM_CORE_ENABLE_CYCCNT();
267:main.c **** BSPACM_CORE_ENABLE_INTERRUPT();
269:main.c **** printf("\n" __DATE__ " " __TIME__ "\n");
270:main.c **** printf("System clock %lu Hz\n", SystemCoreClock);
272:main.c **** printf("Before GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
273:main.c **** CONTEXT_INSN_GPIO();
269:main.c **** printf("\n" __DATE__ " " __TIME__ "\n");
270:main.c **** printf("System clock %lu Hz\n", SystemCoreClock);
272:main.c **** printf("Before GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
274:main.c **** printf("After GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
275:main.c **** RESTORE_CONTEXT_INSN_GPIO();
274:main.c **** printf("After GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
276:main.c **** printf("After GPIO context restored: %lx\n", SYSCTL->RCGCGPIO);
278:main.c **** memset(duration.u, 0, sizeof(duration));
279:main.c **** display_results("Null context, NOP", duration.u, nop_null(duration.v));
278:main.c **** memset(duration.u, 0, sizeof(duration));
281:main.c **** memset(duration.u, 0, sizeof(duration));
282:main.c **** display_results("Null context, MOV", duration.u, mov_null(duration.v));
281:main.c **** memset(duration.u, 0, sizeof(duration));
284:main.c **** memset(duration.u, 0, sizeof(duration));
285:main.c **** display_results("GPIO context, NOP", duration.u, nop_gpio(duration.v));
284:main.c **** memset(duration.u, 0, sizeof(duration));
287:main.c **** memset(duration.u, 0, sizeof(duration));
288:main.c **** display_results("GPIO context, MOV", duration.u, mov_gpio(duration.v));
287:main.c **** memset(duration.u, 0, sizeof(duration));
289:main.c **** }
1:main.c **** /* BSPACM - instruction delay experiment
2:main.c **** *
3:main.c **** * Written in 2014 by Peter A. Bigot <http://pabigot.github.io/bspacm/>
4:main.c **** *
5:main.c **** * To the extent possible under law, the author(s) have dedicated all
6:main.c **** * copyright and related and neighboring rights to this software to
7:main.c **** * the public domain worldwide. This software is distributed without
8:main.c **** * any warranty.
9:main.c **** *
10:main.c **** * You should have received a copy of the CC0 Public Domain Dedication
11:main.c **** * along with this software. If not, see
12:main.c **** * <http://creativecommons.org/publicdomain/zero/1.0/>.
13:main.c **** *
14:main.c **** * This code implements the experimental design outlined in: http://forum.stellarisiti.com/topic/19
15:main.c **** */
17:main.c **** #include <bspacm/utility/led.h>
18:main.c **** #include <bspacm/newlib/ioctl.h>
19:main.c **** #include <stdio.h>
20:main.c **** #include <string.h>
22:main.c **** #define MAX_EXPERIMENTS 10
24:main.c **** #define DELAY_INSN_NOP() do { __asm__ __volatile__("nop"); } while (0)
25:main.c **** #define DELAY_INSN_MOV() do { __asm__ __volatile__("mov r8, r8"); } while (0)
26:main.c **** #define CONTEXT_INSN_NULL() do { } while (0)
27:main.c **** #define CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 1; } while (0)
28:main.c **** #define RESTORE_CONTEXT_INSN_GPIO() do { BSPACM_CORE_BITBAND_PERIPH(SYSCTL->RCGCGPIO, 1) = 0; } whi
30:main.c **** unsigned int *
31:main.c **** nop_null (volatile unsigned int * dp)
32:main.c **** {
33:main.c **** unsigned int t0;
35:main.c **** t0 = BSPACM_CORE_CYCCNT();
35 0000 214B ldr r3, .L2
36 0002 5A68 ldr r2, [r3, #4]
36:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
39 0004 5968 ldr r1, [r3, #4]
40 0006 8A1A subs r2, r1, r2
42 0008 0260 str r2, [r0]
38:main.c **** t0 = BSPACM_CORE_CYCCNT();
44 000a 5A68 ldr r2, [r3, #4]
39:main.c **** DELAY_INSN_NOP();
48 000c 00BF nop
40:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
53 000e 5968 ldr r1, [r3, #4]
54 0010 8A1A subs r2, r1, r2
56 0012 4260 str r2, [r0, #4]
42:main.c **** t0 = BSPACM_CORE_CYCCNT();
58 0014 5A68 ldr r2, [r3, #4]
43:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
62 0016 00BF nop
65 0018 00BF nop
44:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
70 001a 5968 ldr r1, [r3, #4]
71 001c 8A1A subs r2, r1, r2
73 001e 8260 str r2, [r0, #8]
46:main.c **** t0 = BSPACM_CORE_CYCCNT();
75 0020 5A68 ldr r2, [r3, #4]
47:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
79 0022 00BF nop
82 0024 00BF nop
85 0026 00BF nop
48:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
90 0028 5968 ldr r1, [r3, #4]
91 002a 8A1A subs r2, r1, r2
93 002c C260 str r2, [r0, #12]
50:main.c **** t0 = BSPACM_CORE_CYCCNT();
95 002e 5A68 ldr r2, [r3, #4]
51:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
99 0030 00BF nop
102 0032 00BF nop
105 0034 00BF nop
108 0036 00BF nop
52:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
113 0038 5968 ldr r1, [r3, #4]
114 003a 8A1A subs r2, r1, r2
116 003c 0261 str r2, [r0, #16]
54:main.c **** t0 = BSPACM_CORE_CYCCNT();
118 003e 5A68 ldr r2, [r3, #4]
55:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
122 0040 00BF nop
125 0042 00BF nop
128 0044 00BF nop
131 0046 00BF nop
56:main.c **** DELAY_INSN_NOP();
135 0048 00BF nop
57:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
140 004a 5968 ldr r1, [r3, #4]
141 004c 8A1A subs r2, r1, r2
143 004e 4261 str r2, [r0, #20]
59:main.c **** t0 = BSPACM_CORE_CYCCNT();
145 0050 5A68 ldr r2, [r3, #4]
60:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
149 0052 00BF nop
152 0054 00BF nop
155 0056 00BF nop
158 0058 00BF nop
61:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
162 005a 00BF nop
165 005c 00BF nop
62:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
170 005e 5968 ldr r1, [r3, #4]
171 0060 8A1A subs r2, r1, r2
173 0062 8261 str r2, [r0, #24]
64:main.c **** t0 = BSPACM_CORE_CYCCNT();
175 0064 5A68 ldr r2, [r3, #4]
65:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
179 0066 00BF nop
182 0068 00BF nop
185 006a 00BF nop
188 006c 00BF nop
66:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
192 006e 00BF nop
195 0070 00BF nop
198 0072 00BF nop
67:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
203 0074 5968 ldr r1, [r3, #4]
204 0076 8A1A subs r2, r1, r2
206 0078 C261 str r2, [r0, #28]
69:main.c **** t0 = BSPACM_CORE_CYCCNT();
208 007a 5A68 ldr r2, [r3, #4]
70:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
211 007c 5B68 ldr r3, [r3, #4]
212 007e 9B1A subs r3, r3, r2
213 0080 0362 str r3, [r0, #32]
72:main.c **** return (unsigned int *)dp;
73:main.c **** }
215 0082 2430 adds r0, r0, #36
217 0084 7047 bx lr
219 0086 00BF .align 2
221 0088 001000E0 .word -536866816
75:main.c **** unsigned int *
76:main.c **** mov_null (volatile unsigned int * dp)
77:main.c **** {
78:main.c **** unsigned int t0;
80:main.c **** t0 = BSPACM_CORE_CYCCNT();
240 0000 214B ldr r3, .L5
241 0002 5A68 ldr r2, [r3, #4]
81:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
244 0004 5968 ldr r1, [r3, #4]
245 0006 8A1A subs r2, r1, r2
247 0008 0260 str r2, [r0]
83:main.c **** t0 = BSPACM_CORE_CYCCNT();
249 000a 5A68 ldr r2, [r3, #4]
84:main.c **** DELAY_INSN_MOV();
253 000c C046 mov r8, r8
85:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
258 000e 5968 ldr r1, [r3, #4]
259 0010 8A1A subs r2, r1, r2
261 0012 4260 str r2, [r0, #4]
87:main.c **** t0 = BSPACM_CORE_CYCCNT();
263 0014 5A68 ldr r2, [r3, #4]
88:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
267 0016 C046 mov r8, r8
270 0018 C046 mov r8, r8
89:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
275 001a 5968 ldr r1, [r3, #4]
276 001c 8A1A subs r2, r1, r2
278 001e 8260 str r2, [r0, #8]
91:main.c **** t0 = BSPACM_CORE_CYCCNT();
280 0020 5A68 ldr r2, [r3, #4]
92:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
284 0022 C046 mov r8, r8
287 0024 C046 mov r8, r8
290 0026 C046 mov r8, r8
93:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
295 0028 5968 ldr r1, [r3, #4]
296 002a 8A1A subs r2, r1, r2
298 002c C260 str r2, [r0, #12]
95:main.c **** t0 = BSPACM_CORE_CYCCNT();
300 002e 5A68 ldr r2, [r3, #4]
96:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
304 0030 C046 mov r8, r8
307 0032 C046 mov r8, r8
310 0034 C046 mov r8, r8
313 0036 C046 mov r8, r8
97:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
318 0038 5968 ldr r1, [r3, #4]
319 003a 8A1A subs r2, r1, r2
321 003c 0261 str r2, [r0, #16]
99:main.c **** t0 = BSPACM_CORE_CYCCNT();
323 003e 5A68 ldr r2, [r3, #4]
100:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
327 0040 C046 mov r8, r8
330 0042 C046 mov r8, r8
333 0044 C046 mov r8, r8
336 0046 C046 mov r8, r8
101:main.c **** DELAY_INSN_MOV();
340 0048 C046 mov r8, r8
102:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
345 004a 5968 ldr r1, [r3, #4]
346 004c 8A1A subs r2, r1, r2
348 004e 4261 str r2, [r0, #20]
104:main.c **** t0 = BSPACM_CORE_CYCCNT();
350 0050 5A68 ldr r2, [r3, #4]
105:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
354 0052 C046 mov r8, r8
357 0054 C046 mov r8, r8
360 0056 C046 mov r8, r8
363 0058 C046 mov r8, r8
106:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
367 005a C046 mov r8, r8
370 005c C046 mov r8, r8
107:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
375 005e 5968 ldr r1, [r3, #4]
376 0060 8A1A subs r2, r1, r2
378 0062 8261 str r2, [r0, #24]
109:main.c **** t0 = BSPACM_CORE_CYCCNT();
380 0064 5A68 ldr r2, [r3, #4]
110:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
384 0066 C046 mov r8, r8
387 0068 C046 mov r8, r8
390 006a C046 mov r8, r8
393 006c C046 mov r8, r8
111:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
397 006e C046 mov r8, r8
400 0070 C046 mov r8, r8
403 0072 C046 mov r8, r8
112:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
408 0074 5968 ldr r1, [r3, #4]
409 0076 8A1A subs r2, r1, r2
411 0078 C261 str r2, [r0, #28]
114:main.c **** t0 = BSPACM_CORE_CYCCNT();
413 007a 5A68 ldr r2, [r3, #4]
115:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
416 007c 5B68 ldr r3, [r3, #4]
417 007e 9B1A subs r3, r3, r2
418 0080 0362 str r3, [r0, #32]
117:main.c **** return (unsigned int *)dp;
118:main.c **** }
420 0082 2430 adds r0, r0, #36
422 0084 7047 bx lr
424 0086 00BF .align 2
426 0088 001000E0 .word -536866816
120:main.c **** unsigned int *
121:main.c **** nop_gpio (volatile unsigned int * dp)
122:main.c **** {
123:main.c **** unsigned int t0;
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
444 0000 394A ldr r2, .L8
126:main.c **** CONTEXT_INSN_GPIO();
446 0002 3A4B ldr r3, .L8+4
447 0004 0121 movs r1, #1
122:main.c **** {
449 0006 30B5 push {r4, r5, lr}
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
455 0008 5468 ldr r4, [r2, #4]
458 000a 1960 str r1, [r3]
127:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
461 000c 5568 ldr r5, [r2, #4]
462 000e 2C1B subs r4, r5, r4
464 0010 0460 str r4, [r0]
128:main.c **** RESTORE_CONTEXT_INSN_GPIO();
466 0012 0024 movs r4, #0
467 0014 1C60 str r4, [r3]
130:main.c **** t0 = BSPACM_CORE_CYCCNT();
469 0016 5468 ldr r4, [r2, #4]
131:main.c **** CONTEXT_INSN_GPIO();
472 0018 1960 str r1, [r3]
132:main.c **** DELAY_INSN_NOP();
475 001a 00BF nop
133:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
480 001c 5368 ldr r3, [r2, #4]
481 001e 1B1B subs r3, r3, r4
482 0020 4360 str r3, [r0, #4]
134:main.c **** RESTORE_CONTEXT_INSN_GPIO();
484 0022 324B ldr r3, .L8+4
485 0024 0021 movs r1, #0
486 0026 1960 str r1, [r3]
136:main.c **** t0 = BSPACM_CORE_CYCCNT();
488 0028 5168 ldr r1, [r2, #4]
137:main.c **** CONTEXT_INSN_GPIO();
491 002a 0122 movs r2, #1
492 002c 1A60 str r2, [r3]
138:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
495 002e 00BF nop
498 0030 00BF nop
139:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
503 0032 2D4A ldr r2, .L8
504 0034 5368 ldr r3, [r2, #4]
505 0036 5B1A subs r3, r3, r1
506 0038 8360 str r3, [r0, #8]
140:main.c **** RESTORE_CONTEXT_INSN_GPIO();
508 003a 2C4B ldr r3, .L8+4
509 003c 0021 movs r1, #0
511 003e 1960 str r1, [r3]
142:main.c **** t0 = BSPACM_CORE_CYCCNT();
513 0040 5168 ldr r1, [r2, #4]
143:main.c **** CONTEXT_INSN_GPIO();
516 0042 0122 movs r2, #1
517 0044 1A60 str r2, [r3]
144:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
520 0046 00BF nop
523 0048 00BF nop
526 004a 00BF nop
145:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
531 004c 264A ldr r2, .L8
532 004e 5368 ldr r3, [r2, #4]
533 0050 5B1A subs r3, r3, r1
534 0052 C360 str r3, [r0, #12]
146:main.c **** RESTORE_CONTEXT_INSN_GPIO();
536 0054 254B ldr r3, .L8+4
537 0056 0021 movs r1, #0
539 0058 1960 str r1, [r3]
148:main.c **** t0 = BSPACM_CORE_CYCCNT();
541 005a 5168 ldr r1, [r2, #4]
149:main.c **** CONTEXT_INSN_GPIO();
544 005c 0122 movs r2, #1
545 005e 1A60 str r2, [r3]
150:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
548 0060 00BF nop
551 0062 00BF nop
554 0064 00BF nop
557 0066 00BF nop
151:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
562 0068 1F4A ldr r2, .L8
563 006a 5368 ldr r3, [r2, #4]
564 006c 5B1A subs r3, r3, r1
565 006e 0361 str r3, [r0, #16]
152:main.c **** RESTORE_CONTEXT_INSN_GPIO();
567 0070 1E4B ldr r3, .L8+4
568 0072 0021 movs r1, #0
570 0074 1960 str r1, [r3]
154:main.c **** t0 = BSPACM_CORE_CYCCNT();
572 0076 5168 ldr r1, [r2, #4]
155:main.c **** CONTEXT_INSN_GPIO();
575 0078 0122 movs r2, #1
576 007a 1A60 str r2, [r3]
156:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
579 007c 00BF nop
582 007e 00BF nop
585 0080 00BF nop
588 0082 00BF nop
157:main.c **** DELAY_INSN_NOP();
592 0084 00BF nop
158:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
597 0086 184A ldr r2, .L8
598 0088 5368 ldr r3, [r2, #4]
599 008a 5B1A subs r3, r3, r1
600 008c 4361 str r3, [r0, #20]
159:main.c **** RESTORE_CONTEXT_INSN_GPIO();
602 008e 174B ldr r3, .L8+4
603 0090 0021 movs r1, #0
605 0092 1960 str r1, [r3]
161:main.c **** t0 = BSPACM_CORE_CYCCNT();
607 0094 5168 ldr r1, [r2, #4]
162:main.c **** CONTEXT_INSN_GPIO();
610 0096 0122 movs r2, #1
611 0098 1A60 str r2, [r3]
163:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
614 009a 00BF nop
617 009c 00BF nop
620 009e 00BF nop
623 00a0 00BF nop
164:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
627 00a2 00BF nop
630 00a4 00BF nop
165:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
635 00a6 104A ldr r2, .L8
636 00a8 5368 ldr r3, [r2, #4]
637 00aa 5B1A subs r3, r3, r1
638 00ac 8361 str r3, [r0, #24]
166:main.c **** RESTORE_CONTEXT_INSN_GPIO();
640 00ae 0F4B ldr r3, .L8+4
641 00b0 0021 movs r1, #0
643 00b2 1960 str r1, [r3]
168:main.c **** t0 = BSPACM_CORE_CYCCNT();
645 00b4 5168 ldr r1, [r2, #4]
169:main.c **** CONTEXT_INSN_GPIO();
648 00b6 0122 movs r2, #1
649 00b8 1A60 str r2, [r3]
170:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
652 00ba 00BF nop
655 00bc 00BF nop
658 00be 00BF nop
661 00c0 00BF nop
171:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP(); DELAY_INSN_NOP();
665 00c2 00BF nop
668 00c4 00BF nop
671 00c6 00BF nop
172:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
676 00c8 074A ldr r2, .L8
677 00ca 5368 ldr r3, [r2, #4]
678 00cc 5B1A subs r3, r3, r1
679 00ce C361 str r3, [r0, #28]
173:main.c **** RESTORE_CONTEXT_INSN_GPIO();
681 00d0 064B ldr r3, .L8+4
682 00d2 0021 movs r1, #0
684 00d4 1960 str r1, [r3]
175:main.c **** t0 = BSPACM_CORE_CYCCNT();
176:main.c **** CONTEXT_INSN_GPIO();
686 00d6 0125 movs r5, #1
175:main.c **** t0 = BSPACM_CORE_CYCCNT();
688 00d8 5468 ldr r4, [r2, #4]
691 00da 1D60 str r5, [r3]
177:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
694 00dc 5268 ldr r2, [r2, #4]
695 00de 121B subs r2, r2, r4
696 00e0 0262 str r2, [r0, #32]
178:main.c **** RESTORE_CONTEXT_INSN_GPIO();
698 00e2 1960 str r1, [r3]
180:main.c **** return (unsigned int *)dp;
181:main.c **** }
700 00e4 2430 adds r0, r0, #36
702 00e6 30BD pop {r4, r5, pc}
707 00e8 001000E0 .word -536866816
708 00ec 04C1FC43 .word 1140637956
183:main.c **** unsigned int *
184:main.c **** mov_gpio (volatile unsigned int * dp)
185:main.c **** {
186:main.c **** unsigned int t0;
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
726 0000 394A ldr r2, .L11
189:main.c **** CONTEXT_INSN_GPIO();
728 0002 3A4B ldr r3, .L11+4
729 0004 0121 movs r1, #1
185:main.c **** {
731 0006 30B5 push {r4, r5, lr}
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
737 0008 5468 ldr r4, [r2, #4]
740 000a 1960 str r1, [r3]
190:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
743 000c 5568 ldr r5, [r2, #4]
744 000e 2C1B subs r4, r5, r4
746 0010 0460 str r4, [r0]
191:main.c **** RESTORE_CONTEXT_INSN_GPIO();
748 0012 0024 movs r4, #0
749 0014 1C60 str r4, [r3]
193:main.c **** t0 = BSPACM_CORE_CYCCNT();
751 0016 5468 ldr r4, [r2, #4]
194:main.c **** CONTEXT_INSN_GPIO();
754 0018 1960 str r1, [r3]
195:main.c **** DELAY_INSN_MOV();
757 001a C046 mov r8, r8
196:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
762 001c 5368 ldr r3, [r2, #4]
763 001e 1B1B subs r3, r3, r4
764 0020 4360 str r3, [r0, #4]
197:main.c **** RESTORE_CONTEXT_INSN_GPIO();
766 0022 324B ldr r3, .L11+4
767 0024 0021 movs r1, #0
768 0026 1960 str r1, [r3]
199:main.c **** t0 = BSPACM_CORE_CYCCNT();
770 0028 5168 ldr r1, [r2, #4]
200:main.c **** CONTEXT_INSN_GPIO();
773 002a 0122 movs r2, #1
774 002c 1A60 str r2, [r3]
201:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
777 002e C046 mov r8, r8
780 0030 C046 mov r8, r8
202:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
785 0032 2D4A ldr r2, .L11
786 0034 5368 ldr r3, [r2, #4]
787 0036 5B1A subs r3, r3, r1
788 0038 8360 str r3, [r0, #8]
203:main.c **** RESTORE_CONTEXT_INSN_GPIO();
790 003a 2C4B ldr r3, .L11+4
791 003c 0021 movs r1, #0
793 003e 1960 str r1, [r3]
205:main.c **** t0 = BSPACM_CORE_CYCCNT();
795 0040 5168 ldr r1, [r2, #4]
206:main.c **** CONTEXT_INSN_GPIO();
798 0042 0122 movs r2, #1
799 0044 1A60 str r2, [r3]
207:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
802 0046 C046 mov r8, r8
805 0048 C046 mov r8, r8
808 004a C046 mov r8, r8
208:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
813 004c 264A ldr r2, .L11
814 004e 5368 ldr r3, [r2, #4]
815 0050 5B1A subs r3, r3, r1
816 0052 C360 str r3, [r0, #12]
209:main.c **** RESTORE_CONTEXT_INSN_GPIO();
818 0054 254B ldr r3, .L11+4
819 0056 0021 movs r1, #0
821 0058 1960 str r1, [r3]
211:main.c **** t0 = BSPACM_CORE_CYCCNT();
823 005a 5168 ldr r1, [r2, #4]
212:main.c **** CONTEXT_INSN_GPIO();
826 005c 0122 movs r2, #1
827 005e 1A60 str r2, [r3]
213:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
830 0060 C046 mov r8, r8
833 0062 C046 mov r8, r8
836 0064 C046 mov r8, r8
839 0066 C046 mov r8, r8
214:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
844 0068 1F4A ldr r2, .L11
845 006a 5368 ldr r3, [r2, #4]
846 006c 5B1A subs r3, r3, r1
847 006e 0361 str r3, [r0, #16]
215:main.c **** RESTORE_CONTEXT_INSN_GPIO();
849 0070 1E4B ldr r3, .L11+4
850 0072 0021 movs r1, #0
852 0074 1960 str r1, [r3]
217:main.c **** t0 = BSPACM_CORE_CYCCNT();
854 0076 5168 ldr r1, [r2, #4]
218:main.c **** CONTEXT_INSN_GPIO();
857 0078 0122 movs r2, #1
858 007a 1A60 str r2, [r3]
219:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
861 007c C046 mov r8, r8
864 007e C046 mov r8, r8
867 0080 C046 mov r8, r8
870 0082 C046 mov r8, r8
220:main.c **** DELAY_INSN_MOV();
874 0084 C046 mov r8, r8
221:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
879 0086 184A ldr r2, .L11
880 0088 5368 ldr r3, [r2, #4]
881 008a 5B1A subs r3, r3, r1
882 008c 4361 str r3, [r0, #20]
222:main.c **** RESTORE_CONTEXT_INSN_GPIO();
884 008e 174B ldr r3, .L11+4
885 0090 0021 movs r1, #0
887 0092 1960 str r1, [r3]
224:main.c **** t0 = BSPACM_CORE_CYCCNT();
889 0094 5168 ldr r1, [r2, #4]
225:main.c **** CONTEXT_INSN_GPIO();
892 0096 0122 movs r2, #1
893 0098 1A60 str r2, [r3]
226:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
896 009a C046 mov r8, r8
899 009c C046 mov r8, r8
902 009e C046 mov r8, r8
905 00a0 C046 mov r8, r8
227:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
909 00a2 C046 mov r8, r8
912 00a4 C046 mov r8, r8
228:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
917 00a6 104A ldr r2, .L11
918 00a8 5368 ldr r3, [r2, #4]
919 00aa 5B1A subs r3, r3, r1
920 00ac 8361 str r3, [r0, #24]
229:main.c **** RESTORE_CONTEXT_INSN_GPIO();
922 00ae 0F4B ldr r3, .L11+4
923 00b0 0021 movs r1, #0
925 00b2 1960 str r1, [r3]
231:main.c **** t0 = BSPACM_CORE_CYCCNT();
927 00b4 5168 ldr r1, [r2, #4]
232:main.c **** CONTEXT_INSN_GPIO();
930 00b6 0122 movs r2, #1
931 00b8 1A60 str r2, [r3]
233:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
934 00ba C046 mov r8, r8
937 00bc C046 mov r8, r8
940 00be C046 mov r8, r8
943 00c0 C046 mov r8, r8
234:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV(); DELAY_INSN_MOV();
947 00c2 C046 mov r8, r8
950 00c4 C046 mov r8, r8
953 00c6 C046 mov r8, r8
235:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
958 00c8 074A ldr r2, .L11
959 00ca 5368 ldr r3, [r2, #4]
960 00cc 5B1A subs r3, r3, r1
961 00ce C361 str r3, [r0, #28]
236:main.c **** RESTORE_CONTEXT_INSN_GPIO();
963 00d0 064B ldr r3, .L11+4
964 00d2 0021 movs r1, #0
966 00d4 1960 str r1, [r3]
238:main.c **** t0 = BSPACM_CORE_CYCCNT();
239:main.c **** CONTEXT_INSN_GPIO();
968 00d6 0125 movs r5, #1
238:main.c **** t0 = BSPACM_CORE_CYCCNT();
970 00d8 5468 ldr r4, [r2, #4]
973 00da 1D60 str r5, [r3]
240:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
976 00dc 5268 ldr r2, [r2, #4]
977 00de 121B subs r2, r2, r4
978 00e0 0262 str r2, [r0, #32]
241:main.c **** RESTORE_CONTEXT_INSN_GPIO();
980 00e2 1960 str r1, [r3]
243:main.c **** return (unsigned int *)dp;
244:main.c **** }
982 00e4 2430 adds r0, r0, #36
984 00e6 30BD pop {r4, r5, pc}
989 00e8 001000E0 .word -536866816
990 00ec 04C1FC43 .word 1140637956
246:main.c **** void
247:main.c **** display_results (const char * tag,
248:main.c **** const unsigned int * dp,
249:main.c **** const unsigned int * edp)
250:main.c **** {
251:main.c **** printf("%s:", tag);
250:main.c **** {
252:main.c **** while (dp < edp) {
253:main.c **** printf(" %u", *dp++);
252:main.c **** while (dp < edp) {
254:main.c **** }
255:main.c **** putchar('\n');
256:main.c **** }
255:main.c **** putchar('\n');
258:main.c **** void main ()
259:main.c **** {
260:main.c **** union {
261:main.c **** volatile unsigned int v[MAX_EXPERIMENTS];
262:main.c **** unsigned int u[MAX_EXPERIMENTS];
263:main.c **** } duration;
265:main.c **** vBSPACMledConfigure();
266:main.c **** BSPACM_CORE_ENABLE_CYCCNT();
267:main.c **** BSPACM_CORE_ENABLE_INTERRUPT();
269:main.c **** printf("\n" __DATE__ " " __TIME__ "\n");
270:main.c **** printf("System clock %lu Hz\n", SystemCoreClock);
272:main.c **** printf("Before GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
273:main.c **** CONTEXT_INSN_GPIO();
269:main.c **** printf("\n" __DATE__ " " __TIME__ "\n");
270:main.c **** printf("System clock %lu Hz\n", SystemCoreClock);
272:main.c **** printf("Before GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
274:main.c **** printf("After GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
275:main.c **** RESTORE_CONTEXT_INSN_GPIO();
274:main.c **** printf("After GPIO context insn: %lx\n", SYSCTL->RCGCGPIO);
276:main.c **** printf("After GPIO context restored: %lx\n", SYSCTL->RCGCGPIO);
278:main.c **** memset(duration.u, 0, sizeof(duration));
279:main.c **** display_results("Null context, NOP", duration.u, nop_null(duration.v));
281:main.c **** memset(duration.u, 0, sizeof(duration));
282:main.c **** display_results("Null context, MOV", duration.u, mov_null(duration.v));
284:main.c **** memset(duration.u, 0, sizeof(duration));
285:main.c **** display_results("GPIO context, NOP", duration.u, nop_gpio(duration.v));
287:main.c **** memset(duration.u, 0, sizeof(duration));
288:main.c **** display_results("GPIO context, MOV", duration.u, mov_gpio(duration.v));
289:main.c **** }
# BSPACM - Makefile for ARM Cortex-M instruction delay experiment
#
# Written in 2014 by Peter A. Bigot <http://pabigot.github.io/bspacm/>
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to
# the public domain worldwide. This software is distributed without
# any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.
#
SRC=main.c
AUX_CPPFLAGS+=-DBSPACM_CONFIG_ENABLE_UART=1
WITH_FDOPS=1
include $(BSPACM_ROOT)/make/Makefile.common
# Generate the listing with only the instruction sequence
# visible (stripping out asm directives and source whitespace)
REALCLEAN += main.dis
main.dis: main.lst
cat $^ \
| sed -n \
-e '/^....:main/p' \
-e '/^.... 0... /p' \
| sed -r -e '/\*\*\*\*\s*$$/d' \
> $@
The code is available in [url=]this github gist[/url].
Here's the output:
[code]
May 22 2014 06:16:24
System clock 16000000 Hz
Before GPIO context insn: 21
After GPIO context insn: 23
After GPIO context restored: 21
Null context, NOP: 1 2 3 4 5 6 7 8 1
Null context, MOV: 1 3 4 5 6 7 8 9 1
GPIO context, NOP: 7 7 10 10 10 11 12 13 7
GPIO context, MOV: 7 7 10 10 10 11 12 13 7
[/code]
So what does this say?
First, note that I've added diagnostics to confirm that the GPIO context
instruction does what it's supposed to do (enable an unused GPIO
module), and that the instruction to reset the context works.
Let's expand the empty, one, and two delay versions of each case to see
what it is we've timed. These are extracted from
[font=monospace]main.dis-Os[/font] in the gist.
Null context, NOP:
[code]
35:main.c **** t0 = BSPACM_CORE_CYCCNT();
35 0000 214B ldr r3, .L2
36 0002 5A68 ldr r2, [r3, #4]
36:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
39 0004 5968 ldr r1, [r3, #4]
40 0006 8A1A subs r2, r1, r2
42 0008 0260 str r2, [r0]
38:main.c **** t0 = BSPACM_CORE_CYCCNT();
44 000a 5A68 ldr r2, [r3, #4]
39:main.c **** DELAY_INSN_NOP();
48 000c 00BF nop
40:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
53 000e 5968 ldr r1, [r3, #4]
54 0010 8A1A subs r2, r1, r2
56 0012 4260 str r2, [r0, #4]
42:main.c **** t0 = BSPACM_CORE_CYCCNT();
58 0014 5A68 ldr r2, [r3, #4]
43:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
62 0016 00BF nop
65 0018 00BF nop
44:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
70 001a 5968 ldr r1, [r3, #4]
71 001c 8A1A subs r2, r1, r2
73 001e 8260 str r2, [r0, #8]
[/code]
Good, so it's doing what we expect in the most basic case. What about
[font=monospace]MOV[/font]?
[code]
80:main.c **** t0 = BSPACM_CORE_CYCCNT();
240 0000 214B ldr r3, .L5
241 0002 5A68 ldr r2, [r3, #4]
81:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
244 0004 5968 ldr r1, [r3, #4]
245 0006 8A1A subs r2, r1, r2
247 0008 0260 str r2, [r0]
83:main.c **** t0 = BSPACM_CORE_CYCCNT();
249 000a 5A68 ldr r2, [r3, #4]
84:main.c **** DELAY_INSN_MOV();
253 000c C046 mov r8, r8
85:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
258 000e 5968 ldr r1, [r3, #4]
259 0010 8A1A subs r2, r1, r2
261 0012 4260 str r2, [r0, #4]
87:main.c **** t0 = BSPACM_CORE_CYCCNT();
263 0014 5A68 ldr r2, [r3, #4]
88:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
267 0016 C046 mov r8, r8
270 0018 C046 mov r8, r8
89:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
275 001a 5968 ldr r1, [r3, #4]
276 001c 8A1A subs r2, r1, r2
278 001e 8260 str r2, [r0, #8]
[/code]
Good: those differ only in the delay instruction, and it's the same
number of octets in the instruction stream.
Now let's see what the bitband assignment does to the instruction sequence:
[code]
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
444 0000 394A ldr r2, .L8
126:main.c **** CONTEXT_INSN_GPIO();
446 0002 3A4B ldr r3, .L8+4
447 0004 0121 movs r1, #1
122:main.c **** {
449 0006 30B5 push {r4, r5, lr}
125:main.c **** t0 = BSPACM_CORE_CYCCNT();
455 0008 5468 ldr r4, [r2, #4]
458 000a 1960 str r1, [r3]
127:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
461 000c 5568 ldr r5, [r2, #4]
462 000e 2C1B subs r4, r5, r4
464 0010 0460 str r4, [r0]
128:main.c **** RESTORE_CONTEXT_INSN_GPIO();
466 0012 0024 movs r4, #0
467 0014 1C60 str r4, [r3]
130:main.c **** t0 = BSPACM_CORE_CYCCNT();
469 0016 5468 ldr r4, [r2, #4]
131:main.c **** CONTEXT_INSN_GPIO();
472 0018 1960 str r1, [r3]
132:main.c **** DELAY_INSN_NOP();
475 001a 00BF nop
133:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
480 001c 5368 ldr r3, [r2, #4]
481 001e 1B1B subs r3, r3, r4
482 0020 4360 str r3, [r0, #4]
134:main.c **** RESTORE_CONTEXT_INSN_GPIO();
484 0022 324B ldr r3, .L8+4
485 0024 0021 movs r1, #0
486 0026 1960 str r1, [r3]
136:main.c **** t0 = BSPACM_CORE_CYCCNT();
488 0028 5168 ldr r1, [r2, #4]
137:main.c **** CONTEXT_INSN_GPIO();
491 002a 0122 movs r2, #1 // *** OOPS
492 002c 1A60 str r2, [r3]
138:main.c **** DELAY_INSN_NOP(); DELAY_INSN_NOP();
495 002e 00BF nop
498 0030 00BF nop
139:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
503 0032 2D4A ldr r2, .L8
504 0034 5368 ldr r3, [r2, #4]
505 0036 5B1A subs r3, r3, r1
506 0038 8360 str r3, [r0, #8]
140:main.c **** RESTORE_CONTEXT_INSN_GPIO();
508 003a 2C4B ldr r3, .L8+4
509 003c 0021 movs r1, #0
511 003e 1960 str r1, [r3]
[/code]
Don't be misled: although the C source shows the read of the cycle
counter occurring before some overhead instructions (e.g. the push), the
actual read doesn't occur until offset 8. So what's being timed is what
we want.
For completeness, here's the GPIO context with a
[font=monospace]MOV[/font] delay instruction:
[code]
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
726 0000 394A ldr r2, .L11
189:main.c **** CONTEXT_INSN_GPIO();
728 0002 3A4B ldr r3, .L11+4
729 0004 0121 movs r1, #1
185:main.c **** {
731 0006 30B5 push {r4, r5, lr}
188:main.c **** t0 = BSPACM_CORE_CYCCNT();
737 0008 5468 ldr r4, [r2, #4]
740 000a 1960 str r1, [r3]
190:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
743 000c 5568 ldr r5, [r2, #4]
744 000e 2C1B subs r4, r5, r4
746 0010 0460 str r4, [r0]
191:main.c **** RESTORE_CONTEXT_INSN_GPIO();
748 0012 0024 movs r4, #0
749 0014 1C60 str r4, [r3]
193:main.c **** t0 = BSPACM_CORE_CYCCNT();
751 0016 5468 ldr r4, [r2, #4]
194:main.c **** CONTEXT_INSN_GPIO();
754 0018 1960 str r1, [r3]
195:main.c **** DELAY_INSN_MOV();
757 001a C046 mov r8, r8
196:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
762 001c 5368 ldr r3, [r2, #4]
763 001e 1B1B subs r3, r3, r4
764 0020 4360 str r3, [r0, #4]
197:main.c **** RESTORE_CONTEXT_INSN_GPIO();
766 0022 324B ldr r3, .L11+4
767 0024 0021 movs r1, #0
768 0026 1960 str r1, [r3]
199:main.c **** t0 = BSPACM_CORE_CYCCNT();
770 0028 5168 ldr r1, [r2, #4]
200:main.c **** CONTEXT_INSN_GPIO();
773 002a 0122 movs r2, #1 // *** OOPS
774 002c 1A60 str r2, [r3]
201:main.c **** DELAY_INSN_MOV(); DELAY_INSN_MOV();
777 002e C046 mov r8, r8
780 0030 C046 mov r8, r8
202:main.c **** *dp++ = BSPACM_CORE_CYCCNT() - t0;
785 0032 2D4A ldr r2, .L11
786 0034 5368 ldr r3, [r2, #4]
787 0036 5B1A subs r3, r3, r1
788 0038 8360 str r3, [r0, #8]
203:main.c **** RESTORE_CONTEXT_INSN_GPIO();
790 003a 2C4B ldr r3, .L11+4
791 003c 0021 movs r1, #0
793 003e 1960 str r1, [r3]
[/code]
Repeating the timing results:
[code]
Null context, NOP: 1 2 3 4 5 6 7 8 1
Null context, MOV: 1 3 4 5 6 7 8 9 1
[/code]
[font=monospace]NOP[/font] consistently introduces a one-cycle delay,
which is what us old-timers would expect an opcode named "NOP" to do.
The [font=monospace]MOV R8,R8[/font] instruction also introduces a
one-cycle delay, but can be pipelined one level so a single instance in
isolation takes two cycles.
[code]
GPIO context, NOP: 7 7 10 10 10 11 12 13 7
GPIO context, MOV: 7 7 10 10 10 11 12 13 7
[/code]
This results requires a little analysis. If you look at the code, is
that the versions with zero and one delay instruction are what we want
to time. With two delay instructions the compiler happens to have
loaded the RHS of the bitband store operation into a register within the
timed sequence (at the point marked as [font=monospace]*** OOPS[/font]
in the listing above.
When [font=monospace]-O2[/font] is used instead of
[font=monospace]-Os[/font] the compiler's smarter and doesn't do the
load within the timed sequence:
[code]
Null context, NOP: 1 2 3 4 5 6 7 8 1
Null context, MOV: 1 3 4 5 6 7 8 9 1
GPIO context, NOP: 7 7 7 7 7 8 9 10 7
GPIO context, MOV: 7 7 7 7 7 8 9 10 7
[/code]
You can go look at [font=monospace]main.dis-O2[/font] to check out
what's being timed here, but it's exactly what should be timed.
What this shows is that the peripheral bitband write takes six cycles,
and the delay instruction gets absorbed into that regardless of which
delay instruction is used.
My conclusions:
[list]
[*]Use [font=monospace]__NOP()[/font]. Where it has an
effect, it's a one-cycle effect. Where it doesn't, other instructions
don't either.[/*]
[*]The effect of the pipeline is much bigger than I anticipated, and attempts
to do small (1-3) cycle delays have fragile dependencies on the
surrounding instructions, which in turn depend on the compiler and its
optimization flags.[/*]
[/list]
(Appendix: The [font=monospace]-O2[/font] results above a fix for a subtle
error in the original timing approach. The original results were:
[code]
Null context, NOP: 1 5 6 9 10 11 12 13 1
Null context, MOV: 1 5 6 9 10 11 12 13 1
GPIO context, NOP: 7 7 7 7 7 8 9 10 7
GPIO context, MOV: 7 7 7 7 7 8 9 10 7
[/code]
Can you figure out what might have caused this? The answer is made
explicit in the git commit history, but it's also present in the
discussion above.)
Time spent: 2.5 hours.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment