Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 21:48 16 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMBasic:CFunctions:NOPs

Author Message
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 01:05pm 31 Oct 2014
Copy link to clipboard 
Print this post

In the course of developing a CFunction, @Plasma discovered an issue with the way multiple inline assembler NOP statements are handled by the MPLabX disassembler and CFuncGen. I have updated the MMBasic CFunctions tutorial which will be republished soon, but in the meantime here is the relevant section reproduced below.

Assembler NOPs
It is very common to use NOPs in timing/delay loops. XC32/gcc is very good at spotting 'useless' NOPs and will often eliminate them completely from the emitted machine code. In addition, there is a problem when several NOPs in sequence are inserted inline into the 'C' code, although xc32/gcc/xc32-as emits the correct machine code, the disassembly output which is used by CFuncGen omits these NOPs. Quite why is a complete mystery.

To get round this problem, an alternative to NOP which does not suffer from these problems must be used. After some trial and error, a good alternative to NOP is ori $0,$0,0 or li $0,0 instruction, which is load Register 0 with value 0, Register 0 is MIPS register which always contains zero . See an example usage below



asm volatile ("ori $0,$0,0\n\t"
"ori $0,$0,0\n\t"
"ori $0,$0,0\n\t"
"ori $0,$0,0\n\t"
"ori $0,$0,0\n\t"
);
[/CODE}

And the disassembly output in CFuncGen is

[CODE}
9d0000fc: 34000000 li zero,0x0
9d000100: 34000000 li zero,0x0
9d000104: 34000000 li zero,0x0
9d000108: 34000000 li zero,0x0
9d00010c: 34000000 li zero,0x0



The volatile prefix should prevent the optimizer from eliminating this code.
So in sum instead of writing nop, write li $0,0; use a #define to make it easier, eg #define NOP li $0,0


This code seems to work. Any feedback/suggestions for improvement would be most welcome.

Peter

The only Konstant is Change
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 01:25am 01 Nov 2014
Copy link to clipboard 
Print this post

Hi,

this i a good solution .

thx
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1139
Posted: 07:13am 01 Nov 2014
Copy link to clipboard 
Print this post

Hi Peter,

I'm not coding CFunctions yet, but I would expect NOP are much faster than that "li $0,0". I think you can more fine tune do with NOPs.I don't know if that will be a problen in the future. Just a idea.

But you did of course a amazing good job, because you care about CFunctions (and how to handle) and the whole rest of computers! ;)
For me your tools and your manual are the key to use CFunctions and to become popular! (seriously!)

Thanks a lot!

Michael
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:49am 01 Nov 2014
Copy link to clipboard 
Print this post

In MIPS/RISC processors, just about every one of the simple instructions take one cycle - conditiional/branch/jump instructions are a bit more complicated timing wise. NOP in MIPS, is in fact SLL $0,$0,0, ie there is not actually a NOP instruction in MIPS.

For delay loops, people should be using Geoff's CFunction Delay


// delay for a certain number of core timer ticks
//(one tick every 50nS at 40MHz CPU speed, 100nS at 20MHz, etc)
void Delay(unsigned int ticks) {
unsigned int current_ticks = 0;
// set the core timer to zero
asm volatile("mtc0 %0, $9": "+r"(current_ticks));
do {
// get the core timer ticks
asm volatile("mfc0 %0, $9" : "=r"(current_ticks));
} while(current_ticks < ticks);
}




'C:\CFunctions\Tutorial_4_CFunctionLib.X\dist\default\produc tion\Delay.bas

'
'Delay 2014-10-20 22:40:46 CFuncGen Ver 1.0.16 by user=Peter
'
CFunction Delay
00000000
00001021 40824800 40024800 0044102b 1440fffd 00000000 03e00008 00000000
End CFunction


which generates accurate and precise delays. Do/While with NOPs is what we all used to use pre PIC32, but Geoff's function is much, much better.

Thanks Michael for the encouraging comments.

Peter
The only Konstant is Change
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1139
Posted: 12:46pm 01 Nov 2014
Copy link to clipboard 
Print this post

Hi Peter,

this is what happens when you only Z80, 6502 and 8088 knows ... ;)
Sorry! I did not want to be cheeky! Thanks for the clarifying and this stuff to learn. I think many here may benefit.

Take care!

Michael
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 01:24pm 01 Nov 2014
Copy link to clipboard 
Print this post

Hi Michael

No offence taken !

I don't know much more, just learn/know what I need to, in order to get something done. Vorsprung durch Fehler ?

Hopefully you will be writing CFunctions before long !

Peter
The only Konstant is Change
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024