|
|
View previous topic :: View next topic |
Author |
Message |
laser_scientist
Joined: 26 Jun 2013 Posts: 7
|
Computed branch |
Posted: Sun Dec 21, 2014 4:11 pm |
|
|
Hello,
I am using a PIC24EP512GP806, trying to do an efficient computed branch using the BRA Wd instruction via some assembly code (below). However, CCS chokes on this instruction, giving an "expecting an opcode mnemonic" error. This is a valid opcode for this device, and CCS help even has this instruction in its list for inline assembly. I'm using version 5.018 of the compiler. Does anyone know why I might be getting this error? (Note that the actual application has many more entries in the jump table -- this is just a test case)
Thanks,
Dan
Code: |
#asm
MOV i,w0
SL w0,#2,w0
ADD i,w0
BRA w0 ; <- doesn't like this
PUSH tvL
POP 906
PUSH tvH
POP 910
GOTO theend
PUSH tvL
POP 91A
PUSH tvH
POP 924
theend:
NOP
#endasm
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Dec 21, 2014 7:52 pm |
|
|
I don't have a real answer for you as it 'looks OK...' but the Switch statement is pretty clever. Maybe cut a small example then dump the listing to see how CCS does it ?
just an idea...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Dec 22, 2014 3:39 am |
|
|
Get the Microchip assembly reference
(70157F.PDF).
Look at page128 (the page covering the 'computed branch' instruction).
At the top, there is a table of processors that support this. Note that the PIC24E, is _not_ ticked.....
Remember also, the address is relative to the PC. Much easier for a table based approach to use an absolute address. The easy way to do this, is to calculate the address required, push it onto the stack, and then execute a return. |
|
|
laser_scientist
Joined: 26 Jun 2013 Posts: 7
|
|
Posted: Mon Dec 22, 2014 7:23 am |
|
|
Ttelmah, you're absolutely right about the reference. I was going by the device datasheet (70616g.pdf), where on page 488, they do have the BRA Wn instruction listed. I'm guessing that the assembly reference is correct though. And thanks for the alternative suggestion. That's what I'll do.
temtronic, thanks for the suggestion. That's actually how I decided to go with a table approach. From the code that CCS generates, I could see that they were effectively just doing a sequential if-then:
Code: |
switch (i)
00230: MOV 1030,W0
00232: XOR #0,W0
00234: BRA Z,254
00236: XOR #1,W0
00238: BRA Z,260
0023A: XOR #3,W0
0023C: BRA Z,26C
0023E: XOR #1,W0
00240: BRA Z,278
00242: XOR #7,W0
00244: BRA Z,284
00246: XOR #1,W0
00248: BRA Z,290
0024A: XOR #3,W0
0024C: BRA Z,29C
0024E: XOR #1,W0
00250: BRA Z,2A8
00252: BRA 2B4
{
case 0: _OC1R = tvL;
00254: PUSH 102C
00256: POP 906
_OC2R = tvH;
00258: PUSH 102A
0025A: POP 910
break;
0025C: GOTO 2B4
case 1: _OC3R = tvL;
...
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Mon Dec 22, 2014 7:40 am |
|
|
re: switch()...
it's been said that CCS changes the way it code switch() based on the number of entries. Maybe after 16(?) it happens??
Might be worth a coffee to code and see what they do !!
cheers
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Dec 22, 2014 8:53 am |
|
|
I think it is very high on the PIC24.
Reason is that 'straight through' path on these chips only takes one instruction time, so it is quicker for a very large number of tests to use this approach.
A quick play, shows it refusing to switch, even well past the point where switching would be more economical....
However a simple array of function names works. So something like:
Code: |
//four void functions fn1...fn4 - or typed if you want them to return something
typedef void (*fnptr_t)(void);
fnptr_t funcs[4] = {fn1,fn2,fn3,fn4};
//and call with:
(*funcs[n)();
//where 'n' is the function required.
|
It codes this by calculating the location in the table as required, and then executing:
Probably the easiest way. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|