Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@0:77155d68f532, 2011-01-28 (annotated)
- Committer:
- simon
- Date:
- Fri Jan 28 10:04:43 2011 +0000
- Revision:
- 0:77155d68f532
- Child:
- 1:eaf79a9d2939
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| simon | 0:77155d68f532 | 1 | // sford, Examples of C-based optimisations of... |
| simon | 0:77155d68f532 | 2 | // |
| simon | 0:77155d68f532 | 3 | // INTEGER TO BINARY by J.P. Armstrong |
| simon | 0:77155d68f532 | 4 | // http://www.armtronics.com/ |
| simon | 0:77155d68f532 | 5 | // |
| simon | 0:77155d68f532 | 6 | // Improved by Igor Skochinsky |
| simon | 0:77155d68f532 | 7 | // |
| simon | 0:77155d68f532 | 8 | // PART OF CODE FROM: |
| simon | 0:77155d68f532 | 9 | // http://mbed.org/cookbook/Assembly-Language |
| simon | 0:77155d68f532 | 10 | |
| simon | 0:77155d68f532 | 11 | #include "mbed.h" |
| simon | 0:77155d68f532 | 12 | |
| simon | 0:77155d68f532 | 13 | // This program will blink LED1 and LED4 |
| simon | 0:77155d68f532 | 14 | // using assembly language for LED1 and |
| simon | 0:77155d68f532 | 15 | // API functions for LED4 |
| simon | 0:77155d68f532 | 16 | // declare external assembly language function (in a *.s file) |
| simon | 0:77155d68f532 | 17 | extern "C" int binasm(int value); |
| simon | 0:77155d68f532 | 18 | |
| simon | 0:77155d68f532 | 19 | #define L1 0x040000 |
| simon | 0:77155d68f532 | 20 | #define L2 0x100000 |
| simon | 0:77155d68f532 | 21 | #define L3 0x200000 |
| simon | 0:77155d68f532 | 22 | #define L4 0x800000 |
| simon | 0:77155d68f532 | 23 | |
| simon | 0:77155d68f532 | 24 | #define ALLLEDS (L1 | L2 | L3 | L4) |
| simon | 0:77155d68f532 | 25 | |
| simon | 0:77155d68f532 | 26 | #define GPIO1BASE 0x2009C020 |
| simon | 0:77155d68f532 | 27 | #define GPIOSETOFF 0x18 |
| simon | 0:77155d68f532 | 28 | #define GPIOCLROFF 0x1C |
| simon | 0:77155d68f532 | 29 | |
| simon | 0:77155d68f532 | 30 | const uint32_t masks[] = {L1, L2, L3, L4}; |
| simon | 0:77155d68f532 | 31 | |
| simon | 0:77155d68f532 | 32 | // the asm code, translated in to a more natural expressive C function |
| simon | 0:77155d68f532 | 33 | void binc(int value) { |
| simon | 0:77155d68f532 | 34 | LPC_GPIO1->FIOCLR = ALLLEDS; |
| simon | 0:77155d68f532 | 35 | value += 1; |
| simon | 0:77155d68f532 | 36 | for(int i=0; i<4; i++) { |
| simon | 0:77155d68f532 | 37 | if((value >> i) & 1) { |
| simon | 0:77155d68f532 | 38 | LPC_GPIO1->FIOSET = masks[i]; |
| simon | 0:77155d68f532 | 39 | } else { |
| simon | 0:77155d68f532 | 40 | LPC_GPIO1->FIOCLR = masks[i]; |
| simon | 0:77155d68f532 | 41 | } |
| simon | 0:77155d68f532 | 42 | } |
| simon | 0:77155d68f532 | 43 | } |
| simon | 0:77155d68f532 | 44 | |
| simon | 0:77155d68f532 | 45 | // creating the mask values before writing them to registers |
| simon | 0:77155d68f532 | 46 | void binc2(int value) { |
| simon | 0:77155d68f532 | 47 | value += 1; |
| simon | 0:77155d68f532 | 48 | uint32_t set = 0; |
| simon | 0:77155d68f532 | 49 | uint32_t clr = 0; |
| simon | 0:77155d68f532 | 50 | |
| simon | 0:77155d68f532 | 51 | for(int i=0; i<4; i++) { |
| simon | 0:77155d68f532 | 52 | if((value >> i) & 1) { |
| simon | 0:77155d68f532 | 53 | set = masks[i]; |
| simon | 0:77155d68f532 | 54 | } else { |
| simon | 0:77155d68f532 | 55 | clr = masks[i]; |
| simon | 0:77155d68f532 | 56 | } |
| simon | 0:77155d68f532 | 57 | } |
| simon | 0:77155d68f532 | 58 | LPC_GPIO1->FIOSET = set; |
| simon | 0:77155d68f532 | 59 | LPC_GPIO1->FIOCLR = clr; |
| simon | 0:77155d68f532 | 60 | } |
| simon | 0:77155d68f532 | 61 | |
| simon | 0:77155d68f532 | 62 | const uint32_t masks2[] = { |
| simon | 0:77155d68f532 | 63 | L1, |
| simon | 0:77155d68f532 | 64 | L2, |
| simon | 0:77155d68f532 | 65 | L2 | L1, |
| simon | 0:77155d68f532 | 66 | L3, |
| simon | 0:77155d68f532 | 67 | L3 | L1, |
| simon | 0:77155d68f532 | 68 | L3 | L2, |
| simon | 0:77155d68f532 | 69 | L3 | L2 | L1, |
| simon | 0:77155d68f532 | 70 | L4, |
| simon | 0:77155d68f532 | 71 | L4 | L1, |
| simon | 0:77155d68f532 | 72 | L4 | L2, |
| simon | 0:77155d68f532 | 73 | L4 | L2 | L1, |
| simon | 0:77155d68f532 | 74 | L4 | L3, |
| simon | 0:77155d68f532 | 75 | L4 | L3 | L1, |
| simon | 0:77155d68f532 | 76 | L4 | L3 | L2, |
| simon | 0:77155d68f532 | 77 | L4 | L3 | L2 | L1 |
| simon | 0:77155d68f532 | 78 | }; |
| simon | 0:77155d68f532 | 79 | |
| simon | 0:77155d68f532 | 80 | // using a full lookup for the masks (space vs time tradeoff) |
| simon | 0:77155d68f532 | 81 | void binc3(int value) { |
| simon | 0:77155d68f532 | 82 | value += 1; |
| simon | 0:77155d68f532 | 83 | uint32_t set = masks2[value]; |
| simon | 0:77155d68f532 | 84 | uint32_t clr = ~masks2[value] & ALLLEDS; |
| simon | 0:77155d68f532 | 85 | LPC_GPIO1->FIOSET = set; |
| simon | 0:77155d68f532 | 86 | LPC_GPIO1->FIOCLR = clr; |
| simon | 0:77155d68f532 | 87 | } |
| simon | 0:77155d68f532 | 88 | |
| simon | 0:77155d68f532 | 89 | DigitalOut myled1(LED1); |
| simon | 0:77155d68f532 | 90 | DigitalOut myled2(LED2); |
| simon | 0:77155d68f532 | 91 | DigitalOut myled3(LED3); |
| simon | 0:77155d68f532 | 92 | DigitalOut myled4(LED4); |
| simon | 0:77155d68f532 | 93 | |
| simon | 0:77155d68f532 | 94 | // timing functions |
| simon | 0:77155d68f532 | 95 | |
| simon | 0:77155d68f532 | 96 | Timer t; |
| simon | 0:77155d68f532 | 97 | |
| simon | 0:77155d68f532 | 98 | void START(char *msg) { |
| simon | 0:77155d68f532 | 99 | printf("Timing %s\n", msg); |
| simon | 0:77155d68f532 | 100 | t.start(); |
| simon | 0:77155d68f532 | 101 | t.reset(); |
| simon | 0:77155d68f532 | 102 | } |
| simon | 0:77155d68f532 | 103 | |
| simon | 0:77155d68f532 | 104 | void STOP() { |
| simon | 0:77155d68f532 | 105 | int v = t.read_us(); |
| simon | 0:77155d68f532 | 106 | printf(" - %d us\n", v); |
| simon | 0:77155d68f532 | 107 | } |
| simon | 0:77155d68f532 | 108 | |
| simon | 0:77155d68f532 | 109 | #define LOOPS 100000 |
| simon | 0:77155d68f532 | 110 | |
| simon | 0:77155d68f532 | 111 | int main() { |
| simon | 0:77155d68f532 | 112 | START("Assembly"); |
| simon | 0:77155d68f532 | 113 | for(int i=0; i<LOOPS; i++) { |
| simon | 0:77155d68f532 | 114 | binasm(i % 16); |
| simon | 0:77155d68f532 | 115 | } |
| simon | 0:77155d68f532 | 116 | STOP(); |
| simon | 0:77155d68f532 | 117 | |
| simon | 0:77155d68f532 | 118 | START("C translation"); |
| simon | 0:77155d68f532 | 119 | for(int i=0; i<LOOPS; i++) { |
| simon | 0:77155d68f532 | 120 | binc(i % 16); |
| simon | 0:77155d68f532 | 121 | } |
| simon | 0:77155d68f532 | 122 | STOP(); |
| simon | 0:77155d68f532 | 123 | |
| simon | 0:77155d68f532 | 124 | START("C reg-writes outside the loop"); |
| simon | 0:77155d68f532 | 125 | for(int i=0; i<LOOPS; i++) { |
| simon | 0:77155d68f532 | 126 | binc2(i % 16); |
| simon | 0:77155d68f532 | 127 | } |
| simon | 0:77155d68f532 | 128 | STOP(); |
| simon | 0:77155d68f532 | 129 | |
| simon | 0:77155d68f532 | 130 | START("C with mask lookup table"); |
| simon | 0:77155d68f532 | 131 | for(int i=0; i<LOOPS; i++) { |
| simon | 0:77155d68f532 | 132 | binc3(i % 16); |
| simon | 0:77155d68f532 | 133 | } |
| simon | 0:77155d68f532 | 134 | STOP(); |
| simon | 0:77155d68f532 | 135 | |
| simon | 0:77155d68f532 | 136 | START("C with mask lookup table, but caller loop optimised"); |
| simon | 0:77155d68f532 | 137 | for(int i=0; i<LOOPS; i++) { |
| simon | 0:77155d68f532 | 138 | binc3(i & 0xF); |
| simon | 0:77155d68f532 | 139 | } |
| simon | 0:77155d68f532 | 140 | STOP(); |
| simon | 0:77155d68f532 | 141 | } |