How to write assembly function for xCORE-200

If you have a simple question and just want an answer.
martinh
Member++
Posts: 19
Joined: Thu Oct 01, 2015 10:55 am

How to write assembly function for xCORE-200

Post by martinh »

Hi,
 
I am evaluating the xCORE-200 eXplorer board using xTIMEcomposer (Version: Community_14.1.0 (build 17291, Jul-23-2015) ),
 
For performance reasons some assembler instructions need to be modified.
What needs to be optimized is this loop:
  for(i=0; i<Anz; i++) {
      pPing <: ValTable[ui++];  // output 16-bit-words
  } 
 
According to 'Inline-Assembly_X1969A.pdf' jumps from one asm statement to another are not supported when inline assembly is used.
 
The question is how to write an assembly function that does the job?
The examples I found in asm_examples.zip don't seem to work.
For instance // is not accepted, neither is .size.
Some more instructions that are not accepted by the compiler are these:
   subi r1, r1, 1        Unknown opcode 'subi'
   brbt r6, 10            Error: A00004 Unknown opcode 'brbt'
   add (2rus) r3, r11, 0x0   Error: A00001 Unreconciled syntax error
 
 
So far the following asm file is accepted by the compiler:
  .align 4
  .globl DoPingAsm
  .type DoPingAsm, @function
  .cc_top DoPingAsm.function
 
  #*********************************************************************************
  # Fkt.: DoPingAsm() ( called in DoPing() )
  # Ausgabe von 16-Bit-Werten aus einem Array an den Port pPing
  # Par.: r0  - StartAdd, Startadresse des Arrays
  #  r1  - Anz, Anzahl der auszugebenden 16-Bit-Werte
  #       r2  - Port
  # used: r3  - Cnt, zählt hoch, initialize to 0
  #       r4  - inc-Wert, always 1
  # r5  - Val, 16-Bit-Wert aus ValTable[]
  # r6  - becomes 0, when Cnt>=Anz
  #*********************************************************************************
 
  DoPingAsm:
    entsp 0
    ldc  r3, 0 # Count = 0
    ldc   r4, 1 # 4 Bytes,    incr-Wert
#---------------------------------------
  Loop1:
    ld16s r5, r0[r3]   # Val = ValTable[Count]
    out res[r2], r5   # pPing <: Val
    add r3, r3, r4 # Count = Count + 1
    lsu r6, r3, r1 # r6 = 0, wenn Cnt>=Anz
    bt r6, Loop1
 
    retsp0
 
  #.size DoPingAsm, -DoPingAsm    would cause 'Error: A00028 Non-constant expression cannot be reduced to linker'expressions.
  .cc_bottom DoPingAsm.function
 
 
 
What can be seen in the disassembly window is this:
 
          DoPingAsm:
  000401e8:   entsp (u6)      0x0
  25               ldc     r3, 0      # Count = 0
  000401ea:   ldc (ru6)       r3, 0x0
  26               ldc   r4, 1        # 4 Bytes,    incr-Wert
  000401ec:   ldc (ru6)       r4, 0x1
  29                ld16s r5, r0[r3]    # Val = ValTable[Count]
          Loop1:
  000401ee:   ld16s (3r)      r5, r0[r3]
  30               out res[r2], r5     # pPing <: Val
  000401f0:   out (r2r)       res[r2], r5 3  1          add r3, r3, r4      # Count = Count + 1
  000401f2:   add (3r)        r3, r3, r4
  32               lsu r6, r3, r1      # r6 = 0, wenn Cnt>=Anz
  000401f4:   lsu (3r)        r6, r3, r1
  33               bt r6, Loop1
  000401f6:   bt (ru6)        r6, -0x5
  35               retsp 0
  000401f8:   retsp (u6)      0x0
  000401fa:   stw (2rus)      r0, r0[0x0]
  pStartPinging.ctor:
                      and so on .....
At runtime 'xrun: Program received signal ET_ILLEGAL_INSTRUCTION, Unable to decode instruction.'
is displayed for the line 'ld16s r5, r0[r3]  # Val = ValTable[Count]'
 
 
Does anybody know of an assembly example that runs with XCORE-200 or a good manual with examples?
Which instruction set can be used for xCORE-200?
Is there no need to push or pop the registers used by the assembly function?
Any hints regarding that tiny assembly function (and it's errors) are very welcome.
 
Thank you.
 
Regards,
Martin H.
martinh
Member++
Posts: 19
Joined: Thu Oct 01, 2015 10:55 am

Post by martinh »

Hi,

I found some good explanations in xTIMEcomposer-User-Guide_X3766D.pdf ("42Make assembly programs compatible with the XMOS XS1 ABI") that helped me solve the problem.
Remaining question:
Which assemblers can be used? In the makefile that entry is empty. Which one is the default assembler and which is the other one that is
suitable?
Does anybody know?
Thank you.

Regards,
Martin H.

User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

Hello Martin. This website and also xmos.com offers assorted posts and documentation on how to program in assembly language. You can insert inside of your .xc files with inline assembly code or if you prefer, save the assembly language coded routines inside of a .s file. The assembler is built-in the same xTimeComposer toolchain.

Do review some of the posted code on github like the SDRAM BURST code which interfaces between C calling to/from assembler. Using software IP, the XMOS CPU is interfacing with SDRAM and performs the refresh, etc. with a target SDRAM device:

https://github.com/xcore/sc_sdram_burst

Note the .s suffixed files which offer the assembler code for lower latency communications with the SDRAM. Other projects worth a review include 10/100 Mbps Ethernet IP, Gigabit Ethernet IP (for use with XCORE-200 board).

Then there is this totally insane (in a good way) project based on software IP to mimic the ISA bus and Floppy Drive controller - all in software:

http://www.xcore.com/projects/isaflop

 

These links should also help:

https://www.xmos.com/published/xas_en

https://www.xmos.com/search/content?term=assembler

https://www.xmos.com/search/content?term=assembly

https://www.xmos.com/search/content?term=xmos+makefiles

http://www.xcore.com/blog/vinith/post/asm-examples