inline assembly for "c" Simple Tools Toggle function translation
Shawna
Posts: 508
I am trying to convert some basic C code to inline assembly. I am using simpleIDE for my C programming. I realize that there are some programs that will do this but I have not found the courage to leave simpleIDE yet or the simple tools library.
I am trying to convert the simpletools toggle function into inline assembly. This should be a trivial task but I am having problems with it.
The C toggle code is.
I believe I have the OUTA and DIRA working but I can't figure out the Shift Left portion. I am ditching the return portion.
Here is one of my attempts at the shift left portion.
Here are the values for the mask variable at the last printi command based upon initial pin values.
pin = 0 mask = 0
pin = 1 mask = 2
pin = 2 mask = 8
pin = 3 mask = 24
pin = 4 mask = 64
I am not sure what i am doing wrong.
My only references for this are the propeller manual and this link.
https://sites.google.com/site/propellergcc/documentation/tutorials/inline-asm-basics
Thanks
Shawn A
I am trying to convert the simpletools toggle function into inline assembly. This should be a trivial task but I am having problems with it.
The C toggle code is.
unsigned int toggle(int pin) // toggle function definition { int mask = 1 << pin; OUTA ^= mask; DIRA |= mask; return (OUTA >> pin) & 1; }
I believe I have the OUTA and DIRA working but I can't figure out the Shift Left portion. I am ditching the return portion.
Here is one of my attempts at the shift left portion.
#include "simpletools.h" int main() { int mask = 1; int pin = 3; printi("mask = %d ", mask); __asm__ volatile ( "shl %[mask],%[pin]\n\t" :/*outputs (+inputs)*/ [mask] "=r" (mask) :/*inputs */ [pin] "r" (pin) ); printi("mask = %d ", mask); }
Here are the values for the mask variable at the last printi command based upon initial pin values.
pin = 0 mask = 0
pin = 1 mask = 2
pin = 2 mask = 8
pin = 3 mask = 24
pin = 4 mask = 64
I am not sure what i am doing wrong.
My only references for this are the propeller manual and this link.
https://sites.google.com/site/propellergcc/documentation/tutorials/inline-asm-basics
Thanks
Shawn A
Comments
In the project manager window you can right click on your file and in the drop down box is show assemble. This is a good way to see the generated assembly code although very ugly to read.
Here is my attempt at your code:
You will notice that r0-r15 are general purpose registers that are used to pass values back and forth and are used for calculations.
So in standard C code they use the stack and push these values on the stack and these values are then accessed right off the stack. Not the case here. If you pass 5 values they will be passed in r0 - r4 and then the returned value will be in r0.
Mike
Your example works to toggle a pin. I had to modify the return portion of your code, it was always returning a 1. I know I said I was going to ditch that part but......... anyways.
To make the function return the right value I modified these 2 lines.
Original
Modified
The pin number will not change, but the OUTA Reg will change. So we want to MOV OUTA into Mask, SHR Mask with Pin and then AND Mask with 1. And finally Return Mask to show status of the pin output.
Edited 2-2-20
I have tried this but it is extremely hard to understand.
I noticed that you added an underscore to the first portion of your variables during there declaration in the Assembly code. Is this necessary?
I kind of like it, it makes the Assembly a little easier to read.
Shawn A
By this, what I really mean is: don't use values 0-31 or 1-32 to address pins, but instead, just use the actual bit masks. Define an enum or use a bunch of #define's and set the values to the appropriate bit masks. Then each of your pin functions are one assembly instruction each.