assembly syntax

Beta Testing discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
peterverkaik
Posts: 174
Joined: 31 Aug 2009 22:44

assembly syntax

#1 Post by peterverkaik » 09 Dec 2009 21:09

I tried migrating some microchip C30 functions that use asm
and it fails utterly. The mnenomics are not recognized.

Code: Select all

void T4Interrupt(void) {
/*
  register vpBank *slot asm("w5");
  slot = vpPtr;                        //this value is used in all statefunctions
  (slot->statePtr)();                  //call statefunction for slot
  vpPtr = (vpBank *)slot->nextVP;      //next vp
  IFS1bits.T4IF = 0;                   //clear T4 interruptflag 
*/
// 002C2  F80036     push.w 0x0036
  asm {
    mov.d w4,[w15++];             //save w4,w5
    mov.w _vpPtr,w5;              //slot = vpPtr; //this value is used in all statefunctions
    mov.w [w5+16],w0;             //(slot->statePtr)(); //call statefunction for slot
    call w0;
    mov.w [w5+18],w0;             //vpPtr = (vpBank *)slot->nextVP; //next vp
    mov.w w0,_vpPtr;
    bclr.b IFS1bits,#3;          //IFS1bits.T4IF = 0; //clear T4 interruptflag
    mov.d [--w15],w4;             //restore w4,w5
  }
// 002D8  F90036     pop.w 0x0036
}
Also, the online help on asm shows instructions like

Code: Select all

unsigned myvar;
void main() {
  asm {
    MOVLW 10  // just a test
    MOVLW _myvar
    MOVLW 0   // just a test
    MOVLW _myvar+1
  }
}
which is syntax for regular PIC, not dsPIC!

regards peter

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

Re: assembly syntax

#2 Post by milan » 10 Dec 2009 09:34

Hi,
peterverkaik wrote:The mnenomics are not recognized.
probably the variables are not recognized.

We would like to investigate this.
Please make your project small (if possible), zip the project folder
and send it to milan(att)mikroe.com
SmartADAPT2 rules !

peterverkaik
Posts: 174
Joined: 31 Aug 2009 22:44

#3 Post by peterverkaik » 10 Dec 2009 14:05

I disabled the asm statement and enabled the C code.
That compiles and generates for T4Interrupt

Code: Select all

_T4Interrupt:
0x02C4        0xFA0002          LNK        #2
0x02C6        0xF80036          PUSH        RCOUNT
0x02C8        0x781F80          PUSH        W0
0x02CA        0x200020          MOV        #2, W0
0x02CC        0x09000C          REPEAT        #12
0x02CE        0x781FB0          PUSH        [W0++]
;js2.c,130 ::                 void T4Interrupt(void) org 0x003E { //On C30 this autogenerates push.s and pop.s statements)
;js2.c,133 ::                 slot = vpPtr;                        //this value is used in all statefunctions
0x02D0        0x804770          MOV        _vpPtr, W0
0x02D2        0x980700          MOV        W0, [W14+0]
;js2.c,134 ::                 (slot->statePtr)();                  //call statefunction for slot
0x02D4        0x804770          MOV        _vpPtr, W0
0x02D6        0x400072          ADD        W0, #18, W0
0x02D8        0x780010          MOV        [W0], W0
0x02DA        0x010000          CALL        W0
;js2.c,135 ::                 vpPtr = (vpBank *)slot->nextVP;      //next vp
0x02DC        0x90000E          MOV        [W14+0], W0
0x02DE        0x400074          ADD        W0, #20, W0
0x02E0        0x780010          MOV        [W0], W0
0x02E2        0x884770          MOV        W0, _vpPtr
;js2.c,136 ::                 IFS1bits.T4IF = 0;                   //clear T4 interruptflag
0x02E4        0xA96087          BCLR        IFS1bits, #11
;js2.c,152 ::                 }
L_end_T4Interrupt:
0x02E6        0x2001A0          MOV        #26, W0
0x02E8        0x09000C          REPEAT        #12
0x02EA        0x78104F          POP        [W0--]
0x02EC        0x78004F          POP        W0
0x02EE        0xF90036          POP        RCOUNT
0x02F0        0xFA8000          ULNK
0x02F2        0x064000          RETFIE
; end of _T4Interrupt
So the variable name _vpPtr is correct.
mov.w _vpPtr,w0 is not recognized but mov _vpPtr,w0 is.
Same for mov.w w0,_vpPtr
Totally not recognized is call w0, or call wreg, or call wreg0
but the listing uses call w0

Another problem is the autosave and restore upon function entry
and exit. For this particular use these autosavings must be disabled
because they consume too much cycles.
C30 uses an attribute to turn the autosave off. I'd like MikroE C
to allow that too.

I will zip the folder and mail it to you.

regards peter

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#4 Post by milan » 10 Dec 2009 15:11

Hi,

let's solve things one by one

1) mov.w _vpPtr, w5

According to dspic30f programmer's reference manual :
http://ww1.microchip.com/downloads/en/D ... f#page=219
there are four MOV instruction of interest :
- MOV{.B} f {, WREG}
- MOV{.B} WREG, f
- MOV f, Wnd
- MOV Wns, f

I think that you are trying to use :
- MOV{.B} f, Wnd
That doesn't exist.

Correct me if I'm wrong I think you should write :
mov _vpPtr, w5

2) Call W0 - I will grab this problem after I get your feedback about 1) and 3) and see if that two problems are solved.
3) interrupt prologue and epilogue can be turned-off

use linker directive:
#pragma disablecontexsaving

This was omitted in help, it will be on page "Interrupts" for official release.
Sorry for this error :(
SmartADAPT2 rules !

peterverkaik
Posts: 174
Joined: 31 Aug 2009 22:44

#5 Post by peterverkaik » 10 Dec 2009 16:00

Hi Milan,

1. According to ASM30 userguide, the .w is optional so
mov _vpPtr,w0 is identical to mov.w _vpPtr,w0
It is not mentioned for mov f,wnd but the .w is accepted
by the microchip assembler. Would be nice if MikroE assembler
accepts it too. Omitting the .w resolves the error.

3. #pragma disablecontexsaving did the trick.

I now only get the error
Undeclared identifier w0 in expression
(call w0)

Code: Select all

//-----------------------------------------------------------------------------
// Virtual Peripheral Scheduler
//-----------------------------------------------------------------------------
#pragma disablecontexsaving

//This routine is called every 1.24 usec (49 cycles @79MHz). It provides 7 timeslots.
//These run at priority 7 to ensure deterministic behaviour for all states.
//Cycles is 16 + statefunction cycles
//Only registers w0-w5 must be used by vp driver code because other w registers are not saved.
//The interrupt frequency for each timeslot equals 1/(7*1.24) MHz = 115.2 kHz
void T4Interrupt(void) org 0x003E { //On C30 this autogenerates push.s and pop.s statements)
/*
  register vpBank *slot; // asm("w5");
  slot = vpPtr;                        //this value is used in all statefunctions
  (slot->statePtr)();                  //call statefunction for slot
  vpPtr = (vpBank *)slot->nextVP;      //next vp
  IFS1bits.T4IF = 0;                   //clear T4 interruptflag 
*/
  asm {
    push.s              ; //save w0-w3,status
    mov.d w4,[w15++]    ; //save w4,w5
    mov _vpPtr,w5       ; //slot = vpPtr; //this value is used in all statefunctions
    mov.w [w5+16],w0    ; //(slot->statePtr)(); //call statefunction for slot
    call w0             ;
    mov.w [w5+18],w0    ; //vpPtr = (vpBank *)slot->nextVP; //next vp
    mov w0,_vpPtr       ;
    bclr.b IFS1bits,#3  ; //IFS1bits.T4IF = 0; //clear T4 interruptflag
    mov.d [--w15],w4    ; //restore w4,w5
    pop.s               ; //restore w0-w3,status
  }
}

regards peter

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#6 Post by milan » 10 Dec 2009 17:02

Hi,
peterverkaik wrote: 1. According to ASM30 userguide, the .w is optional so
mov _vpPtr,w0 is identical to mov.w _vpPtr,w0
It is not mentioned for mov f,wnd but the .w is accepted
by the microchip assembler. Would be nice if MikroE assembler
accepts it too. Omitting the .w resolves the error.
that is non-standard addition that is not covered by
dspic30f programmer's reference manual.

We are using this manual to follow the standard.

IMHO if there are several dsPIC compilers - they should all follow the standard.
So in case of porting code - there should be no problems.
SmartADAPT2 rules !

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#7 Post by janni » 10 Dec 2009 17:06

peterverkaik wrote:Totally not recognized is call w0, or call wreg, or call wreg0
but the listing uses call w0
That's probably the same kind of limitation that was introduced in other PRO versions. All calls and jumps in user assembly block are limited to labels within single routine. I guess that for 16-bit processors this limitation means also blocking indirect and computed calls & jumps.
In PIC compilers, exception to the rule is a name of another routine (and numerical address, which is somewhat inconsistent with the general limitation) - in dsPIC compilers even calls of other routines from assembly seem to be blocked.

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#8 Post by milan » 10 Dec 2009 17:26

Hi,
peterverkaik wrote: I now only get the error
Undeclared identifier w0 in expression
(call w0)
this is solved now :)
SmartADAPT2 rules !

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#9 Post by janni » 12 Dec 2009 14:34

Yep :) . indirect calls & jumps are not intentionally blocked and, contrary to what I stated before, other functions may be called (directly, using internal function's name) from assembly. While checking it, I've forgotten about another introduced limitation - only functions preceeding the call in code may be called now. Direct jumps and calls to labels are still limited to a function the labels were declared in.

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#10 Post by milan » 14 Dec 2009 09:30

Hi,
janni wrote:only functions preceeding the call in code may be called now.
Can you post small example to explain this problem
SmartADAPT2 rules !

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#11 Post by janni » 14 Dec 2009 12:43

Hi Milan,

Naturally, here's the code (I actually tested mP PRO for dsPIC):

Code: Select all

program Test6;

procedure  dummy();
 begin
  nop;
  asm call _dummy1 end;  // 'Identifier "_dummy1" was not declared
 end;

procedure  dummy1();
 begin
  nop;
  asm call _dummy end;  // works
 end;

begin
  dummy;
  dummy1;

end.
Apparently, rules from the high-level language were extended to assembly (also the other one about labels visibility).

User avatar
srdjan
mikroElektronika team
Posts: 1552
Joined: 28 Dec 2005 12:47
Location: Serbia

#12 Post by srdjan » 16 Dec 2009 16:04

Hi,
janni wrote:Hi Milan,

Naturally, here's the code (I actually tested mP PRO for dsPIC):

Code: Select all

program Test6;

procedure  dummy();
 begin
  nop;
  asm call _dummy1 end;  // 'Identifier "_dummy1" was not declared
 end;

procedure  dummy1();
 begin
  nop;
  asm call _dummy end;  // works
 end;

begin
  dummy;
  dummy1;

end.
Apparently, rules from the high-level language were extended to assembly (also the other one about labels visibility).
You should just ad forward declaration for procedure dummy1() before
you use it in procedure dummy().

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#13 Post by janni » 16 Dec 2009 16:20

Hi Srdjan,

I know it'll work with the forward declaration in the final release :wink: . Anyway, it does not change the fact that rules from the high-level language were extended to assembly thus introducing limitations one has to be aware of while porting older code to the PRO version.

User avatar
srdjan
mikroElektronika team
Posts: 1552
Joined: 28 Dec 2005 12:47
Location: Serbia

#14 Post by srdjan » 16 Dec 2009 16:45

janni wrote:Hi Srdjan,

I know it'll work with the forward declaration in the final release :wink: . Anyway, it does not change the fact that rules from the high-level language were extended to assembly thus introducing limitations one has to be aware of while porting older code to the PRO version.
That is correct.
In assembly block you can use jumps and calls to 'identifier' with the following restrictions:
1. 'identifier' can be routine name
2. 'identifier' can be any label defined within the function containing the asm block

Thus, you can not jump to a label which belongs to another function.

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 Beta Testing”