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 ?
LADD and LSUB in XC ??
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
LADD and LSUB in XC ??
Probably not the most confused programmer anymore on the XCORE forum.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
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
C
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
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
}
Code: Select all
int COMPUTE_in_C(IN)
{
// CALC something that is not supported in XC
return(OUT)
}
{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.
-
- Respected Member
- Posts: 318
- Joined: Tue Dec 15, 2009 12:46 am
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:
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 };
}
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
Thats SUPER! :!: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 }; }
Where can I read about the
Code: Select all
%0, %1, %2, %3, %4" : "=r"(result), "=r"(carryout) : "r"(a), "r"(b), "r"(carryin)
/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.
-
- Respected Member
- Posts: 318
- Joined: Tue Dec 15, 2009 12:46 am
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.
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.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
Consider this:
Using the simulator I get this result:
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 ?
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);
Code: Select all
30000000 + 1 = 30000001 carry=0
"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.
-
- Respected Member
- Posts: 318
- Joined: Tue Dec 15, 2009 12:46 am
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.
-
- Member
- Posts: 13
- Joined: Wed Jun 01, 2011 7:33 pm
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,
So you can remove the carryin, when you have to do the high word addition after the ladd call anyhow.
Best
Stefan
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,
is that only me?carryin = 5000, 2147483655 + 2147483648 = 7, carryout = 1
So you can remove the carryin, when you have to do the high word addition after the ladd call anyhow.
Best
Stefan
-
- Respected Member
- Posts: 318
- Joined: Tue Dec 15, 2009 12:46 am
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.
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
If you really want to do a widening add of three words, you can use LMUL
(with a multiplicand of 1).
(with a multiplicand of 1).