From mboxrd@z Thu Jan 1 00:00:00 1970 X-Received: by 2002:ac8:4f54:0:b0:419:57a3:e0ab with SMTP id i20-20020ac84f54000000b0041957a3e0abmr49707qtw.4.1700816979197; Fri, 24 Nov 2023 01:09:39 -0800 (PST) X-Received: by 2002:a05:6a00:1952:b0:6c6:af58:ca06 with SMTP id s18-20020a056a00195200b006c6af58ca06mr553992pfk.1.1700816978788; Fri, 24 Nov 2023 01:09:38 -0800 (PST) Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!eternal-september.org!border-1.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 24 Nov 2023 01:09:38 -0800 (PST) In-Reply-To: Injection-Info: google-groups.googlegroups.com; posting-host=2a02:1210:1c95:d400:f5c5:84e9:ed7c:a456; posting-account=DQbqYQoAAACn8hHn2LmG2aF7Mhbxl_Lf NNTP-Posting-Host: 2a02:1210:1c95:d400:f5c5:84e9:ed7c:a456 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <05a0c608-0278-4cce-aa75-a89d2d807ef2n@googlegroups.com> Subject: Re: Using Log_Float in inline assembler for ARM From: Ahlan Marriott Injection-Date: Fri, 24 Nov 2023 09:09:39 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:65871 List-Id: On Sunday, November 19, 2023 at 1:22:22=E2=80=AFPM UTC+1, Ahlan Marriott wr= ote: > Hi,=20 > The following procedure Unbiased_Rounding for Float works as expected.=20 >=20 > function Unbiased_Rounding (X : Float) return Float is=20 > Y : Float;=20 > begin=20 > Asm ("vrintn.f32 %0,%1",=20 > Outputs =3D> Float'asm_output ("=3Dt", Y),=20 > Inputs =3D> Float'asm_input ("t", X));=20 > return Y;=20 > end Unbiased_Rounding;=20 >=20 > according to https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html= =20 > the constraint t means "VFP floating-point registers s0-s31. Used for 32 = bit values=E2=80=9D and the constraint w means "VFP floating-point register= s d0-d31 and the appropriate subset d0-d15 based on command line options. U= sed for 64 bit values only=E2=80=9D=20 >=20 > therefore we wrote our long_float version as=20 >=20 > function Unbiased_Rounding (X : Long_Float) return Long_Float is=20 > Y : Long_Float;=20 > begin=20 > Asm ("vrintn.f64 %0,%1",=20 > Outputs =3D> Long_Float'asm_output ("=3Dw", Y),=20 > Inputs =3D> Long_Float'asm_input ("w", X));=20 > return Y;=20 > end Unbiased_Rounding;=20 >=20 > however this fails to compile.=20 > GNAT 11.2/0-4 (Alire) complains=20 > Error: invalid instruction shape -- `vrintn.f64 s14,s14=E2=80=99=20 >=20 > presumably because the operands are S registers rather than double precis= ions D registers.=20 > Is this a bug or have we misunderstood something?=20 >=20 > Best wishes,=20 > Ahlan The solution is to use %P to access the parameters constrained using =E2=80= =9Cw=E2=80=9D Try as I might I can=E2=80=99t find this wonderful secret documented anywhe= re. I stumbled on the solution in the NXP forum where jingpan replied to a ques= tion 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 =E2=80=9Cw=E2=80=9D, ie D registers usi= ng %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 assembl= er. My GNAT Ada code to implement the Unbiased_Rounding attribute efficiently u= sing the VFLOATN instruction is therefore subtype T is Long_Float; function Unbiased_Rounding (X : T) return T is Y : T; begin Asm (=E2=80=9Cvrintn.f64 %P0,%P1=E2=80=9D, Outputs =3D> T=E2=80=99asm_output (=E2=80=9C=3Dw=E2=80=9D, Y), Inputs =3D> T=E2=80=99asm_input (=E2=80=9Cw=E2=80=9D, X)); return Y; end Unbiased_Rounding; Of course we wouldn=E2=80=99t 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