Shop OBEX P1 Docs P2 Docs Learn Events
GCC usage? — Parallax Forums

GCC usage?

davidsaundersdavidsaunders Posts: 1,559
edited 2015-04-22 20:20 in Propeller 1
Ok I give up, I do not want to fight a new to me language, and I know C very well so:

I have a few questions on the usage of C in GCC on the Propeller:

Where do I get the version of GCC to target the Propeller (using Linux ARMv6 on RPi, and Win32 on x86).

How do you compile COG code for multiple COGS?

In gcc what are the macros for COGINIT, the timer stuff, and the name assignment of the control registers?

How is HUB RAM accessed with code compiled -mcog?

What are the limits of mixing COG and LMM code in a single binary blob?

How do you avoid using the C stack in COG only code (for local variables and functions calls)?

Is there anything that compiles to be larger than would be expected with the Propeller target?

What else do I need to know before I translate my SPIN and PropBASIC code to C?

Am I correct in assuming that the Propeller implementation of GCC correctly supports K&R style function definitions and declarations like other implementations of GCC?
«134

Comments

  • jmgjmg Posts: 15,173
    edited 2015-04-15 21:34
    How do you avoid using the C stack in COG only code (for local variables and functions calls)?

    Did you see the example in the other thread, where David ? ported the PropBASIC frequency Counter to GCC in two modes, showing the stack effects ?
    PropBASIC came in smaller, and it seems the main item restricting GCC, is that GCC is based on a 16 register code model.- and it's not clear if you can even force important variables to reserve one of those registers.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-15 21:39
    davidsaunders,

    I have SimpleIDE, which includes prop-gcc, for the Raspbery Pi here: https://dl.dropboxusercontent.com/u/81267937/SimpleIDE-0-9-47.x86_64.debian-linux.tar.bz2 That's a year old now and I'm sure others have created packages for the Pi since.

    A good way to see how to do what you want with COG code is to look in the demos that care in the propgcc source code:
    https://github.com/parallaxinc/propgcc/tree/master/demos

    For example https://github.com/parallaxinc/propgcc/tree/master/demos/full_duplex_serial_ht is a Full Duplex Serial I made that shows how to start in COG code and access HUB variables from it.

    If you mean K&R style function definitions like:
    int foo(a, p) 
        int a; 
        char *p; 
    { 
        return 0; 
    }
    
    Don't do that. There is no reason to use that obsolete style and will only confuse people.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 02:56
    Can you post your PropBASIC code so we can see what you're trying to do? No matter what language you use for writing code that runs in a COG, you're going to be limited to the amount of code that will fit. The fact is, the COG memory is very small. Also, addressing COG arrays is cumbersome because there is no indirect addressing in PASM. There is no way around that. Accessing hub memory is a lot more straight forward. Anyway, give us an example of what you're trying to do and either Bean will help you figure out how to do it in PropBASIC or we can give you advice for PropGCC.

    You can get a RaspberryPi build of PropGCC from SwimDude0614 has setup a build server that automatically builds new versions of PropGCC for various platforms including the RaspberryPi whenever anything changes in the propeller-gcc project on github. Just log in as "guest" and select the "PropGCC" project in the tab on the upper left. If you click on the "Artifacts" tab for the gcc4 build you should find a tarball containing the results of the build.

    Here is the URL to the build server: http://david.zemon.name:8111/login.html

    I'll try to answer some of your other questions later.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 04:58
    Ok I have answered many of my questions, by looking at the sample code. I am going to dig up the other thread for the information on no stack in COG code.

    I do append one more question:
    What are the data type sizes in the Propeller target?

    I would expect:
    int = long
    long = 32-bits.
    short = 16 bits.
    char = 8bits.
    float = 32 bit IEEE floating point.
    double = 64 bit IEEE floating point.

    Would that be correct? I do not so much care about float and double, they are not of much use to me in small applications(heck even in rendering 3D graphics on a desktop computer I use pure integer math [still the fastest way with out using an accelerator]).
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 05:03
    Ok I have answered many of my questions, by looking at the sample code. I am going to dig up the other thread for the information on no stack in COG code.

    I do append one more question:
    What are the data type sizes in the Propeller target?

    I would expect:
    int = long
    long = 32-bits.
    short = 16 bits.
    char = 8bits.
    float = 32 bit IEEE floating point.
    double = 64 bit IEEE floating point.

    Would that be correct? I do not so much care about float and double, they are not of much use to me in small applications(heck even in rendering 3D graphics on a desktop computer I use pure integer math [still the fastest way with out using an accelerator]).
    Yes, those are all correct. Also, I believe that char is signed. There is also a compiler option -m32bit-doubles that forces doubles to be 32 bits as well. That gives much better performance and smaller code size on the Propeller if you don't need the full range of 64 bit doubles.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 05:22
    David Betz wrote: »
    Yes, those are all correct. Also, I believe that char is signed. There is also a compiler option -m32bit-doubles that forces doubles to be 32 bits as well. That gives much better performance and smaller code size on the Propeller if you don't need the full range of 64 bit doubles.
    Thank you. I will be sticking mostly with long, int, short, and char data types.

    For dealing with the floating point numbers in G-Code I will just convert it to integers representing increments of 1/16th of a mm, and use only integer math, As the minimum usable size is about 0.0625mm on my 3D printer (and 99% only go down to 0.1mm) I see no reason to do better than that. The two or three places where the fractional value of a calculation could make a difference for rounding error I will just use shifted values (ie crude fixed point where IValue = FValue << 8), will work well as the range of values is way less than 65536 in any direction (with the exception of number of steps, which is 8 for each usable minimum move [minimum move being 0.0625mm] so 32768 [max possible range] * 8 is 262144 total steps if you expand the print volume in at least one direction all the way to 512 meters [good luck]).

    I think that the floating point code would be just wasted space in a bit of firmware running on a Propeller, there are very very few applications that truly require floating point, so it is a lot better to just use integer math in 99% of cases and not waste the space of the floating point code.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-16 07:34
    David Betz wrote: »
    Also, I believe that char is signed.
    I think char is unsigned. If you run the following code the output will be 255 and not -1.
    char x = -1;
    printf("%d\n", x);
    
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 07:36
    Dave Hein wrote: »
    I think char is unsigned. If you run the following code the output will be 255 and not -1.
    char x = -1;
    printf("%d\n", x);
    
    Okay, I stand corrected. That's why I said "I think" in my original response. Thanks for checking!
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 08:40
    Dave Hein wrote: »
    I think char is unsigned. If you run the following code the output will be 255 and not -1.
    char x = -1;
    printf("%d\n", x);
    
    Not a good test. That only shows how printf(*s,...) interprets the data, not how it is treated in the usage of expressions. A better test would be:
    char x; short y;
    y = 5; x = -5;
    
    if (x < y) puts("unsigned char type\n"); else puts("signed char type");
    

    That would give a definite answer. At the moment I am still attempting to recover where I was in PropBASIC, so I have not yet installed Prop GCC, and can not check for myself.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-16 08:42
    I feel so silly reading this. We all have the link for PropGCC's source code right in front of us... we could look and find out for sure. But I guess no one has any idea where in the source code to look! :P
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 08:43
    I feel so silly reading this. We all have the link for PropGCC's source code right in front of us... we could look and find out for sure. But I guess no one has any idea where in the source code to look! :P
    GCC source is huge regardless of target, it would be difficult to find what is needed.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-16 08:50
    GCC source is huge regardless of target, it would be difficult to find what is needed.

    I spent 60 seconds looking after I posted and gave up. "huge" doesn't quite cover it
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-16 09:38
    Not a good test. That only shows how printf(*s,...) interprets the data, not how it is treated in the usage of expressions.
    No, that's not quite true. It shows how the C compiler promotes a variable to a 32-bit function parameter. But a better test is to just look at the generated assembly code for "i = x;", where x is declared as a char and i is declared as an int. The generated code contains a rdbyte followed by a wrlong. There is no sign extension in between the two instructions, so a char is treated as an unsigned byte. If I declare x as a signed char the compiler will generate a "shl r..,#24" followed by a "sar r..,#24", which performs a sign extension for an 8-bit value.
  • koehlerkoehler Posts: 598
    edited 2015-04-16 10:02
    Heater. wrote: »
    davidsaunders,
    If you mean K&R style function definitions like:
    int foo(a, p) 
        int a; 
        char *p; 
    { 
        return 0; 
    }
    
    Don't do that. There is no reason to use that obsolete style and will only confuse people.


    Heater,

    Really? I am used to that, or at least learned it like that.

    What is the preferred way, using the same example, and why?
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-16 10:12
    The preferred way is
    int foo(int a, char *p) 
    { 
        return 0; 
    }
    
    Some people will write this as
    int foo(
    int a,  // First parameter
    char *p // Second parameter
    ) 
    { 
        return 0; 
    }
    
    This method allows for adding comments after each parameter to describe what they mean. I haven't seen the K&R style used in years.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-16 10:16
    Dave Hein wrote: »
    The preferred way is
    int foo(int a, char *p) 
    { 
        return 0; 
    }
    
    Some people will write this as
    int foo(
    int a,  // First parameter
    char *p // Second parameter
    ) 
    { 
        return 0; 
    }
    
    This method allows for adding comments after each parameter to describe what they mean. I haven't seen the K&R style used in years.

    I hope you'll choose to follow the (new?) standard of doxygen comments though. This is the comment/documentation standard used by Parallax and numerous others
    /**
     * @brief My Cool function
     * @param a First parameter
     * @param *p Second parameter
     * @return The constant zero
     */
    int foo(int a, char *p)
    {
        return 0;
    }
    
  • ersmithersmith Posts: 6,053
    edited 2015-04-16 11:22
    I feel so silly reading this. We all have the link for PropGCC's source code right in front of us... we could look and find out for sure. But I guess no one has any idea where in the source code to look! :P
    How about in the doc directory? :) Specifically, doc/C-Standard.h says "char is equivalent to "unsigned char" by default".
  • ersmithersmith Posts: 6,053
    edited 2015-04-16 11:29
    Where do I get the version of GCC to target the Propeller (using Linux ARMv6 on RPi, and Win32 on x86).
    Personally I would compile it myself on an x86 Linux machine (e.g. make CROSS=rpi, make CROSS=win32).
    In gcc what are the macros for COGINIT, the timer stuff, and the name assignment of the control registers?
    See propeller.h.
    How is HUB RAM accessed with code compiled -mcog?
    With pointers. All data is in hub by default.
    What are the limits of mixing COG and LMM code in a single binary blob?
    You have to compile them separately and link them together.
    How do you avoid using the C stack in COG only code (for local variables and functions calls)?
    Declare functions _NATIVE, and declare variables to be _COGMEM.
    What else do I need to know before I translate my SPIN and PropBASIC code to C?
    You can translate your Spin code to C (or C++) with spin2cpp.

    Eric
  • ersmithersmith Posts: 6,053
    edited 2015-04-16 11:31
    Dave Hein wrote: »
    No, that's not quite true. It shows how the C compiler promotes a variable to a 32-bit function parameter. But a better test is to just look at the generated assembly code for "i = x;", where x is declared as a char and i is declared as an int. The generated code contains a rdbyte followed by a wrlong. There is no sign extension in between the two instructions, so a char is treated as an unsigned byte. If I declare x as a signed char the compiler will generate a "shl r..,#24" followed by a "sar r..,#24", which performs a sign extension for an 8-bit value.

    That's definitely the best way to check! And as you've noticed, unsigned char is a lot more natural on the Propeller.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-16 11:54
    koehler,

    Well, the style, and the standard changed about twenty years ago or so. As people have shown above.

    Is it better or worse?. Up to you to judge I guess.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 14:39
    Heater. wrote: »
    davidsaunders,
    If you mean K&R style function definitions like:
    int foo(a, p) 
        int a; 
        char *p; 
    { 
        return 0; 
    }
    
    Don't do that. There is no reason to use that obsolete style and will only confuse people.
    Ok I am confused. How does the more readable form confuse people?? The ANSI C style definitions are more difficult to read (especially as you get a good number of parameters).
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 14:49
    ersmith wrote: »
    Personally I would compile it myself on an x86 Linux machine (e.g. make CROSS=rpi, make CROSS=win32).


    See propeller.h.
    OK will do.
    With pointers. All data is in hub by default.
    OUCH, that is going to make using pointers to hub locations difficult.
    You have to compile them separately and link them together.
    Ok easy enough.
    Declare functions _NATIVE, and declare variables to be _COGMEM.
    OK, that seems easy enough.
    You can translate your Spin code to C (or C++) with spin2cpp.

    Eric
    Do not like auto translation programs, besides the PropBASIC Version is further along than the SPIN version.

    So if I understand correctly for a COG only function and not using the stack I would do something like:
    _NATIVE MyFunc(a,b,c,d)
    char *c;
    {
      _COGMEM long tmp;
      /* Do something using int parameters a, b, and d, and string parameter c */
      return 0;
    }
    
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 14:50
    Heater. wrote: »
    koehler,

    Well, the style, and the standard changed about twenty years ago or so. As people have shown above.

    Is it better or worse?. Up to you to judge I guess.
    Who knows which is best, though I have been using K&R style C since I was 8 years old (before ANSI C existed), so it is what I am accustomed to.

    There are many views on the subject.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 15:41
    As I need to actually make some headway, and do not want to scare new to prop users by using PASM, I have decided to forge ahead with C, I will be installing Simple IDE on my x86 in a few minutes, and I already have it on the RPi (for SPIN and PASM stuff).
  • David BetzDavid Betz Posts: 14,516
    edited 2015-04-16 15:52
    As I need to actually make some headway, and do not want to scare new to prop users by using PASM, I have decided to forge ahead with C, I will be installing Simple IDE on my x86 in a few minutes, and I already have it on the RPi (for SPIN and PASM stuff).
    If you really want to use K&R syntax, it looks like PropGCC will support it.
  • jmgjmg Posts: 15,173
    edited 2015-04-16 15:57
    As I need to actually make some headway, and do not want to scare new to prop users by using PASM, I have decided to forge ahead with C, I will be installing Simple IDE on my x86 in a few minutes, and I already have it on the RPi (for SPIN and PASM stuff).

    If you are doing a lot of sparse jump tables, one alternative method would be to pack the Addr:Condition into hub memory, and code either a compact scanner, or a dual-lookup. - There is more HUB memory than COG memory
  • jmgjmg Posts: 15,173
    edited 2015-04-16 16:01
    Ok I am confused. How does the more readable form confuse people?? The ANSI C style definitions are more difficult to read (especially as you get a good number of parameters).
    another test is how does the Find-declaration editors cope with the various forms.?
    I prefer to see the type info close to the param name & for many params, multiple lines are easily used.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-16 17:06
    David Betz wrote: »
    If you really want to use K&R syntax, it looks like PropGCC will support it.
    I figured as much, I just got Simple IDE installed, so we will see how it goes.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-16 17:31
    David

    All depending how deep you want to get into it.....

    The simpletools library (simpletools.h) is the goto place to get things done quickly and then other times, you may just need a Propeller function without all the extras, in which case just use propeller.h. To get your code size down to a minimum, check "Enable Pruning" under compiler options.

    Additionally, there are times when the SimpleIDE help is helpful for a quick reference, and then there are times when it is nice to look at the library itself, and the various definitions. Most if not all of the functions declared in simpletools.h, are defined in seperate C files. Although the C file names do not always match the function names. In which case, I simply search the function name, in the SimpleIDE directory, and several files usually pop up. Select the file that most closely resembles the function name and you will find the function defintion that you are seeking.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-16 17:44
    If you need to see the definition of something in Simple, you can search the function name from PropWare's documentation site - Simple is documented there. For instance, by searching "putchar" in the top-right corner search box, I get this link. From there, you can see it says "Definition at line 11 of file putChar.c". Very helpful :)
Sign In or Register to comment.