* Using Log_Float in inline assembler for ARM
@ 2023-11-19 12:22 Ahlan Marriott
2023-11-24 9:09 ` Ahlan Marriott
0 siblings, 1 reply; 3+ messages in thread
From: Ahlan Marriott @ 2023-11-19 12:22 UTC (permalink / raw)
Hi,
The following procedure Unbiased_Rounding for Float works as expected.
function Unbiased_Rounding (X : Float) return Float is
Y : Float;
begin
Asm ("vrintn.f32 %0,%1",
Outputs => Float'asm_output ("=t", Y),
Inputs => Float'asm_input ("t", X));
return Y;
end Unbiased_Rounding;
according to https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
the constraint t means "VFP floating-point registers s0-s31. Used for 32 bit values” and the constraint w means "VFP floating-point registers d0-d31 and the appropriate subset d0-d15 based on command line options. Used for 64 bit values only”
therefore we wrote our long_float version as
function Unbiased_Rounding (X : Long_Float) return Long_Float is
Y : Long_Float;
begin
Asm ("vrintn.f64 %0,%1",
Outputs => Long_Float'asm_output ("=w", Y),
Inputs => Long_Float'asm_input ("w", X));
return Y;
end Unbiased_Rounding;
however this fails to compile.
GNAT 11.2/0-4 (Alire) complains
Error: invalid instruction shape -- `vrintn.f64 s14,s14’
presumably because the operands are S registers rather than double precisions D registers.
Is this a bug or have we misunderstood something?
Best wishes,
Ahlan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Using Log_Float in inline assembler for ARM
2023-11-19 12:22 Using Log_Float in inline assembler for ARM Ahlan Marriott
@ 2023-11-24 9:09 ` Ahlan Marriott
2023-11-24 10:43 ` Jeffrey R.Carter
0 siblings, 1 reply; 3+ messages in thread
From: Ahlan Marriott @ 2023-11-24 9:09 UTC (permalink / raw)
On Sunday, November 19, 2023 at 1:22:22 PM UTC+1, Ahlan Marriott wrote:
> Hi,
> The following procedure Unbiased_Rounding for Float works as expected.
>
> function Unbiased_Rounding (X : Float) return Float is
> Y : Float;
> begin
> Asm ("vrintn.f32 %0,%1",
> Outputs => Float'asm_output ("=t", Y),
> Inputs => Float'asm_input ("t", X));
> return Y;
> end Unbiased_Rounding;
>
> according to https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
> the constraint t means "VFP floating-point registers s0-s31. Used for 32 bit values” and the constraint w means "VFP floating-point registers d0-d31 and the appropriate subset d0-d15 based on command line options. Used for 64 bit values only”
>
> therefore we wrote our long_float version as
>
> function Unbiased_Rounding (X : Long_Float) return Long_Float is
> Y : Long_Float;
> begin
> Asm ("vrintn.f64 %0,%1",
> Outputs => Long_Float'asm_output ("=w", Y),
> Inputs => Long_Float'asm_input ("w", X));
> return Y;
> end Unbiased_Rounding;
>
> however this fails to compile.
> GNAT 11.2/0-4 (Alire) complains
> Error: invalid instruction shape -- `vrintn.f64 s14,s14’
>
> presumably because the operands are S registers rather than double precisions D registers.
> Is this a bug or have we misunderstood something?
>
> Best wishes,
> Ahlan
The solution is to use %P to access the parameters constrained using “w”
Try as I might I can’t find this wonderful secret documented anywhere.
I stumbled on the solution in the NXP forum where jingpan replied to a question on how to use the ARM VSQRT instruction for double.
When using the inline assembler from C and using named parameters you need to access parameters constrained by “w”, ie D registers using %P[name] rather than %[name] as everywhere else.
Using positional parameters one needs to use %Pn rather than %n
And yes it must be a capital P
I fail to understand why one needs to do this because surely the assembler already knows that the parameter has been constrained to a D register - but I guess this is just an additional quirk to an already very quirky assembler.
My GNAT Ada code to implement the Unbiased_Rounding attribute efficiently using the VFLOATN instruction is therefore
subtype T is Long_Float;
function Unbiased_Rounding (X : T) return T is
Y : T;
begin
Asm (“vrintn.f64 %P0,%P1”,
Outputs => T’asm_output (“=w”, Y),
Inputs => T’asm_input (“w”, X));
return Y;
end Unbiased_Rounding;
Of course we wouldn’t have to resort to assembler at all had there been a built-in intrinsic for VFLOATN as there is for all the other VFLOAT instructions. But I guess that is hoping for too much.
Best wishes and happy programming,
Ahlan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Using Log_Float in inline assembler for ARM
2023-11-24 9:09 ` Ahlan Marriott
@ 2023-11-24 10:43 ` Jeffrey R.Carter
0 siblings, 0 replies; 3+ messages in thread
From: Jeffrey R.Carter @ 2023-11-24 10:43 UTC (permalink / raw)
On 2023-11-24 10:09, Ahlan Marriott wrote:
>
> subtype T is Long_Float;
>
> function Unbiased_Rounding (X : T) return T is
> Y : T;
> begin
> Asm (“vrintn.f64 %P0,%P1”,
> Outputs => T’asm_output (“=w”, Y),
> Inputs => T’asm_input (“w”, X));
> return Y;
> end Unbiased_Rounding;
What do you get from T'Unbiased_Rounding?
--
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-11-24 10:43 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-19 12:22 Using Log_Float in inline assembler for ARM Ahlan Marriott
2023-11-24 9:09 ` Ahlan Marriott
2023-11-24 10:43 ` Jeffrey R.Carter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox