// Program where loop-head optimization produces wrong return value // Reported by Richard-William Loerakker .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" .label BORDER_COLOR = $d020 .label BG_COLOR = $d021 main: { .label result = 2 .label kaputt = $a // mul16u(4,123) jsr mul16u // mul16u(4,123) // result = mul16u(4,123) // kaputt = kaputt lda.z kaputt+1 // *BG_COLOR = >kaputt sta BG_COLOR // } rts } // Perform binary multiplication of two unsigned 16-bit unsigned ints into a 32-bit unsigned long // mul16u(word zp($a) a) mul16u: { .const b = $7b .label a = $a .label mb = 6 .label res = 2 .label return = 2 lda #b sta.z mb+1 lda #>$10 sta.z mb+2 lda #>b>>$10 sta.z mb+3 lda #<0 sta.z res sta.z res+1 lda #<0>>$10 sta.z res+2 lda #>0>>$10 sta.z res+3 lda #<4 sta.z a lda #>4 sta.z a+1 __b1: // while(a!=0) lda.z a bne __b2 lda.z a+1 bne __b2 // } rts __b2: // a&1 lda #1 and.z a // if( (a&1) != 0) cmp #0 beq __b3 // res = res + mb lda.z res clc adc.z mb sta.z res lda.z res+1 adc.z mb+1 sta.z res+1 lda.z res+2 adc.z mb+2 sta.z res+2 lda.z res+3 adc.z mb+3 sta.z res+3 __b3: // a = a>>1 lsr.z a+1 ror.z a // mb = mb<<1 asl.z mb rol.z mb+1 rol.z mb+2 rol.z mb+3 jmp __b1 }