Skip to content

Frame pointer clobbered in some functions which have spills #38

Closed
@gergoerdi

Description

@gergoerdi

I'm trying to add an interrupt handler to TIMER1_COMPA to flash PB5. Here's what I tried:

#[no_mangle]
pub unsafe extern "avr-interrupt" fn __vector_11() {
    volatile_store(PORTB, volatile_load(PORTB) ^ MASK);
}

simavr reports that the generated executable goes wrong after running the handler twice:

CORE: *** Invalid read address PC=0136 SP=2022 O=901f Address 2023 out of ram (08ff)
avr_sadly_crashed

Standalone, full test case:

#![feature(no_core)]
#![feature(lang_items)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(optin_builtin_traits)]
#![feature(asm)]
#![feature(abi_avr_interrupt)]

#![no_core]
#![no_main]

mod clone {
    use marker::Sized;

    pub trait Clone : Sized {
        fn clone(&self) -> Self;

        #[inline(always)]
        fn clone_from(&mut self, source: &Self) {
            *self = source.clone()
        }
    }
}

mod marker {
    use clone::Clone;

    #[lang = "sized"]
    #[fundamental]
    pub trait Sized {}

    #[lang = "copy"]
    pub trait Copy : Clone {}


    #[lang = "freeze"]
    unsafe trait Freeze {}

    unsafe impl Freeze for .. {}
}

mod ops {
    #[lang = "bitor"]
    pub trait BitOr {
        fn bitor(self, rhs: Self) -> Self;
    }

    impl BitOr for u8 {
        #[inline]
        fn bitor(self, rhs: u8) -> u8 { self | rhs }
    }


    #[lang = "bitxor"]
    pub trait BitXor {
        fn bitxor(self, rhs: Self) -> Self;
    }

    impl BitXor for u8 {
        #[inline]
        fn bitxor(self, other: u8) -> u8 { self ^ other }
    }
}

mod intrinsics {
    extern "rust-intrinsic" {
        pub fn volatile_load<T>(src: *const T) -> T;
        pub fn volatile_store<T>(dst: *mut T, val: T);
    }
}

use intrinsics::{volatile_load, volatile_store};

mod avr {
    pub const DDRB:   *mut u8  = 0x24 as *mut u8;
    pub const PORTB:  *mut u8  = 0x25 as *mut u8;
    pub const TCCR1B: *mut u8  = 0x81 as *mut u8;
    pub const TIMSK1: *mut u8  = 0x6f as *mut u8;
    pub const OCR1A:  *mut u16 = 0x88 as *mut u16;
}

use avr::*;

const MASK: u8 = 0b_0010_0000;

#[no_mangle]
pub extern fn main() {
    unsafe {
        volatile_store(DDRB, volatile_load(DDRB) | MASK);

        // Configure timer 1 for CTC mode, with divider of 64
        volatile_store(TCCR1B, volatile_load(TCCR1B) | 0b_0000_1101);

        // Timer frequency
        volatile_store(OCR1A, 62500);

        // Enable CTC interrupt
        volatile_store(TIMSK1, volatile_load(TIMSK1) | 0b_0000_0010);

        // Good to go!
        asm!("SEI");

        loop {}
    }
}

#[no_mangle]
pub unsafe extern "avr-interrupt" fn __vector_11() {
    volatile_store(PORTB, volatile_load(PORTB) ^ MASK);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-llvmAffects the LLVM AVR backendhas-llvm-commitThis issue should be fixed in upstream LLVMhas-reduced-testcaseA small LLVM IR file exists that demonstrates the problem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions