LADD and LSUB in XC ??

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

LADD and LSUB in XC ??

Post by lilltroll »

Below is built in functions that I have found, making it possible to acess special instructions in XC.

crc32 (unsigned &checksum, unsigned data, unsigned poly)
crc8shr (unsigned &checksum, unsigned data, unsigned poly)
lmul (unsigned a, unsigned b, unsigned c, unsigned d)
mac (unsigned a, unsigned b, unsigned c, unsigned d)
macs (signed a, signed b, signed c, unsigned d)
bitrev(unsigned x);
byterev(unsigned x);
clz(unsigned x);

But I have a need of acessing the instruction LongADD and LongSUB as well, is it possible from XC ??

Also is it possible to acess the MASK instructions MKMSK and MKMSKI from XC ?


Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

One way is of course to define a long long in C, and to call a function from XC.

Last time I had a function call from XC that handled port-com to a C-function inside a computational heavy loop I expected to get a terrible unefficient compiled code, but the code was brutal efficient - checking the ASM with XTA.

XC

Code: Select all

while(1)
{
Channel <: OUT
OUT=COMPUTE_in_C(IN);
Channel :> IN 
}
C

Code: Select all

int COMPUTE_in_C(IN)
{
// CALC something that is not supported in XC

return(OUT)
}
created something like

{fix everything with registers in a very smart way}
OUT res[r_a],r_x
some math using r_x directly as input
some math
some math putting the answer in r_y
IN r_y,res[r_b]
BRanch back to OUT

It used the registers in such a way that no mem-copy, stack or register moves happend at all :D
Probably not the most confused programmer anymore on the XCORE forum.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

There is no builtin for MKMSKI, but there isn't a need for one either - the XC compiler will automatically use it if it needs to load a constant of the correct form into a register.

You can target ladd, lsub and mkmsk using inline asm (supported in XC from 9.9 onwards). For example:

Code: Select all

{unsigned, unsigned} static inline ladd(unsigned a, unsigned b, unsigned carryin)
{
  unsigned result, carryout;
  asm("ladd %0, %1, %2, %3, %4" : "=r"(result), "=r"(carryout) : "r"(a), "r"(b), "r"(carryin));
  return { carryout, result };
}
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

richard wrote:There is no builtin for MKMSKI, but there isn't a need for one either - the XC compiler will automatically use it if it needs to load a constant of the correct form into a register.

You can target ladd, lsub and mkmsk using inline asm (supported in XC from 9.9 onwards). For example:

Code: Select all

{unsigned, unsigned} static inline ladd(unsigned a, unsigned b, unsigned carryin)
{
  unsigned result, carryout;
  asm("ladd %0, %1, %2, %3, %4" : "=r"(result), "=r"(carryout) : "r"(a), "r"(b), "r"(carryin));
  return { carryout, result };
}
Thats SUPER! :!:

Where can I read about the

Code: Select all

%0, %1, %2, %3, %4" : "=r"(result), "=r"(carryout) : "r"(a), "r"(b), "r"(carryin)
way to write code. Is it GCC standard or a XMOS special ??

/Never used GCC combined ASM before XMOS arived, but I have used GCC for ANSI C and ASM stand alone.
Probably not the most confused programmer anymore on the XCORE forum.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Inline assembly is documented in the "Inline Assembly" section of the following document.

http://www.xmos.com/published/xtools_en_ch19

The inline assembly support in the XC compiler is modelled on GCC's Extended Asm syntax. We currently support a subset of what is supported in GCC. For example early clobbers and tied operands are not yet implemented.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Consider this:

Code: Select all

		asm("ladd %0, %1, %2, %3, %4" : "=r"(carry), "=r"(y_l) : "r"(l), "r"(Z0_l), "r"(0));
		printf("%x + %x = %x carry=%x\n",l,Z0_l,y_l,carry);
Using the simulator I get this result:

Code: Select all

30000000 + 1 = 30000001 carry=0
The strange this is that at page 120 in the XS1 its written

"one destination register which is used to store the carry (e), and a destination register for the sum (d)."
LADD d, e, x, y, v

I have to change place on e and d!
Am I extra studid, or that is wrong here ?
Probably not the most confused programmer anymore on the XCORE forum.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

In the XS1 book destination and source operands are ordered according to the order in which they appear in the instruction encoding. For ladd, lsub this doesn't match the order operands appear in the assembly instruction (the two destination registers are swapped). This should be documented in the assembly language manual, but I notice the ordering given there is incorrect. This will be fixed in the next version of the assembly language documentation.
stefanharjes
Member
Posts: 13
Joined: Wed Jun 01, 2011 7:33 pm

Post by stefanharjes »

Hi all,

I just tried the inline asm function (with carryout and result exchanged) on my XC-2 hardware.

In my case the carryin is completely ignored,
carryin = 5000, 2147483655 + 2147483648 = 7, carryout = 1
is that only me?

So you can remove the carryin, when you have to do the high word addition after the ladd call anyhow.

Best

Stefan
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Only the least significant bit of the carry in is used. If implementing multiword arithmetic the carry in would normally be the carry out of a previous ladd and therefore guaranteed to be 0 or 1.
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

If you really want to do a widening add of three words, you can use LMUL
(with a multiplicand of 1).