Migrating from Propeller Tool to PropellerIDE or SimpleIDE

2»

Comments

  • DavidZemon wrote: »
    Absolutely. And in those scenarios, PropWare::Pin::set_direction would not be appropriate. But of course there are many ways to solve that problem with PropGCC as the build tool of choice

    I put great value into readability of code. Especially because part of the purpose of my project is educational. When it comes to that, PropWare::Pin::set_direction is perfect: Everyone who reads it (even with zero Propeller knowledge) will understand what's going on. The compiler does a pretty decent job of translating it to code too (at least it inserts the code inline instead of implementing it as a function) and even the Assembly output from the compiler is decently readable. I've only started to look at PropWare but I'm impressed so far. But I hope you agree the C/C++ compiler could use some work in the optimization department.

    ===Jac
    Rancho Cucamonga, CA
  • DavidZemon wrote: »
    Absolutely. And in those scenarios, PropWare::Pin::set_direction would not be appropriate. But of course there are many ways to solve that problem with PropGCC as the build tool of choice

    I put great value into readability of code. Especially because part of the purpose of my project is educational. When it comes to that, PropWare::Pin::set_direction is perfect: Everyone who reads it (even with zero Propeller knowledge) will understand what's going on. The compiler does a pretty decent job of translating it to code too (at least it inserts the code inline instead of implementing it as a function) and even the Assembly output from the compiler is decently readable. I've only started to look at PropWare but I'm impressed so far. But I hope you agree the C/C++ compiler could use some work in the optimization department.

    ===Jac
    You might try a newer version of PropGCC than what comes with SimpleIDE. I think Eric Smith said that the newer version has some additional optimizations.

  • yetiyeti Posts: 415
    edited April 7 Vote Up0Vote Down
    David Betz wrote: »
    You might try a newer version of PropGCC than what comes with SimpleIDE. I think Eric Smith said that the newer version has some additional optimizations.
    The last tests I did (in 2015) showed PropGCC5 being slower than PropGCC4 in non-cog-modes. In cog mode they were identically fast.

    Is there a newer PropGCC5 now?

    Or do you mean PropGCC4-1.0 vs PropGCC4-1.9?
    ◁ Stay OmmmmmmPtimistic! ▷ ◁ Facebook. ▷ ◁ Google. ▷ ◁ Microsoft. ▷ ◁ No Source – No Go! ▷ ◁ Please help: http://rosettacode.org/wiki/Category:Spin ▷ ◁ Why Asimov's Laws of Robotics Don't Work - Computerphile ▷ ◁ DNA is a four letter word. ▷
  • yeti wrote: »
    David Betz wrote: »
    You might try a newer version of PropGCC than what comes with SimpleIDE. I think Eric Smith said that the newer version has some additional optimizations.
    The last tests I did (in 2015) showed PropGCC5 being slower than PropGCC4 in non-cog-modes. In cog mode they were identically fast.

    Is there a newer PropGCC5 now?

    Or do you mean PropGCC4-1.0 vs PropGCC4-1.9?
    I'm not sure what we're up to now. It may be GCC6. David Zemon's build server builds the latest version whenever anything changes.
  • It's gcc6 now
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: http://david.zemon.name:8111/?guest=1
  • DavidZemon wrote: »
    It's gcc6 now
    Where are the sources?
    Is XMM completely dead now?

    And what version is Parallax's "official" release?
    Still on PropGCC4-1.0?

    That whole PropGCC mischmasch needs a massive cleanup!
    ◁ Stay OmmmmmmPtimistic! ▷ ◁ Facebook. ▷ ◁ Google. ▷ ◁ Microsoft. ▷ ◁ No Source – No Go! ▷ ◁ Please help: http://rosettacode.org/wiki/Category:Spin ▷ ◁ Why Asimov's Laws of Robotics Don't Work - Computerphile ▷ ◁ DNA is a four letter word. ▷
  • David BetzDavid Betz Posts: 12,512
    edited April 8 Vote Up0Vote Down
    yeti wrote: »
    DavidZemon wrote: »
    It's gcc6 now
    Where are the sources?
    Is XMM completely dead now?

    And what version is Parallax's "official" release?
    Still on PropGCC4-1.0?

    That whole PropGCC mischmasch needs a massive cleanup!
    XMM is still in PropGCC. It's just been removed from SimpleIDE.

    Talk to Parallax about the PropGCC mismatch. We've been after them for YEARS to update GCC in SimpleIDE. That's one of the main reasons that GCC development has ceased. There is no point in working on something that isn't getting used.

  • yeti wrote: »
    DavidZemon wrote: »
    It's gcc6 now
    Where are the sources?

    Since it's open source, they're in lots of places. These are the sources my server uses though: https://github.com/dbetz/propeller-gcc
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: http://david.zemon.name:8111/?guest=1
  • For example, check out https://github.com/jacgoudsmit/L-Star/tree/master/Software/SimpleIDE/Demo3 which is a complete emulator for the Apple 1. It runs as fast as it can, and it does the trick of demonstrating and explaining how the Propeller bitbangs the 6502. But I can only make it run at 1 MHz if I use assembler for the low level stuff. That's okay, because most of my audience is probably not going to be interested in that kind of detail anyway; they can just use a library or object file that contains the assembly code, or I can use inline assembly. But there is still a large amount of value in having an IDE that handles the tediousness of compiling and linking various modules together.

    Sorry but I don't understand, I'm not using SimpleIDE but as far as I can tell it supports mixing assembler files and c code just fine.
    You have a couple of options:

    1. Write the low level code that runs in a cog in assembler to .s files
    2. Move the low level C code in .cogc files that will get compiled to run in a cog natively without lmm

    The assembler option results in the fastest code, but if assembler is not suitable for your audience, the cogc option is more readable and even if the generated code is not highly optimized it will run significantly faster than your current code that, if I'm not wrong, runs the cogs in lmm mode which is at least 1/16 slower than anything that runs natively in a cog.

    The more recent builds of the propeller-gcc toolchain from David Zemon also compiles existing pasm code almost unchanged. I have a lot of c and assembler code running for my projects.
    VT-100 Terminal and Graphics Card for the RC2014 Z80 Computer
  • Fcache combined with inline assembly is my personal favorite option for code that needs to be fast. I use that for most of the serial protocols (UART, SPI, I2C). I've talked about it at length in other threads, but I just think it's the coolest thing ever that we can get the legibility and compactness of CMM code when we need it, and the speed and control of native assembly when we need it, all without having to use up precious cogs! Here's an example from PropWare::SPI:

    https://github.com/parallaxinc/PropWare/blob/develop/PropWare/serial/spi/spi.h#L273
    (note that FC_START, FC_END, and FC_ADDR are defined here: https://github.com/parallaxinc/PropWare/blob/develop/PropWare/PropWare.h#L69)
    /**
     * @brief       Send an array of data at max transmit speed. Mode is always MODE_0 and data is always MSB first
     *
     * Clock will run at 4 MHz with a sustained 3.33 Mbps average bitrate over multiple bytes.
     *
     * @param[in]   buffer[]        Address where data is stored
     * @param[in]   numberOfBytes   Number of words to send
     */
    void shift_out_block_msb_first_fast (const uint8_t buffer[], size_t numberOfBytes) const {
        __asm__ volatile (
    #define ASMVAR(name) FC_ADDR(#name "%=",  "SpiBlockWriteStart%=")
        FC_START("SpiBlockWriteStart%=", "SpiBlockWriteEnd%=")
                "       jmp #" FC_ADDR("loopOverBytes%=", "SpiBlockWriteStart%=") "                         \n\t"
    
                // Temporary variables
                "bitIdx%=:                                                                                  \n\t"
                "       nop                                                                                 \n\t"
                "data%=:                                                                                    \n\t"
                "       nop                                                                                 \n\t"
    
    
                "loopOverBytes%=:                                                                           \n\t"
                "       rdbyte " ASMVAR(data) ", %[_bufAdr]                                                 \n\t"
                "       mov " ASMVAR(bitIdx) ", #8                                                          \n\t"
                "       ror " ASMVAR(data) ", " ASMVAR(bitIdx) "                                            \n\t"
    
                "loopOverBits%=:                                                                            \n\t"
                "       rol " ASMVAR(data) ", #1 wc                                                         \n\t"
                "       muxc outa, %[_mosi]                                                                 \n\t"
                "       xor outa, %[_sclk]                                                                  \n\t"
                "       xor outa, %[_sclk]                                                                  \n\t"
                "       djnz " ASMVAR(bitIdx) ", #" FC_ADDR("loopOverBits%=", "SpiBlockWriteStart%=") "     \n\t"
    
                // Write the word back to the buffer in HUB memory
                "       add %[_bufAdr], #1                                                                  \n\t"
    
                "       djnz %[_numberOfBytes], #" FC_ADDR("loopOverBytes%=", "SpiBlockWriteStart%=") "     \n\t"
    
                "       or outa, %[_mosi]                                                                   \n\t"
                FC_END("SpiBlockWriteEnd%=")
    #undef ASMVAR
        : [_bufAdr] "+r"(buffer),
        [_numberOfBytes] "+r"(numberOfBytes)
        :[_mosi] "r"(this->m_mosi.get_mask()),
        [_sclk] "r"(this->m_sclk.get_mask())
        );
    }
    
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: http://david.zemon.name:8111/?guest=1
  • DavidZemon wrote: »
    yeti wrote: »
    DavidZemon wrote: »
    It's gcc6 now
    Where are the sources?

    Since it's open source, they're in lots of places. These are the sources my server uses though: https://github.com/dbetz/propeller-gcc
    That repo's README still speaks of GCC5. No wonder that I missed the change from 5 to 6!
    ◁ Stay OmmmmmmPtimistic! ▷ ◁ Facebook. ▷ ◁ Google. ▷ ◁ Microsoft. ▷ ◁ No Source – No Go! ▷ ◁ Please help: http://rosettacode.org/wiki/Category:Spin ▷ ◁ Why Asimov's Laws of Robotics Don't Work - Computerphile ▷ ◁ DNA is a four letter word. ▷
  • [*]Compatibility of PASM/BSTC/OpenSpin? PASM issues in gas? Answer: Crickets...
    ===Jac

    Recent versions of gas (based on binutils 2.28, rather than the 2.21 that comes with SimpleIDE) can handle most PASM constructs, except that it only understands the subset of Spin operators that is also present in C (so for example it does not understand "|< N", but is OK if you write "1<<N" instead). I think David Zemon has up to date builds of binutils and PropGCC, and he's done a great service to the community.


  • Also, everyone keeps saying that "Spin is slower than C", but they're talking about the traditional Spin compilers (OpenSpin, bstc, homespun) which compile to bytecode. There's also a Spin compiler called fastspin that compiles directly to PASM, and in many cases it produces better code than PropGCC. For example, the Spin function:
    ''
    '' write a long word to a pin, as fast as we can
    ''
    
    PUB write_long(data, pin)
      repeat 32
        OUTA[pin] := (data & 1)
        data >>= 1
    

    compiles in LMM mode (with optimization on) to:
    @L__0005)
    L__0005
    	shr	arg1, #1 wc
    	muxc	OUTA, _var_03
    	djnz	_var_04, #LMM_FCACHE_START + (L__0005 - L__0005)
    L__0010
    _Write_long_ret
    	sub	sp, #4
    	rdlong	pc, sp
    

    fastspin's global optimizations are nowhere near as sophisticated as gcc's, but it's local optimizations know a lot more about the machine and so it can produce some very tight loops like the one above.

    fastspin itself doesn't have a GUI, but there are a few options:

    (1) fastspin's command line syntax is identical to openspin's, so it should be possible to drop it into PropellerIDE. For that matter, if it is invoked with the name "bstc" then it changes its command line handling to match bstc's, so if for some reason your version of PropellerIDE doesn't understand openspin then you can copy fastspin on top of bstc to use it.

    (2) fastspin is part of the spin2cpp tool suite, which comes with a very simple GUI called "spinconvert". That GUI lets you enter Spin code and see how it would be converted to C, C++, or PASM, with various options. It also allows you to run the compiled Spin code, although that part isn't as well tested and won't be as smooth as, say, PropellerIDE.

    Eric
  • Paraphrasing:
    "It's Open Source, it's all over the place"
    "What's the point in working on something if it doesn't get used anyway?"
    "GCC4? I thought GCC6"

    From all this, I'm concluding that there's a need for the tool developers to get organized.

    I started a new thread at https://forums.parallax.com/discussion/168351/idea-propeller-plumbers-organization-on-github

    ===Jac
    Rancho Cucamonga, CA
  • Paraphrasing:
    "It's Open Source, it's all over the place"
    "What's the point in working on something if it doesn't get used anyway?"
    "GCC4? I thought GCC6"

    From all this, I'm concluding that there's a need for the tool developers to get organized.

    I started a new thread at https://forums.parallax.com/discussion/168351/idea-propeller-plumbers-organization-on-github

    ===Jac
    Yes. Roy wrote OpenSpin using Chip's x86 code (as used in PropTool) years ago. Yet hardly anyone uses it because SimpleIDE and PropellerIDE seem to not be ready for mainstream despite lots of work done on them.

    For me, if I cannot use PropTool, then I usually edit with PropTool and compile with either bst or homespun. I use homespun to compile my Propeller OS because I have a BAT file that compiles all the little OS files in one job.

    Both bst and homespun just work so it doesn't matter that they are not supported. For that matter, PropTool isn't supported because any request has fallen on deaf ears for the past decade anyway. It's a shame because the text editing GUI is quite nice in most respects.

    This just confirms Jac's comments. His solution is probably as good as any other since Parallax cannot/won't solve this.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
Sign In or Register to comment.