Jump to content
 
  • 0

Mixing C and ASM


Orunmila

Question

  • Member

I have a fairly general question for you all. I keep on running into situations where I need to mix C and ASM. Sometimes this works out easily by just using some asm("") instructions in the middle of my function, but sometimes I really feel like I could benefit from writing a function in ASM and calling it from C.

I think my best example of this is the implementation of cryptographic functions such as AES or SHA. For these I see sometimes a 2x or even 3x speed improvement over what the compiler produces and I need to use these from more than one place so I really need a C function I can call to do these but I reallly need to implement it in ASM.

Whenever I ask about mixing C and ASM I am told just not to do it, but it still seems to me that there are a lot of situations where this really is the best way to go?

I recall a converstation with @holdmybeer where he needed very precise timing and the optimizer would always change the timing depending how the banks ended up being laid out (adding or removing bank switches), where implementing a function in ASM also seemed to be the solution.

So I would like to get some opinions on this, do you guys agree? Any thoughts on this?

PS. We recently had a related discussion about calculating parity as another example.

 

Link to comment
Share on other sites

6 answers to this question

Recommended Posts

One strength of 8 bit devices is the precise timing. Unlike 32 bit machines, you simply don't have to deal with such things like

- a bus matrix 

- long pipelines 

- clock domain crossing

- caching

 

A colleague of mine calls 8 bit devices "honest souls". You can calculate the exact behavior by simply counting instruction cycles. 

 

I had three situations where I needed to mix ASM and C. I recommend to use an encapsulated ASM module, inline ASM gets messy quickly. 

- for a motor to have exact commutation times after a BEMF event

- for a capacity measurement with an AD input

- to sample two AD channels and do a MAC operation for an enery meter

 

All three solutions needed fastest execution and exact timing, independent from the compiler. This also had the advantage that I had to do testing of these routines only once. For example I didn't have to check for things like motor efficiency under load every time I released an update.

There is a pitfall if you use ASM functions in interrupts. Because the compiler loses track of which registers to backup, XC8 simply copies all registers. But there was a way to skip automatic context saving. I'll have to look that up tomorrow. 

 

Oh and did they fix the clumsy switch case implementation in XC8 finally? I noticed that they use an XOR sequence to branch to the cases. That means the higher the case number, the higher the latency to execute the code in the case. Another reason for ASM.

Link to comment
Share on other sites

  • Member
7 hours ago, holdmybeer said:

Oh and did they fix the clumsy switch case implementation in XC8 finally? I noticed that they use an XOR sequence to branch to the cases. That means the higher the case number, the higher the latency to execute the code in the case. Another reason for ASM.

XC8 has several different ways of implementing switch case.

It analyses how many conditions there are, and what pattern they follow before deciding which one to use.

When you read the LST file, it tells you which type it has decided to use.

Link to comment
Share on other sites

  • Member
17 hours ago, ric said:

XC8 has several different ways of implementing switch case.

It analyses how many conditions there are, and what pattern they follow before deciding which one to use.

When you read the LST file, it tells you which type it has decided to use.

Yes and there used to be some "unofficial" pragmas you could use to force it to a specific way of doing this, not sure - with the XC8 2.0 changes they may not be valid any more, but you were able to choose strategies using these. Seems like PIC18 was the stepchild ...

This is what it was like in the User Guide

image.png

 

Link to comment
Share on other sites

  • Member

Being in the User's guide does not always means that it still works :), it is possible that it now only works when you select the option C90 and that this caveat is not well documented ... I don't know.

I know with C99 they replaced the front-end with the CLANG based front-end, and kept the old back-end, not sure if this change affects the way the switch is implemented, it could be done in the templates or in the ASN step I guess, so it could go either way.

I guess the best option is to try one and check the list file to see what happens ...

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

 


×
×
  • Create New...