Probably another misunderstanding on my part..
I'm continuing on with my project and am hitting some difficulty again. I am using inline assembly since I am short on the number of cycles available and the compiler isn't generating tight enough code. That's OK though I can work in assembly.
I have a bit of code that is supposed to work like a serial port running at about 1.8 MHz. Here is the assembly that I am giving it:
The compiled version of this looks like this with what the code should be in comments to its right:
For some reason, it is using r7 as both temp3 and outLong, which doesn't do what I want. Is there a way to force it to honor the difference between these variables? I tried sticking in volatile after __asm__ as suggested by this page https://sites.google.com/site/propellergcc/documentation/tutorials/inline-asm-basics but that didn't do the trick.
Any ideas?
I have a bit of code that is supposed to work like a serial port running at about 1.8 MHz. Here is the assembly that I am giving it:
__asm__ volatile(
// a bunch of other code here but I am just showing the last bit for the sake of simplicity
// It is pretty much a bunch of repetitions of the snippet shown below.
"waitcnt %[temp1],%[waitDelay]\n\t" // bit 7
"mov %[temp3],INA\n\t"
"and %[temp3],%[theBit]\n\t" // clear everything but the bit that I am looking at
"shr %[outLong],#1\n\t"
"add %[outLong],%[temp3]\n\t"
: //outputs
[outLong] "=r" (outLong)
: //inputs
[temp1] "r" (temp1),
[theBit] "r" (theBit),
[LED] "r" (LED),
[waitDelay] "r" (waitDelay),
[zero] "r" (zero),
[temp3] "r" (temp3)
);
The compiled version of this looks like this with what the code should be in comments to its right:
69 00dc 0000BCF8 waitcnt r6,r2 // waitcnt temp1,waitDelay 70 00e0 0000BCA0 mov r7,INA // mov temp3,INA 71 00e4 0000BC60 and r7,r5 // and temp3,theBit 72 00e8 0100FC28 shr r7,#1 // shr outLong,#1 73 00ec 0000BC80 add r7,r7 // add outLong,temp3
For some reason, it is using r7 as both temp3 and outLong, which doesn't do what I want. Is there a way to force it to honor the difference between these variables? I tried sticking in volatile after __asm__ as suggested by this page https://sites.google.com/site/propellergcc/documentation/tutorials/inline-asm-basics but that didn't do the trick.
Any ideas?

Comments
For those of you who might be reading this in the future, I changed:
[outLong] "=r" (outLong)
to
[outLong] "&=r" (outLong)
Now, I need to dive into the documentation to really understand why this did the trick.
//------------------------------------------------------------------------------------------------------------------------------- volatile int readButtons() {// top button takes highest priority if multiple buttons are being pushed if(INA & (1<<6) == (1<<6)) return 1; if(INA & (1<<7) == (1<<7)) return 2; if(INA & (1<<8) == (1<<8)) return 3; return 0; }Here is the assembly code that is generated:
149:encoderDevice02.c **** volatile int readButtons() 150:encoderDevice02.c **** {// top button takes highest priority if multiple buttons are being pushed 7 .loc 1 150 0 8 0000 031E lpushm #16+14 9 .LCFI0 10 0002 F2101CA0 mov r14, sp 11 .LCFI1 151:encoderDevice02.c **** if(INA & (1<<6) == (1<<6)) 12 .loc 1 151 0 13 0006 F2000EA0 mov r7, INA 14 000a F9010E60 test r7,#0x1 wz 152:encoderDevice02.c **** return 1; 15 .loc 1 152 0 16 000e 8AA001 IF_NE mov r0, #1 151:encoderDevice02.c **** if(INA & (1<<6) == (1<<6)) 17 .loc 1 151 0 18 0011 751D IF_NE brs #.L2 153:encoderDevice02.c **** if(INA & (1<<7) == (1<<7)) 19 .loc 1 153 0 20 0013 F2000EA0 mov r7, INA 21 0017 F9010E60 test r7,#0x1 wz 154:encoderDevice02.c **** return 2; 22 .loc 1 154 0 23 001b 8AA002 IF_NE mov r0, #2 153:encoderDevice02.c **** if(INA & (1<<7) == (1<<7)) 24 .loc 1 153 0 25 001e 7510 IF_NE brs #.L2 155:encoderDevice02.c **** if(INA & (1<<8) == (1<<8)) 26 .loc 1 155 0 27 0020 F2000EA0 mov r7, INA 28 0024 FB010E60 and r7,#1 wz 156:encoderDevice02.c **** return 3; 29 .loc 1 156 0 30 0028 2702 cmps r7, #0 wz,wc 31 002a 85A000 IF_E mov r0,#0 32 002d 8AA003 IF_NE mov r0,#3 33 .L2 157:encoderDevice02.c **** return 0;It doesn't appear to be doing the correct thing. It is doing some optimization here, which is good because what I have to do in C isn't optimal but the line:
test r7,#0x1 wz
Is comparing what was copied from INA to the value 1, which isn't what I want. In my case, I really need to compare to 1<<6, 1<<7, or 1<<8 to get correct answers.
Is there a setting or keyword that I can use (short of setting things to -O0) to keep the compiler from being so hyperactive about its optimization that it loses sight of what I am asking it to do?
No hurry on this one though, it was relatively easy to drop to assembly for this one.
if((INA & (1<<6)) == (1<<6)) return 1;...Though this one ended up not having anything to do with the compiler. I can't believe that I have never run across this one before.
Do any of you have any ideas about this one?
Update....
I just built a new project from scratch that only has the toggle cog and the TV and graphics stuff. This project isn't allowing me to run both things at the same time as well.
Here is the code for that project:
/* LensEncoderDevice.c */ #include "propeller.h" #include "tv.h" #include "Graphics.h" void startTVgraphics(); void startToggleCog(); void drawSomethingOnTheScreen(); // STUFF FOR THE TV AND GRAPHICS COG #define X_TILES 10 #define Y_TILES 7 #define X_EXPANSION 16 #define Y_EXPANSION 2 #define X_ORIGIN 0 // sets the origin to be the bottom left corner #define Y_ORIGIN 0 #define MAX_COLORS 64 HUBDATA TV_t gTV; HUBDATA volatile uint16_t gScreen[X_TILES * Y_TILES]; HUBDATA volatile uint32_t gColors[MAX_COLORS]; HUBDATA volatile uint32_t gDisplay[(X_TILES * Y_TILES << 4)+128]; HUBDATA volatile uint32_t gBitmap [(X_TILES * Y_TILES << 4)+128]; HUBDATA volatile unsigned int bottomButton = 1 << 6; #define BITMAP_BASE (((int)gBitmap +256) & ~127) // page align #define DISPLY_BASE (((int)gDisplay+256) & ~127) // VARIABLES FOR THE TOGGLE COG static uint32_t delay; // a pointer to this gets passed to the PASM code as the PAR register static uint32_t pins; static uint32_t loop_cnt; static uint32_t pasm_done; _COGMEM volatile unsigned int LED = 1 << 13; //------------------------------------------------------------------------------------------------ int main() { startToggleCog(); startTVgraphics(); drawSomethingOnTheScreen(); while(1) { } }// end of main //------------------------------------------------------------------------------------------------ void startTVgraphics() { int n, dx, dy; int cog; TV_t* tp = &gTV; tp->enable = 1; tp->pins = TV_BASEBAND_PIN(24); tp->mode = 0; tp->screen = (uint32_t) &gScreen[0]; tp->colors = (uint32_t) &gColors[0]; tp->ht = X_TILES; tp->vt = Y_TILES; tp->hx = X_EXPANSION; tp->vx = Y_EXPANSION; tp->ho = 0; tp->vo = 0; tp->broadcast = 0; tp->auralcog = 0; cog = TV_start(tp); // init colors for(n = 0; n < MAX_COLORS; n++) gColors[n] = 0x1010 * ((n+4) & 0xF) + 0x2B060C02; // init tile screen for (dx = 0; dx < tp->ht; dx++) for (dy = 0; dy < tp->vt; dy++) gScreen[dy * tp->ht + dx] = (DISPLY_BASE >> 6) + dy + dx * tp->vt + ((dy & 0x3F) << 10); // start graphics cog Graph_start(); Graph_setup(X_TILES, Y_TILES, X_ORIGIN, Y_ORIGIN, BITMAP_BASE); } //------------------------------------------------------------------------------------------------ void startToggleCog() { // just blinks my LED pin now. delay = CLKFREQ>>4; pins = LED; loop_cnt = 50; pasm_done = 0; extern unsigned int binary_toggle_dat_start[]; cognew(&binary_toggle_dat_start, &delay); } //------------------------------------------------------------------------------------------------ void drawSomethingOnTheScreen() { Graph_colorwidth(2,0); Graph_textmode(1,1,6,0); Graph_text(120,0,"Menu ->"); }The compiler settings are:
EEPROM
C
CMM
-O1 Mixed
I have also tried tucking the toggle cog stuff into the graphics demo program. The graphics portion runs but the toggle won't. If I take all of the graphics and TV stuff out of the project manager and put it right back in then the LED blinks but there are no graphics....