afgncaap - 2009-01-09

So, sorry if this has already been answered somewhere, I can't seem to see anything:

I have been working on a context swap, and it seems that sdcc, even with model large used, uses the local stack for the address of the return function.  Because I am swapping, this is trashed, so I have been using the peephole to replace LCALL/RET with LJMP.  I think that code should now work as intended, but now, when I try to compile, I get the error:

sdcc  --peep-file ../../src/kernel/hal/cc243X/peep.c --stack-auto --xstack --mod
el-large -L "C:\Program Files\SDCC\lib\large-stack-auto-xstack" -I. -mmcs51 --xr
am-loc 0xE000 -D NANORK -D __SDCC__ -D NODE_ADDR=0 -I . -I../../src/platform/inc
lude -I../../src/platform/cc243X/include -I../../src/radio/cc243X/include -I../.
./src/radio/cc243X/hal/cc243X -I../../src/radio/cc243X/platform/cc243X -I../../s
rc/drivers/include -I../../src/drivers/platform/cc243X/include -I../../src/kerne
l/include -I../../src/kernel/hal/include --std-sdcc89  --debug  -c  ../../src/ke
rnel/source/nrk.c -o ../../src/kernel/source/nrk.rel

...

../../src/kernel/source/nrk.c:212: error 9: FATAL Compiler Internal Error in fil
e '/home/sdcc-builder/build/sdcc-build/orig/sdcc/src/mcs51/peep.c' line number '
180' : error in deadmove
Contact Author with source code

where peep.c is my peephole file.  If I compile with the peep.c empty, there is no error.  If I compile with the function in nrk.c removed, I just get an error 9 somewhere else.
What is "deadmove," and why is the my peephole file and the .c file interacting in the first place?  Am I going about this whole thing wrong?

Compiled with version SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.8.4 #5242 (Sep 22 2008) (MINGW32)

files peep.c and nrk.c below:

peep.c_____________________________________________________________
replace {
    lcall %1
} by {
    push acc
    mov r0, _spx
    mov a,pcl
    add a,#0x15
    movx @r0,a
    inc r0
    mov a,pch
    movx @r0,a
    inc r0
    mov _spx, r0
    pop acc
    ljmp %1
}

replace {
    reti
}by{
    ri
}
replace {
    ret
} by {
    xch a,r1
    mov r0, _spx
   
    dec r0
    movx a,@r0
    push acc
    dec r0
    movx a,@r0
    push acc
    xch a,r1
    rrt
}

replace {
    rrt
} by {
    ret
}

replace {
    ri
} by {
    reti
}

replace {
    sjmp %1
} by {
    ljmp %1
}

replace {
    jz %1
} by {
    jnnz (pc+3)
    ljmp %1
}

replace {
    jnnz (pc+3)
    ljmp %5
} by {
    jz %5
} if labelInRange

replace {
    jnz %1
} by {
    jz (pc+3)
    ljmp %1
}

replace {
    jz (pc+3)
    ljmp %5
} by {
    jnz %5
} if labelInRange

replace {
    jnnz (pc+3)
} by {
    jnz (pc+3)
}

replace {
    jc %1
} by {
    jnnc (pc+3)
    ljmp %1
}

replace {
    jnnc (pc+3)
    ljmp %5
} by {
    jc %5
} if labelInRange

replace {
    jnc %1
} by {
    jc (pc+3)
    ljmp %1
}

replace {
    jc (pc+3)
    ljmp %5
} by {
    jnc %5
} if labelInRange

replace {
    jnnc (pc+3)
} by {
    jnc (pc+3)
}

replace {
    jb %1,%2
} by {
    jnnb %1,(pc+3)
    ljmp %2
}

replace {
    jnnb %1,(pc+3)
    ljmp %5
} by {
    jb %1,%5
} if labelInRange   

replace {
    jnb %1,%2
} by {
    jb %1,(pc+3)
    ljmp %2
}

replace {
    jb %1,(pc+3)
    ljmp %5
} by {
    jnb %1,%5
} if labelInRange

replace {
    jnnb %1,(pc+3)
} by {
    jnb %1,(pc+3)
}

replace {
    cjne a,%2,%3
} by {
    subb a,%2
    jz (pc+3)
    ljmp %3
}

replace {
    cjne %1,%2,%3
} by {
    mov a,%1
    subb a,%2
    jz (pc+3)
    ljmp %3
}

replace {
    ljmp %5
} by {
    sjmp %5
} if labelInRange

____________________________________________

nrk.c________________________________________
/******************************************************************************
*  Nano-RK, a real-time operating system for sensor networks.
*  Copyright (C) 2007, Real-Time and Multimedia Lab, Carnegie Mellon University
*  All rights reserved.
*
*  This is the Open Source Version of Nano-RK included as part of a Dual
*  Licensing Model. If you are unsure which license to use please refer to:
http://www.nanork.org/nano-RK/wiki/Licensing
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, version 2.0 of the License.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*  Contributing Authors (specific to this file):
*  Anthony Rowe
*  Zane Starr
*  Anand Eswaren
*******************************************************************************/

#include <stdio.h>
#include <nrk_includes.h>
#include <ulib.h>
#include <nrk.h>
#include <nrk_task.h>
#include <nrk_idle_task.h>
#include <nrk_defs.h>
#include <nrk_cpu.h>
#include <nrk_scheduler.h>
#include <nrk_error.h>
#include <nrk_events.h>
#include <nrk_stack_check.h>
#include <nrk_status.h>
#include <nrk_watchdog.h>
#include <nrk_reserve.h>
#include <nrk_cfg.h>
#include <nrk_stats.h>

#ifdef __SDCC__
void nrk_int_disable(void) {
  DISABLE_GLOBAL_INT();
}

void nrk_int_enable(void) {
  ENABLE_GLOBAL_INT();
}
#else

inline void nrk_int_disable(void) {
  DISABLE_GLOBAL_INT();
};

inline void nrk_int_enable(void) {
  ENABLE_GLOBAL_INT();
};
#endif

uint8_t nrk_task_init_cnt;

NRK_STK *nrk_kernel_stk_ptr;

NRK_TCB    nrk_task_TCB[NRK_MAX_TASKS];

NRK_STK    nrk_idle_task_stk[NRK_TASK_IDLE_STK_SIZE];  /* Idle task stack   */
#ifdef KERNEL_STK_ARRAY
    NRK_STK nrk_kernel_stk[NRK_KERNEL_STACKSIZE];
#endif

void nrk_halt()
{
nrk_int_disable();
while(1);
}

/**
*  nrk_init();
* *  - Init TCBlist - linked list of empty TCBs
*  - Init global variables
*  - Init event list
*  - Create idle task
*/
void nrk_init()
{
   
    uint8_t i;   
//    unsigned char *stkc;
   nrk_task_type IdleTask;
   printf("Start init: %u\r\n",nrk_task_init_cnt);
   nrk_wakeup_signal = nrk_signal_create();
   if(nrk_wakeup_signal==NRK_ERROR) nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,0);
   
   //if((volatile)TCCR1B!=0) nrk_kernel_error_add(NRK_STACK_OVERFLOW,0);
   if(_nrk_startup_ok()==0) nrk_kernel_error_add(NRK_BAD_STARTUP,0);
   #ifdef NRK_STARTUP_VOLTAGE_CHECK
       if(nrk_voltage_status()==0) nrk_kernel_error_add(NRK_LOW_VOLTAGE,0);
   #endif

   #ifdef NRK_REBOOT_ON_ERROR
   #ifndef NRK_WATCHDOG
   while(1)
       {
        nrk_kprintf( PSTR("KERNEL CONFIG CONFLICT:  NRK_REBOOT_ON_ERROR needs watchdog!\r\n") );
            for (i = 0; i < 100; i++)
                  nrk_spin_wait_us (1000);
       }
   #endif
   #endif

    #ifdef NRK_WATCHDOG
    if(nrk_watchdog_check()==NRK_ERROR)
    {
        nrk_watchdog_disable();
    nrk_kernel_error_add(NRK_WATCHDOG_ERROR,0);
    }
    nrk_watchdog_enable();
    #endif
 
    nrk_stack_pointer_init();
/*
    #ifdef KERNEL_STK_ARRAY
    stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1];
    nrk_kernel_stk[0]=STK_CANARY_VAL;
        nrk_kernel_stk_ptr = &nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1];
    #else
        stkc = NRK_KERNEL_STK_TOP-NRK_KERNEL_STACKSIZE;
        *stkc = STK_CANARY_VAL;
        stkc = NRK_KERNEL_STK_TOP;
    nrk_kernel_stk_ptr = NRK_KERNEL_STK_TOP;
    #endif
    *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8);
    *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF);
*/   

   // printf( "Init kernel_entry= %d %d\n",kernel_entry[1], kernel_entry[0] );

    printf("mid init: %u\r\n",nrk_task_init_cnt);
    nrk_cur_task_prio = 0;
    nrk_cur_task_TCB = NULL;
   
    nrk_high_ready_TCB = NULL;
    nrk_high_ready_prio = 0;

   #ifdef NRK_STATS_TRACKER
    nrk_stats_reset();
   #endif

    #ifdef NRK_MAX_RESERVES
    // Setup the reserve structures
    _nrk_reserve_init();
    #endif

    _nrk_resource_cnt = NRK_MAX_RESOURCE_CNT;

for(i=0;i<NRK_MAX_RESOURCE_CNT;i++)
{
    nrk_sem_list[i].count=-1;
    nrk_sem_list[i].value=-1;
    nrk_sem_list[i].resource_ceiling=-1;
    //nrk_resource_count[i]=-1;
    //nrk_resource_value[i]=-1;
    //nrk_resource_ceiling[i]=-1;
   
}       
    for (i= 0; i<NRK_MAX_TASKS; i++)
    {
        nrk_task_TCB[i].task_prio = TCB_EMPTY_PRIO;
        nrk_task_TCB[i].task_ID = -1;
        }
 
      
    // Setup a double linked list of Ready Tasks
    for (i=0;i<NRK_MAX_TASKS;i++)
    {
        _nrk_readyQ[i].Next    =    &_nrk_readyQ[i+1];
        _nrk_readyQ[i+1].Prev    =    &_nrk_readyQ[i];
    }
   
    _nrk_readyQ[0].Prev    =    NULL;
    _nrk_readyQ[NRK_MAX_TASKS].Next    =    NULL;
    _head_node = NULL;
    _free_node = &_nrk_readyQ[0];
   
   
   
        // SDCC can not do cast
    nrk_task_set_entry_function( &IdleTask,(void *) nrk_idle_task);
    nrk_task_set_stk( &IdleTask, nrk_idle_task_stk, NRK_TASK_IDLE_STK_SIZE);
    nrk_idle_task_stk[0]=STK_CANARY_VAL;   
    //IdleTask.task_ID = NRK_IDLE_TASK_ID;
    IdleTask.prio = 0;
    IdleTask.offset.secs = 0;
    IdleTask.offset.nano_secs = 0;
    IdleTask.FirstActivation = TRUE;
    IdleTask.Type = IDLE_TASK;
    IdleTask.SchType = PREEMPTIVE;
    nrk_activate_task(&IdleTask);
   
}

uint8_t*  stkptr;

void nrk_start (void)
{
    int8_t task_ID;
    uint8_t i,j;
//    NRK_STK *x;
//    unsigned char *stkc;
    NRK_TCB    *new_nrk_TCB;

    /*
        - Get highest priority task from rdy list
        - set cur prio and start the task
    */
    // Check to make sure all tasks unique

//    dump_stack_info();
    task_ID = nrk_get_high_ready_task_ID();   
    nrk_high_ready_prio = nrk_task_TCB[task_ID].task_prio;
    nrk_high_ready_TCB = nrk_cur_task_TCB = &nrk_task_TCB[task_ID]; 
    //new_nrk_high_ready_TCB =  nrk_task_TCB[task_ID];
    //printf("new_nrk_high_ready_TCB %x",new_nrk_high_ready_TCB);
    printf("Task %u, Ready= %u, Cur= %u,TCB= %x\r\n",task_ID,nrk_high_ready_prio,nrk_cur_task_prio,(uint16_t)nrk_high_ready_TCB);   
    nrk_cur_task_prio = nrk_high_ready_prio;

    nrk_print_readyQ();
//    nrk_stack_pointer_restore();

    /*
    #ifdef KERNEL_STK_ARRAY
         stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1];
    #else
        stkc = NRK_KERNEL_STK_TOP;
    #endif
    *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8);
    *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF);
   
    //TODO: this way on msp
    // *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF);
    // *stkc = (uint16_t)((uint16_t)_nrk_timer_tick>>8);
*/
//    nrk_target_start();

_asm
    mov _stkptr,sp
_endasm;

    nrk_stack_pointer_init();
printf("1st %X %X\r\n",(uint16_t) nrk_high_ready_TCB,(*((xdata uint16_t*) nrk_high_ready_TCB)));
nrk_kprintf("XStack\r\n");
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)+2))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)+1))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-1))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-2))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-3))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-4))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-5))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-6))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-7))));
printf("%X\r\n",(*((xdata uint8_t*)(*((xdata uint16_t*) nrk_high_ready_TCB)-8))));
nrk_kprintf("Stack\r\n");
printf("%X\r\n",(*(stkptr+2)));
printf("%X\r\n",(*(stkptr+1)));
printf("%X\r\n",(*(stkptr)));
printf("%X\r\n",(*(stkptr-1)));
printf("%X\r\n",(*(stkptr-2)));
printf("%X\r\n",(*(stkptr-3)));
printf("%X\r\n",(*(stkptr-4)));
printf("%X\r\n",(*(stkptr-5)));
printf("%X\r\n",(*(stkptr-6)));
printf("%X\r\n",(*(stkptr-7)));
printf("%X\r\n",(*(stkptr-8)));
    nrk_target_start();
    nrk_start_high_ready_task();

    // you should never get here   
    while(1);
}

void nrk_start_high_ready_task() __naked
{
    _asm
        mov dptr,#_nrk_high_ready_TCB
       
        movx a,@dptr
        mov b,a
        inc dptr
        movx a,@dptr
        mov dph,a
        mov a,b
        mov dpl,a
       
        movx a, @dptr
        mov _spx,a
        inc dptr
        movx a, @dptr
        mov __XPAGE,a
    
        mov a, _spx
        mov r0,a
        subb a,#0xD
        mov _spx,a
       
        ;Get the tasks PC and put it on the local stack
        dec r0
        movx a,@r0
        push acc
        dec r0
        movx a,@r0
        push acc
       
        dec r0
        movx a,@r0
        mov psw,a
        dec r0
        movx a,@r0
        mov r1,a
        dec r0
        movx a,@r0
        ;get r0 and put it on the local stack
        push acc
        dec r0
        movx a,@r0
        mov r7,a
        dec r0
        movx a,@r0
        mov r6,a
        dec r0
        movx a,@r0
        mov r5,a
        dec r0
        movx a,@r0
        mov r4,a
        dec r0
        movx a,@r0
        mov r3,a
        dec r0
        movx a,@r0
        mov r2,a
        dec r0
        movx a,@r0
        mov dph,a
        dec r0
        movx a,@r0
        mov dpl,a
        dec r0
        movx a,@r0
        mov b,a
        dec r0
        movx a,@r0
       
        pop ar0   
       
        reti
    _endasm;
}

int8_t nrk_TCB_init (nrk_task_type *Task, NRK_STK *ptos, NRK_STK *pbos, uint16_t stk_size, void *pext, uint16_t opt)
{
    //  Already in critical section so no needenter critical section
    if(Task->Type!=IDLE_TASK)
        Task->task_ID=nrk_task_init_cnt;
    else Task->task_ID=NRK_IDLE_TASK_ID;

    if(nrk_task_init_cnt>=NRK_MAX_TASKS) nrk_kernel_error_add(NRK_EXTRA_TASK,0);
    if(Task->Type!=IDLE_TASK) nrk_task_init_cnt++;
    if(nrk_task_init_cnt==NRK_IDLE_TASK_ID) nrk_task_init_cnt++;
    //initialize member of TCB structure
    nrk_task_TCB[Task->task_ID].OSTaskStkPtr = ptos;
    nrk_task_TCB[Task->task_ID].task_prio = Task->prio;
    nrk_task_TCB[Task->task_ID].task_state = SUSPENDED;
   
    nrk_task_TCB[Task->task_ID].task_ID = Task->task_ID;
    nrk_task_TCB[Task->task_ID].suspend_flag = 0;
    nrk_task_TCB[Task->task_ID].period= _nrk_time_to_ticks( (void *)Task->period );  // sdcc can not do cast
    nrk_task_TCB[Task->task_ID].next_wakeup= _nrk_time_to_ticks( (void*)Task->offset); // sdcc can not do cast
    nrk_task_TCB[Task->task_ID].next_period= nrk_task_TCB[Task->task_ID].period+nrk_task_TCB[Task->task_ID].next_wakeup;
    nrk_task_TCB[Task->task_ID].cpu_reserve= _nrk_time_to_ticks((void *)Task->cpu_reserve); // sdcc can not do cast
    nrk_task_TCB[Task->task_ID].cpu_remaining = nrk_task_TCB[Task->task_ID].cpu_reserve;
    nrk_task_TCB[Task->task_ID].num_periods = 1;
    nrk_task_TCB[Task->task_ID].OSTCBStkBottom = pbos;
    nrk_task_TCB[Task->task_ID].errno= NRK_OK;
   
    return NRK_OK;
}

/*
* _nrk_timer_tick()
*
* This function is called by the interrupt timer0.
* It calls the scheduler.
*/
void _nrk_timer_tick(void)
{
    // want to do something before the scheduler gets called?
    // Go ahead and put it here...
    _nrk_scheduler();
      return;
}

uint16_t nrk_version (void)
{
    return (NRK_VERSION);
}

___________________________________________________________