PropGCC for P2

124»

Comments

  • roglohrogloh Posts: 1,289
    edited 2019-09-16 - 01:17:45
    Register r14 is being used as the frame pointer, except it wasn't initialized with the value of ptra first.

    I noticed this use of r14 too. I wonder if it makes sense if the other P2 pointer register PTRB could/should be used for doing the frame pointer? Then potentially any local hub variables/arguments could be accessed directly with these types of indexed/offset hub access instruction formats:

    rdlong rxx, ptrb[8]
    rdword ryy, ptrb[4]
    wrbyte rzz, ptrb[-10]
    etc

    Initially I though the SP (PTRA) register itself could also be used for this same purpose, but its base can obviously change during execution as data is pushed/popped on/off the stack dynamically which changes all the offsets required, and I'm not sure if GCC compensates automatically for that or not (hopefully it could though I don't think it would easily work if extra dynamic stack memory is ever allocated with alloca for example). So perhaps using a separate frame pointer register is probably somewhat more standard, and may make good use of PTRB.

    I'd also earlier thought PTRB might be good to use for doing pointers to structures and directly accessing the data members at known offsets too but perhaps it's easier to use instead as a frame pointer which could give some good bang per buck for argument/local accesses on the stack as it frees the need to construct separate pointers everywhere the stack frame data gets accessed (which is probably quite a lot in C, though structure access can still get somewhat common too depending on how things are coded).
  • David BetzDavid Betz Posts: 13,481
    edited 2019-09-16 - 02:29:01
    The good news is that I've been able to build both binutils and gcc. Unfortunately, I just tried to update using the following commands and got an error.
    git pull
    git submodule update
    
    The error was:
    error: no such remote ref bdf8861e1312d64f3858f00e3290e2b499df12d4
    Fetched in submodule path 'binutils-gdb', but it did not contain bdf8861e1312d64f3858f00e3290e2b499df12d4. Direct fetching of that commit failed.
    
  • David Betz wrote: »
    The good news is that I've been able to build both binutils and gcc. Unfortunately, I just tried to update using the following commands and got an error.
    git pull
    git submodule update
    
    The error was:
    error: no such remote ref bdf8861e1312d64f3858f00e3290e2b499df12d4
    Fetched in submodule path 'binutils-gdb', but it did not contain bdf8861e1312d64f3858f00e3290e2b499df12d4. Direct fetching of that commit failed.
    

    That looks like someone rewrote the history of the submodule repository resulting in a broken commit reference.
  • Actually I just forgot to push a commit to binutils when I updated p2gcc-dev. Details details.

    The other way to update is to go into 'gcc' and 'binutils-gdb' and do:
    git checkout feature/propeller2
    git pull
    
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • Mid-week update:

    GAS + LD can now output a runnable ELF image loadable by loadp2!

    blink.s
        .file       "blink.s"
        .section    ".cogram"
    _start:
        shl p, pin
        or dirb, p
    _blink:
        xor outb, p
        waitx t
        jmp #_blink
    
    p:
        .long 1
    t:  
        .long 40000000
    pin:
        .long 24
    

    steps to reproduce:
    propeller-elf-as blink.s -o blink.o
    propeller-elf-ld blink.o -o blink
    ./loadp2/build/loadp2 -CHIP -v -p /dev/ttyUSB0 blink
    
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • Great milestone! Can't wait to update and try it as soon as I get a chance myself.
  • (Obligatory hello world blinky photo)
    800 x 600 - 253K
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • Oh wow photos and all, well done Brian!
  • Hehe, it must be real then.

    "We suspect that ALMA will allow us to observe this rare form of CO in many other discs.
    By doing that, we can more accurately measure their mass, and determine whether
    scientists have systematically been underestimating how much matter they contain."
  • ntosme2ntosme2 Posts: 32
    edited 2019-09-22 - 20:55:46
    It took my brain some time to grok exactly how ELF relocations are used by LD to link an executable, but it's finally working.

    Here's a new demo of a simple cogexec boot snippet that sets up the clock, sets the stack pointer and jumps to _main.
    boot code loaded to 0x0
        .file       "crti.S"
        .section    ".boot"
    _start:
        hubset _clkmode
        waitx   ##200000
        or _clkmode, #3
        hubset _clkmode
        mov ptra, #__stack
        jmp #_main
    
        //  PLL on   div 0+1  mul 7+1    div 2    drive  RCFAST
        // (1<<24) + (0<<18) + (7<<8) + (0<<4) + (2<<2) + (0)
    _clkmode:
        .long 0x1000708
    
        .section    ".hubram"
    __stack:
        .zero 4*100
    

    C++ in hubexec with some variables in COGRAM
    #define _COGRAM __attribute__((cogram))
    #define _LUTRAM __attribute__((lutram))
    #define _HUBRAM __attribute__((hubram))
    
    unsigned int num _COGRAM = 3;
    unsigned int period _COGRAM = 10000000;
    
    void waitx(int x) {
        asm("waitx %[x]"
            :
            : [x] "r" (x));
    }
    
    void blink(unsigned int cnt, unsigned int pin) {
        unsigned int mask = 1 << pin;
        asm("or dirb, %[mask]\n\t"
            :
            : [mask] "r" (mask));
        for(int i=0; i<cnt; i++) {
            asm("andn outb, %[mask]\n\t"
                :
                : [mask] "r" (mask));
            waitx(period);
            asm("or outb, %[mask]\n\t"
                :
                : [mask] "r" (mask));
            waitx(period);
        }
    }
    
    int main() {
        unsigned int p = 24;
        while(true) {
            blink(num, p);
            p++;
            if(p>31)
                p = 24;
        }
    }
    

    Build/run steps
    propeller-elf-as crti.S -o crti.o
    propeller-elf-g++ test.cpp -c -O2
    propeller-elf-ld crti.o test.o -o test
    /loadp2/build/loadp2 -CHIP -v -p /dev/ttyUSB0 test
    

    Also here's the default linker script:
    /* Default linker script, for normal executables */
    /* Copyright (C) 2014-2019 Free Software Foundation, Inc.
       Copying and distribution of this script, with or without modification,
       are permitted in any medium without royalty provided the copyright
       notice and this notice are preserved.  */
    OUTPUT_FORMAT("elf32-littlepropeller")
    OUTPUT_ARCH(propeller)
    MEMORY
    {
      cogram : org = 0, l = 4 * 0x1EF
      lutram : org = 0x800, l = 4 * 0x200
      hubram : org = 0x0, l = 512K
    }
    PHDRS
    {
      headers PT_PHDR ;
      text PT_LOAD ;
    }
    SECTIONS
    {
      . = SIZEOF_HEADERS ;
      .data :
      {
        *(.boot)
        *(.cogram)
        . = 0x1000 ;
        *(.hubram)
      } >hubram :text
    }
    
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • roglohrogloh Posts: 1,289
    edited 2019-09-23 - 14:05:06
    This is great Brian! Have updated my tree and am re-compiling your latest gcc as I type and can already hear the fans spinning up so I know my Mac is hard at work in preparation for this.

    You've now got an end to end toolchain for the P2 showing great signs of life. Keep at it! :smile: :smile:

    Very :cool: work. I know to get things going this far requires a lot.
  • HUBSET police calling ... making sure you are aware of the important workaround, after the PLL is engaged, needed in any subsequent _hubset() primitive ... Heh, funnily, there isn't an actual example of this posted anywhere.
    "We suspect that ALMA will allow us to observe this rare form of CO in many other discs.
    By doing that, we can more accurately measure their mass, and determine whether
    scientists have systematically been underestimating how much matter they contain."
  • ntosme2ntosme2 Posts: 32
    edited 2019-09-23 - 02:21:36
    @evanh Yeah I noticed the glaring warning in the v33 docs about saving the last value used. In the above example that would be hub address 0x1c (or let the linker find it).

    Is there actually a way to read the current value?
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • evanhevanh Posts: 7,922
    edited 2019-09-23 - 03:17:46
    ntosme2 wrote: »
    Is there actually a way to read the current value?
    Nope, all the special purpose registers are read only or write only, with maybe the exception of OUT and DIR. There is a lot of them in the prop2, all the smartpins for example, so it does save transistors.

    Eric and Ross will have nicely curated versions for C primative. Here's what I do in my dynamic setting routine after recalculating a new sysclock frequency and baud divider. No bounds checking, I know. "clk_mode" in this case is just a general cogRAM variable internal to my programs.
    'adjust hardware to new XMUL sysclock frequency
    		andn	clk_mode, #%11			'clear the two select bits to force RCFAST selection
    		hubset	clk_mode			'**IMPORTANT**  Switches to RCFAST using known prior mode
    
    		mov	clk_mode, xtalmul		'replace old with new ...
    		sub	clk_mode, #1			'range 1-1024
    		shl	clk_mode, #8
    		or	clk_mode, ##(1<<24 + (XDIV-1)<<18 + XPPPP<<4 + XOSC<<2)
    		hubset	clk_mode			'setup PLL mode for new frequency (still operating at RCFAST)
    
    		or	clk_mode, #XSEL			'add PLL as the clock source select
    		waitx	##22_000_000/100		'~10ms (at RCFAST) for PLL to stabilise
    		hubset	clk_mode			'engage!  Switch back to newly set PLL
    		ret			wcz
    

    Don't know about Ross but Eric has followed Dave's lead and used the preassigned mailbox at hub address $18 instead. The mailbox is important if you are passing a preset PLL mode between programs. If you can count on RCFAST as the handover between programs then the mailbox mechnism is optional. Further reading - https://forums.parallax.com/discussion/comment/1475472/#Comment_1475472

    "We suspect that ALMA will allow us to observe this rare form of CO in many other discs.
    By doing that, we can more accurately measure their mass, and determine whether
    scientists have systematically been underestimating how much matter they contain."
  • Dang it, the stack pointer isn't being linked correctly. Not much is going to work until I fix that!
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • roglohrogloh Posts: 1,289
    edited 2019-09-23 - 04:28:03
    Hi @ntosme2,

    I updated (via git pull) and recompiled both gcc and binutils using your feature/propeller2 branch.

    I can't replicate the results you have above, are you sure it is checked into gitlab or is it still something you are working on, or perhaps exists in some other branch I should use instead?

    I get this result during compile on the code above:
    propeller-elf-g++ test.cpp -c -O2
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s: Assembler messages:
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:8: Error: unknown opcode 'wa'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:16: Error: unknown flag, 'r1'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:29: Error: unknown opcode 'wai'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:32: Error: unknown flag, 'r7'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:36: Error: unknown opcode 'wai'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:53: Error: unknown flag, 'r3'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:66: Error: unknown opcode 'wai'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:69: Error: unknown flag, 'r6'
    /var/folders/mb/x0js1f3s30qfjrfx0pj644740000gn/T//ccnQkzGW.s:73: Error: unknown opcode 'wai'
    

    I attached the same file converted to assembly code below (with the -S option to gcc) if that helps identify the issue.

    The assembler doesn't seem to like it. Similar types of errors when assembling the crti.S file.
    RLs-MacBook-Pro:proptest roger$ propeller-elf-as crti.S -o crti.o
    crti.S: Assembler messages:
    crti.S:4: Error: unknown flag, 'mode'
    crti.S:6: Error: unknown flag, '3'
    crti.S:8: Error: unknown opcode 'v'
    crti.S:9: Error: unknown opcode 'j'
    
    RLs-MacBook-Pro:proptest roger$ cat crti.S
        .file       "crti.S"
        .section    ".boot"
    _start:
        hubset _clkmode
        waitx   ##200000
        or _clkmode, #3
        hubset _clkmode
        mov ptra, #__stack
        jmp #_main
    
        //  PLL on   div 0+1  mul 7+1    div 2    drive  RCFAST
        // (1<<24) + (0<<18) + (7<<8) + (0<<4) + (2<<2) + (0)
    _clkmode:
        .long 0x1000708
    
        .section    ".hubram"
    __stack:
        .zero 4*100
    
    s
    s
    1K
  • ntosme2 wrote: »
    It took my brain some time to grok exactly how ELF relocations are used by LD to link an executable, but it's finally working.

    Here's a new demo of a simple cogexec boot snippet that sets up the clock, sets the stack pointer and jumps to _main.
    boot code loaded to 0x0
        .file       "crti.S"
        .section    ".boot"
    _start:
        hubset _clkmode
        waitx   ##200000
        or _clkmode, #3
        hubset _clkmode
        mov ptra, #__stack
        jmp #_main
    
        //  PLL on   div 0+1  mul 7+1    div 2    drive  RCFAST
        // (1<<24) + (0<<18) + (7<<8) + (0<<4) + (2<<2) + (0)
    _clkmode:
        .long 0x1000708
    
        .section    ".hubram"
    __stack:
        .zero 4*100
    

    C++ in hubexec with some variables in COGRAM
    #define _COGRAM __attribute__((cogram))
    #define _LUTRAM __attribute__((lutram))
    #define _HUBRAM __attribute__((hubram))
    
    unsigned int num _COGRAM = 3;
    unsigned int period _COGRAM = 10000000;
    
    void waitx(int x) {
        asm("waitx %[x]"
            :
            : [x] "r" (x));
    }
    
    void blink(unsigned int cnt, unsigned int pin) {
        unsigned int mask = 1 << pin;
        asm("or dirb, %[mask]\n\t"
            :
            : [mask] "r" (mask));
        for(int i=0; i<cnt; i++) {
            asm("andn outb, %[mask]\n\t"
                :
                : [mask] "r" (mask));
            waitx(period);
            asm("or outb, %[mask]\n\t"
                :
                : [mask] "r" (mask));
            waitx(period);
        }
    }
    
    int main() {
        unsigned int p = 24;
        while(true) {
            blink(num, p);
            p++;
            if(p>31)
                p = 24;
        }
    }
    

    Build/run steps
    propeller-elf-as crti.S -o crti.o
    propeller-elf-g++ test.cpp -c -O2
    propeller-elf-ld crti.o test.o -o test
    /loadp2/build/loadp2 -CHIP -v -p /dev/ttyUSB0 test
    

    Also here's the default linker script:
    /* Default linker script, for normal executables */
    /* Copyright (C) 2014-2019 Free Software Foundation, Inc.
       Copying and distribution of this script, with or without modification,
       are permitted in any medium without royalty provided the copyright
       notice and this notice are preserved.  */
    OUTPUT_FORMAT("elf32-littlepropeller")
    OUTPUT_ARCH(propeller)
    MEMORY
    {
      cogram : org = 0, l = 4 * 0x1EF
      lutram : org = 0x800, l = 4 * 0x200
      hubram : org = 0x0, l = 512K
    }
    PHDRS
    {
      headers PT_PHDR ;
      text PT_LOAD ;
    }
    SECTIONS
    {
      . = SIZEOF_HEADERS ;
      .data :
      {
        *(.boot)
        *(.cogram)
        . = 0x1000 ;
        *(.hubram)
      } >hubram :text
    }
    
    Very nice work! Parallax is lucky to have you working on this. Have you been in touch with Ken Gracey or Jeff Martin? I'm sure they will be excited about your progress.

  • @rogloh Oh boy, I've seen that bug before and I thought I'd fixed it. You're on the correct branch. I may have to re-write a small piece of the assembler to fix this. Weirdly it behaves on my machine.

    @David Betz I haven't reached out but they're probably aware. This is mostly a hobby project for me, but it's fun to be able to share something useful.

    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • ntosme2 wrote: »
    @David Betz I haven't reached out but they're probably aware. This is mostly a hobby project for me, but it's fun to be able to share something useful.
    Well, your hobby project is making great progress and will likely be quite useful to the P2 community as are Eric Smith's Fastspin efforts. Parallax is lucky to have some great people volunteering their time.
  • ntosme2 wrote: »
    @David Betz I haven't reached out but they're probably aware. This is mostly a hobby project for me, but it's fun to be able to share something useful.

    Whether you realize it or not, your "hobby project" is likely the best C++ compiler the P2 will ever have. Once PropGCC for P2 is at feature-parity with PropGCC for P1, I don't expect anyone will have the motivation necessary to port LLVM. And arguably, this may be the best C compiler for P2 as well (I'll certainly prefer it to FastSpin or Catalina, simply because it will integrate nicely with the rest of my tools) - but others may well disagree and I've no interest in finding out who is right :tongue:

    Anyway, don't kid yourself. You are creating something that will be useful for the entire Parallax community for the next decade most likely. No pressure or anything..... :smiley:
    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: https://ci.zemon.name?guest=1
  • Having both Hubexec and an industry standard C/C++ compiler finally working together will be a very powerful combination for the P2 and will unlock a lot of potential.
  • ntosme2ntosme2 Posts: 32
    edited 2019-09-27 - 21:29:47
    Can someone help me understand what I'm doing wrong here? Here's a simple example that should alternate blinking LED 56 and 63 by calling functions using a stack at ptra = 0x1044 via calla/reta. Instead it just appears to repeatedly call "_blink56".

    A few posibilities:
    1. I'm misusderstanding how these instructions should work
    2. The bits aren't being assembled correctly

    blink.s
        .section    ".boot"
    _start:
        hubset _clkmode
        waitx   ##200000
        or _clkmode, #3
        hubset _clkmode
        loc ptra, #_stack
        jmp #_main
    
        //  PLL on   div 0+1  mul 7+1    div 2    drive  RCFAST
        // (1<<24) + (0<<18) + (7<<8) + (0<<4) + (2<<2) + (0)
    _clkmode:
        .long 0x1000708
    
        .section    ".cogram"
    p56:
        .long 0x1000000
    p63:
        .long 0x80000000
    t:  .long 40000000
    pin:
        .long 24
    
        .section    ".hubram"
        .global _main
    _blink56:
        andn outb, p56
        waitx t
        or outb, p56
        waitx t
        reta
    _blink63:
        andn outb, p63
        waitx t
        or outb, p63
        waitx t
        reta
    _main:
        or outb, p56
        or dirb, p56
        or outb, p63
        or dirb, p63
    _loop:
        calla #_blink56
        calla #_blink63
        jmp #_loop
    
    _stack:
        .zero 4*100
    

    generated machine code
    Contents of section .data:
     0000 000e60fd 860180ff 1f8062fd 030e44f5  ..`.......b...D.
     0010 000e60fd 4410c0fe 281080fd 08070001  ..`.D...(.......
     0020 00000001 00000080 005a6202 18000000  .........Zb.....
     0030 00000000 00000000 00000000 00000000  ................
     <lots of 00000000>
     0ff0 00000000 00000000 00000000 00000000  ................
     1000 08fa23f5 1f1460fd 08fa43f5 1f1460fd  ..#...`...C...`.
     1010 2e0060fd 09fa23f5 1f1460fd 09fa43f5  ..`...#...`...C.
     1020 1f1460fd 2e0060fd 08fa43f5 08f643f5  ..`...`...C...C.
     1030 09fa43f5 09f643f5 0010c0fd 1410c0fd  ..C...C.........
     1040 381080fd 00000000 00000000 00000000  8............... {
     1050 00000000 00000000 00000000 00000000  ................
     1060 00000000 00000000 00000000 00000000  ................
     1070 00000000 00000000 00000000 00000000  ................
     1080 00000000 00000000 00000000 00000000  ................
     1090 00000000 00000000 00000000 00000000  ................
     10a0 00000000 00000000 00000000 00000000  ................
     10b0 00000000 00000000 00000000 00000000  ................
     10c0 00000000 00000000 00000000 00000000  ................
     10d0 00000000 00000000 00000000 00000000  ................
     10e0 00000000 00000000 00000000 00000000  ................
     10f0 00000000 00000000 00000000 00000000  ................
     1100 00000000 00000000 00000000 00000000  ................
     1110 00000000 00000000 00000000 00000000  ................
     1120 00000000 00000000 00000000 00000000  ................
     1130 00000000 00000000 00000000 00000000  ................
     1140 00000000 00000000 00000000 00000000  ................
     1150 00000000 00000000 00000000 00000000  ................
     1160 00000000 00000000 00000000 00000000  ................
     1170 00000000 00000000 00000000 00000000  ................
     1180 00000000 00000000 00000000 00000000  ................
     1190 00000000 00000000 00000000 00000000  ................
     11a0 00000000 00000000 00000000 00000000  ................
     11b0 00000000 00000000 00000000 00000000  ................
     11c0 00000000 00000000 00000000 00000000  ................
     11d0 00000000                             .... }
    

    *** note the above dump is unfortunately in little-endian and kinda gross to parse; here's a python snippet I've been using
    import struct
    
    insn = int('0x' + $ARGS[1], 16)
    insn = struct.unpack("<I", struct.pack(">I", insn))[0]
    print('insn', hex(insn))
    print(bin((insn>>28) & 0xF)[2:], bin((insn>>21) & 0x7F)[2:], bin((insn>>18) & 0x7)[2:], (insn>>9) & 0x1FF, insn & 0x1FF)
    
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • Does .zero in the stack need a "long" keyword?
    Prop Info and Apps: http://www.rayslogic.com/
  • @ntosme2 you may wish to use a disassembler that returns your binary back into assembly instructions to see what it did and make sure it did what you expected. A useful one has already been written by Dave Hein in his gcc work.

    https://github.com/davehein/p2gcc/tree/master/util

  • Dave HeinDave Hein Posts: 5,948
    edited 2019-09-28 - 02:47:55
    It appears that RETA isn't encoded correctly. Bit 18 needs to be set, otherwise it is interpreted as a CALLA.

    EDIT: Here's the disassembled output from p2dump
    1000 f523fa08              andn    $1fd, 8
    1004 fd60141f              waitx   $a
    1008 f543fa08              or      $1fd, 8
    100c fd60141f              waitx   $a
    1010 fd60002e              calla   0
    1014 f523fa09              andn    $1fd, 9
    1018 fd60141f              waitx   $a
    101c f543fa09              or      $1fd, 9
    1020 fd60141f              waitx   $a
    1024 fd60002e              calla   0
    1028 f543fa08              or      $1fd, 8
    102c f543f608              or      $1fb, 8
    1030 f543fa09              or      $1fd, 9
    1034 f543f609              or      $1fb, 9
    1038 fdc01000              calla   #\$1000
    103c fdc01014              calla   #\$1014
    1040 fd801038              jmp     #\$1038
    
  • Dave Hein wrote: »
    It appears that RETA isn't encoded correctly. Bit 18 needs to be set, otherwise it is interpreted as a CALLA.
    Thank you!! I've been staring at that for longer than I'd like to admit. Now I can test gcc function prologues/epilogues.
    Rayman wrote: »
    Does .zero in the stack need a "long" keyword?
    With GAS, ".zero 4" is equivalent to ".long x" except it doesn't get initialazed.
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
  • ntosme2 wrote: »
    Now I can test gcc function prologues/epilogues.
    Cool. When you do get to that, I've found there is scope there to include P2 specific optimizations using setq burst transfers to/from the stack. Though best just get it working first, then try to optimize.
  • Ok I finally had some time to poke at this more. There were several bugs/typos in GAS that are fixed and it in most cases generates binaries that dump correctly with p2dump. Most common instructions are supported. I need to refactor GAS because I realize I over-complicated things a bit, at which point all instructions will be supported.

    Now I have a much better grasp of gcc's handling of stack/frame pointers (ptra/ptrb in this case) and I fixed a few related lines of code.

    The following will now compile and run in both -O0 and -O2 optimization with the newest commits in git.

    crti.S
        .file       "crti.S"
        .section    ".boot"
        .global _start
    _start:
        rdlong _tmpmode, ##__clkmode
        hubset _tmpmode
        waitx   ##200000
        or _tmpmode, #3
        hubset _tmpmode
        wrlong _tmpmode, ##__clkmode
        loc ptra, #__stack
        jmp #_main
        .global _tmpmode
    _tmpmode:
        .long 0
    

    test.cpp - cycle through LEDs [56..63] repeatedly
    unsigned int _clkmode = 0x1000708;
    unsigned int _stack[100];
    
    void nextPin(unsigned int* pin) {
        unsigned int p = *pin;
        p++;
        if(p > 31)
            p = 24;
        *pin = p;
    }
    
    void blink(unsigned int period, unsigned int mask) {
        asm("or dirb, %[mask]\n\t"
            "andn outb, %[mask]\n\t"
            "waitx %[period]\n\t"
            "or outb, %[mask]\n\t"
            :
            : [period] "r" (period),
              [mask] "r" (mask));
    }
    
    int main() {
        unsigned int pin = 24;
        unsigned int period = 10000000;
        unsigned int mask;
    
        while(true) {
            mask = 1<<pin;
            blink(period, mask);
            nextPin(&pin);
        }
    }
    

    compile/run:
    propeller-elf-as crti.S -o crti.o
    propeller-elf-g++ test.cpp -S -O2
    propeller-elf-ld crti.o test.o -o test
    ./loadp2/build/loadp2 -SINGLE test
    

    @rogloh let me know if you're still seeing that assembler bug; I haven't been able to replicate it again
    - Brian
    P2 GCC 9.1 alpha - instructions to download and compile
Sign In or Register to comment.