This is the pinchangeint inner loop prior to the optimisations being discussed here, for those watching the discussion, this is the most important part to optimise because it is potentially executed many times on each interrupt -
A lot of the code is relating to the if statements -
thisChangedPin=p->mask & changedPins;
340: 6b 81 ldd r22, Y+3 ; 0x03
342: 8f 2d mov r24, r15
344: 86 23 and r24, r22
if (thisChangedPin) {
346: 71 f1 breq .+92 ; 0x3a4 <_ZN9PCintPort5PCintEv+0x86>
if ((thisChangedPin & portRisingPins & PCintPort::curr ) ||
348: 48 2f mov r20, r24
34a: 50 e0 ldi r21, 0x00 ; 0
34c: f8 01 movw r30, r16
34e: 85 81 ldd r24, Z+5 ; 0x05
350: 20 91 44 01 lds r18, 0x0144
354: 90 e0 ldi r25, 0x00 ; 0
356: 84 23 and r24, r20
358: 95 23 and r25, r21
35a: 30 e0 ldi r19, 0x00 ; 0
35c: 82 23 and r24, r18
35e: 93 23 and r25, r19
360: 89 2b or r24, r25
362: 69 f4 brne .+26 ; 0x37e <_ZN9PCintPort5PCintEv+0x60>
364: 86 81 ldd r24, Z+6 ; 0x06
366: 20 91 44 01 lds r18, 0x0144
36a: 90 e0 ldi r25, 0x00 ; 0
36c: 48 23 and r20, r24
36e: 59 23 and r21, r25
370: 30 e0 ldi r19, 0x00 ; 0
372: 20 95 com r18
374: 30 95 com r19
376: 42 23 and r20, r18
378: 53 23 and r21, r19
37a: 45 2b or r20, r21
37c: 99 f0 breq .+38 ; 0x3a4 <_ZN9PCintPort5PCintEv+0x86>
(thisChangedPin & portFallingPins & ~PCintPort::curr ))
{
// Trigger interrupt if the bit is high and it's set to trigger on mode RISING or CHANGE
// Trigger interrupt if the bit is low and it's set to trigger on mode FALLING or CHANGE
#ifndef NO_PIN_STATE
PCintPort::pinState=PCintPort::curr & p->mask ? HIGH : LOW;
37e: 20 91 44 01 lds r18, 0x0144
382: 40 e0 ldi r20, 0x00 ; 0
384: 86 2f mov r24, r22
386: 90 e0 ldi r25, 0x00 ; 0
388: 30 e0 ldi r19, 0x00 ; 0
38a: 82 23 and r24, r18
38c: 93 23 and r25, r19
38e: 89 2b or r24, r25
390: 09 f0 breq .+2 ; 0x394 <_ZN9PCintPort5PCintEv+0x76>
392: 41 e0 ldi r20, 0x01 ; 1
394: 40 93 46 01 sts 0x0146, r20
#endif
#ifndef NO_PIN_NUMBER
PCintPort::arduinoPin=p->arduinoPin;
398: 8c 81 ldd r24, Y+4 ; 0x04
39a: 80 93 45 01 sts 0x0145, r24
#endif
#ifdef PINMODE
PCintPort::pinmode=p->mode;
#endif
p->PCintFunc();
39e: e8 81 ld r30, Y
3a0: f9 81 ldd r31, Y+1 ; 0x01
3a2: 09 95 icall
}
}
p=p->next;
3a4: 0d 80 ldd r0, Y+5 ; 0x05
3a6: de 81 ldd r29, Y+6 ; 0x06
3a8: c0 2d mov r28, r0
uint8_t changedPins = PCintPort::curr ^ lastPinView;
//changedPins &= portPCMask;
lastPinView = PCintPort::curr;
PCintPin* p = firstPin; // 3427
while (p) {
3aa: 20 97 sbiw r28, 0x00 ; 0
3ac: 49 f6 brne .-110 ; 0x340 <_ZN9PCintPort5PCintEv+0x22>
}
}
p=p->next;
Disassembled by following this procedure -
Duane B