|
|
  |
Перенос кода из под ИАРа на WinAVR, возникают некоторые вопросы... |
|
|
|
Nov 30 2008, 15:43
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(alx2 @ Nov 30 2008, 20:26)  В последних - это в каких? вот тут описано. Цитата(Rst7 @ Nov 30 2008, 20:28)  Это не помощь. А объезд кривого оптимизатора. По науке сам должен был структуру скопировать, а не по полям разносить. Ну если не понимает, то почему бы не подсказать? По крайней мере, это даёт результат  Цитата(Rst7 @ Nov 30 2008, 20:28)  ЗЫ Приведите, чтоли, получившийся код, глянем... Пожалуйста: CODE 17 .section .text.__vector_18,"ax",@progbits 18 .global __vector_18 19 .type __vector_18, @function 20 __vector_18: 21 .LFB2: 22 .LSM0: 23 /* prologue: frame size=0 */ 24 0000 1F92 push __zero_reg__ 25 0002 0F92 push __tmp_reg__ 26 0004 0FB6 in __tmp_reg__,__SREG__ 27 0006 0F92 push __tmp_reg__ 28 0008 1124 clr __zero_reg__ 29 000a 2F93 push r18 30 000c 3F93 push r19 31 000e 4F93 push r20 32 0010 5F93 push r21 33 0012 6F93 push r22 34 0014 7F93 push r23 35 0016 8F93 push r24 36 0018 9F93 push r25 37 001a AF93 push r26 38 001c EF93 push r30 39 001e FF93 push r31 40 /* prologue end (size=16) */ 41 .LSM1: 42 0020 5091 0000 lds r21,statusRx+3 43 .LVL0: 44 0024 A091 0000 lds r26,length.1644 45 .LVL1: 46 0028 4091 0000 lds r20,statusRx 47 002c 7091 0000 lds r23,statusRx+1 48 .LVL2: 49 .L2: 50 .LSM2: 51 0030 9BB1 in r25,43-0x20 52 .LSM3: 53 0032 6CB1 in r22,44-0x20 54 .LVL3: 55 .LSM4: 56 0034 8091 0000 lds r24,statusRx+2 57 0038 8823 tst r24 58 003a 01F0 breq .L3 59 .LSM5: 60 003c 5061 ori r21,lo8(16) 61 003e 00C0 rjmp .L5 62 .L3: 63 .LSM6: 64 0040 292F mov r18,r25 65 0042 30E0 ldi r19,lo8(0) 66 0044 C901 movw r24,r18 67 0046 8C71 andi r24,lo8(28) 68 0048 9070 andi r25,hi8(28) 69 004a 892B or r24,r25 70 004c 01F0 breq .L6 71 .LSM7: 72 004e 24FD sbrc r18,4 73 0050 5160 ori r21,lo8(1) 74 .L8: 75 .LSM8: 76 0052 23FD sbrc r18,3 77 0054 5260 ori r21,lo8(2) 78 .L10: 79 .LSM9: 80 0056 22FF sbrs r18,2 81 0058 00C0 rjmp .L28 82 005a 5460 ori r21,lo8(4) 83 005c 00C0 rjmp .L28 84 .L6: 85 .LSM10: 86 005e 50E0 ldi r21,lo8(0) 87 .LSM11: 88 0060 7130 cpi r23,lo8(1) 89 0062 01F0 breq .L14 90 0064 7230 cpi r23,lo8(2) 91 0066 01F4 brne .L5 92 0068 00C0 rjmp .L15 93 .L14: 94 .LSM12: 95 006a 4230 cpi r20,lo8(2) 96 006c 00F4 brsh .L16 97 .LBB2: 98 .LSM13: 99 006e E42F mov r30,r20 100 .LVL4: 101 0070 F0E0 ldi r31,lo8(0) 102 0072 E050 subi r30,lo8(-(sign.1643)) 103 0074 F040 sbci r31,hi8(-(sign.1643)) 104 0076 E081 ld r30,Z 105 0078 F0E0 ldi r31,lo8(0) 106 /* #APP */ 107 007a E491 lpm r30, Z 108 109 .LVL5: 110 /* #NOAPP */ 111 .LBE2: 112 007c 6E17 cp r22,r30 113 007e 01F4 brne .L27 114 .LSM14: 115 0080 4F5F subi r20,lo8(-(1)) 116 0082 00C0 rjmp .L5 117 .L16: 118 .LSM15: 119 0084 862F mov r24,r22 120 0086 8150 subi r24,lo8(-(-1)) 121 0088 8531 cpi r24,lo8(21) 122 008a 00F0 brlo .L20 123 .LSM16: 124 008c 58E0 ldi r21,lo8(8) 125 .L27: 126 008e 40E0 ldi r20,lo8(0) 127 0090 00C0 rjmp .L5 128 .L20: 129 .LSM17: 130 0092 6093 0000 sts rx_buffer,r22 131 .LSM18: 132 0096 A62F mov r26,r22 133 0098 AF5F subi r26,lo8(-(1)) 134 .LVL6: 135 009a 41E0 ldi r20,lo8(1) 136 009c 72E0 ldi r23,lo8(2) 137 009e 00C0 rjmp .L5 138 .LVL7: 139 .L15: 140 .LSM19: 141 00a0 E42F mov r30,r20 142 .LVL8: 143 00a2 F0E0 ldi r31,lo8(0) 144 00a4 E050 subi r30,lo8(-(rx_buffer)) 145 00a6 F040 sbci r31,hi8(-(rx_buffer)) 146 00a8 6083 st Z,r22 147 00aa 4F5F subi r20,lo8(-(1)) 148 .LSM20: 149 00ac A150 subi r26,lo8(-(-1)) 150 .LVL9: 151 .LSM21: 152 00ae 01F4 brne .L5 153 .LSM22: 154 00b0 81E0 ldi r24,lo8(1) 155 00b2 8093 0000 sts statusRx+2,r24 156 .LVL10: 157 .L28: 158 00b6 40E0 ldi r20,lo8(0) 159 00b8 71E0 ldi r23,lo8(1) 160 .LVL11: 161 .L5: 162 .LSM23: 163 00ba 5F99 sbic 43-0x20,7 164 00bc 00C0 rjmp .L2 165 00be A093 0000 sts length.1644,r26 166 00c2 4093 0000 sts statusRx,r20 167 00c6 7093 0000 sts statusRx+1,r23 168 .LSM24: 169 00ca 5093 0000 sts statusRx+3,r21 170 /* epilogue: frame size=0 */ 171 00ce FF91 pop r31 172 00d0 EF91 pop r30 173 00d2 AF91 pop r26 174 00d4 9F91 pop r25 175 00d6 8F91 pop r24 176 00d8 7F91 pop r23 177 00da 6F91 pop r22 178 00dc 5F91 pop r21 179 00de 4F91 pop r20 180 00e0 3F91 pop r19 181 00e2 2F91 pop r18 182 00e4 0F90 pop __tmp_reg__ 183 00e6 0FBE out __SREG__,__tmp_reg__ 184 00e8 0F90 pop __tmp_reg__ 185 00ea 1F90 pop __zero_reg__ 186 00ec 1895 reti 187 /* epilogue end (size=16) */ 188 /* function __vector_18 size 125 (93) */
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 30 2008, 15:48
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Кстати, я бы не рекомендовал использовать for() для обрамления критических блоков.... Все понятно, рука кодера дрогнет и все сломается. Не применяйте return, break для выхода из такой критической секции. Зато есть плюс - continue приводит к корректному выходу из этого блока. Приятный бонус  И самое главное - критическая секция из for - она портабельна. А вот в гнусе это реализовано благодаря дополнительным костылям, которые не соответствуют стандартамЦитата Пожалуйста: CODE.... А ниче так. До IAR'а правда не дотянул. ЧТД
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Nov 30 2008, 15:56
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(Rst7 @ Nov 30 2008, 18:48)  А вот в гнусе это реализовано благодаря дополнительным костылям, которые не соответствуют стандартам Ещё раз справшиваю, почему не делать так: Код #include <avr/interrupt.h> #include <util/atomic.h>
uint8_t get_SREG_and_CLI() { uint8_t s = SREG; cli(); return s; }
#define ATOMIC_CODE() for(uint8_t __temp=get_SREG_and_CLI(),iter=0; iter<1; iter++,SREG=__temp) for(int iter2=0; iter2 < 1; iter2++) Портабельно, без костылей, хошь на Яре, хоть на Гнусе. И вроде всё правильно отрабатывается?
|
|
|
|
|
Nov 30 2008, 16:11
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(Petka @ Nov 30 2008, 19:56)  Ещё раз справшиваю, почему не делать так: Код #include <avr/interrupt.h> #include <util/atomic.h>
uint8_t get_SREG_and_CLI() { uint8_t s = SREG; cli(); return s; }
#define ATOMIC_CODE() for(uint8_t __temp=get_SREG_and_CLI(),iter=0; iter<1; iter++,SREG=__temp) for(int iter2=0; iter2 < 1; iter2++) Портабельно, без костылей, хошь на Яре, хоть на Гнусе. И вроде всё правильно отрабатывается? А разве при встрече return в теле второго for будет выполняться SREG=__temp?
|
|
|
|
|
Nov 30 2008, 20:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(demiurg_spb @ Nov 30 2008, 19:17)  А тут с Ваших слов должно быть другое поведение. Может я чего не знаю о return. Хочется устранить пробелы... Сорри, извиняюсь. Ступил. Я конечно-же о break. Конечно-же от return не спасёт. Тут ко мне идиотская идея пришла: Код goto 10 ATOMIC_CODE(){ func1(); 10: func2(); goto 30; func3(); } 30: Будет-ли такое работать?
|
|
|
|
|
Nov 30 2008, 20:18
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Rst7 @ Nov 30 2008, 18:48)  А ниче так. До IAR'а правда не дотянул. ЧТД  Ну раз уж тут IAR vs GCC... Не могли бы Вы собрать вот этот примерчик под IAR: Код #define ARR_SIZE 100
unsigned char src1[ARR_SIZE],src2[ARR_SIZE],dst[ARR_SIZE];
void copy_xor(unsigned char *dst, unsigned char *src1, unsigned char *src2, unsigned char count) {
if (count) { do { *dst++ = *src1++ ^ *src2++; } while (--count); } }
int main(void) {
copy_xor(dst, src1, src2, ARR_SIZE);
while (1); return 0; } и посчитать сколько МЦ циклов это займет под IAR: copy_xor(dst, src1, src2, ARR_SIZE); под gcc это занимает 1026МЦ включая передачу параметров...
|
|
|
|
|
Nov 30 2008, 20:35
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(singlskv @ Nov 30 2008, 22:18)  Ну раз уж тут IAR vs GCC... Не могли бы Вы собрать вот этот примерчик под IAR: Я знаю, что будет не очень хорошо. Потому что в гнусе есть еще один указатель. Занятие отдельного указателя под стек конечно ухудшает код в таком случае. Но на самом деле, наверняка можно убрать необходимость третьего указателя, но тут надо рассматривать функцию в общем контексте. PS Давайте тогда 4 указателя сделаем, чтобы и гнусь обгадился  PPS На самом деле даже на IAR'е можно сделать код, который не очень проиграет этому. PPPS Кстати, а слабо конкретно этот код собрать последним гнусем. А то в связи с багом это черевато тем, что будет очень ужасно
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Nov 30 2008, 20:51
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Petka @ Nov 30 2008, 23:11)  Тут ко мне идиотская идея пришла: Код goto 10 ATOMIC_CODE(){ func1(); 10: func2(); goto 30; func3(); } 30: Будет-ли такое работать? На мой взгляд не будет: goto заменится на jmp/rjmp и всё...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Nov 30 2008, 21:00
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Rst7 @ Nov 30 2008, 23:35)  Я знаю, что будет не очень хорошо. Потому что в гнусе есть еще один указатель. Занятие отдельного указателя под стек конечно ухудшает код в таком случае. Но на самом деле, наверняка можно убрать необходимость третьего указателя, но тут надо рассматривать функцию в общем контексте. Ну дык это будет всегда когда данные будут из >2источников (структур, массивов, итд) Цитата PS Давайте тогда 4 указателя сделаем, чтобы и гнусь обгадился  для 4: Код void copy_xor(unsigned char *dst, unsigned char *src1, unsigned char *src2, unsigned char *src3, unsigned char count) {
if (count) { do { *dst++ = *src1++ ^ *src2++ ^ *src3++; } while (--count); } } 1740 МЦ, а сколько на IAR ? Цитата PPS На самом деле даже на IAR'е можно сделать код, который не очень проиграет этому. А это как ? Если копировать побайтно... Цитата PPPS Кстати, а слабо конкретно этот код собрать последним гнусем. А то в связи с багом это черевато тем, что будет очень ужасно  А вот это без меня  я сижу на gcc3.4.6 (winavr20060421) и никуда пока не собираюсь, пускай по граблям ходют другие...
|
|
|
|
|
Nov 30 2008, 21:45
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
avr-gcc 4.4 Код void copy_xor(unsigned char * dst, unsigned char * src1, unsigned char * src2, unsigned char count) {
if (count) { do { *dst++ = *src1++ ^ *src2++; } while (--count); } } -Os Код void copy_xor(unsigned char * dst, unsigned char * src1, unsigned char * src2, unsigned char count) { ce: ef 92 push r14 d0: ff 92 push r15 d2: 0f 93 push r16 d4: 1f 93 push r17 d6: cf 93 push r28 d8: df 93 push r29
if (count) da: 22 23 and r18, r18 dc: c9 f0 breq .+50; 0x110 <copy_xor+0x42>
#define ARR_SIZE 100
unsigned char src1[ARR_SIZE],src2[ARR_SIZE],dst[ARR_SIZE];
void copy_xor(unsigned char * dst, unsigned char * src1, unsigned char * src2, unsigned char count) de: 21 50 subi r18, 0x01; 1 e0: 30 e0 ldi r19, 0x00; 0 e2: 2f 5f subi r18, 0xFF; 255 e4: 3f 4f sbci r19, 0xFF; 255 e6: e0 e0 ldi r30, 0x00; 0 e8: f0 e0 ldi r31, 0x00; 0
if (count) { do { *dst++ = *src1++ ^ *src2++; ea: 7c 01 movw r14, r24 ec: ee 0e add r14, r30 ee: ff 1e adc r15, r31 f0: 8a 01 movw r16, r20 f2: 0e 0f add r16, r30 f4: 1f 1f adc r17, r31 f6: eb 01 movw r28, r22 f8: ce 0f add r28, r30 fa: df 1f adc r29, r31 fc: d8 01 movw r26, r16 fe: 0c 91 ld r16, X 100: 18 81 ld r17, Y 102: 10 27 eor r17, r16 104: d7 01 movw r26, r14 106: 1c 93 st X, r17 108: 31 96 adiw r30, 0x01; 1 } while (--count); 10a: e2 17 cp r30, r18 10c: f3 07 cpc r31, r19 10e: 69 f7 brne .-38; 0xea <copy_xor+0x1c> } } 110: df 91 pop r29 112: cf 91 pop r28 114: 1f 91 pop r17 116: 0f 91 pop r16 118: ff 90 pop r15 11a: ef 90 pop r14 11c: 08 95 ret -Os -fno-ivopts Код void copy_xor(unsigned char * dst, unsigned char * src1, unsigned char * src2, unsigned char count) { ce: cf 93 push r28 d0: df 93 push r29 d2: fc 01 movw r30, r24 d4: db 01 movw r26, r22 d6: ea 01 movw r28, r20
if (count) d8: 22 23 and r18, r18 da: 31 f0 breq .+12; 0xe8 <copy_xor+0x1a> { do { *dst++ = *src1++ ^ *src2++; dc: 99 91 ld r25, Y+ de: 8d 91 ld r24, X+ e0: 89 27 eor r24, r25 e2: 81 93 st Z+, r24 } while (--count); e4: 21 50 subi r18, 0x01; 1 e6: f8 cf rjmp .-16; 0xd8 <copy_xor+0xa> } } e8: df 91 pop r29 ea: cf 91 pop r28 ec: 08 95 ret Вы не умеете его готовить. Анатолий.
Сообщение отредактировал aesok - Nov 30 2008, 21:54
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|