Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

How to change the len in FPSCR? [SOLVED]

Sat May 01, 2021 9:32 pm

Hi iam trying to modify the len in the FPSCR register, but i can't write it. Here is my code:

Code: Select all

/*Comment*/
.text
.balign 4
.global main
main:
    mov r0, #0x03
    mov r0, r0, LSL #16
    fmrx r1, fpscr
    orr r1, r1, r0
    fmxr fpscr, r1
    fmrx r1, fpscr
    mov r0,r1, LSR #16
    bx lr
Returns error 0 and it should be 3...

if you want to use printf:

Code: Select all

/*Comment*/
.data
.balign 4       
   string: .asciz "FPSCR: %d\n" 
.text
.balign 4
.global main
.extern printf
main:
	push {lr}
	mov r0, #0x03
	mov r0, r0, LSL #16
	fmrx r1, fpscr
	orr r1, r1, r0
	fmxr fpscr, r1
	ldr r0, =string
	fmrx r1, fpscr
	bl printf
	pop {lr}
	bx lr
Last edited by Jabon on Sun May 02, 2021 5:16 pm, edited 2 times in total.

User avatar
jahboater
Posts: 7033
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: How to change the len in FPSCR?

Sat May 01, 2021 9:44 pm

I used:

vmrs r,fpscr

and

vmsr fpscr,r

last time I did something like this (years ago).

Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

Re: How to change the len in FPSCR?

Sat May 01, 2021 9:52 pm

jahboater wrote:
Sat May 01, 2021 9:44 pm
I used:
vmrs r,fpscr
and
vmsr fpscr,r
Changed fmrx for vmrs and fmxr for vmsr still cant write the fpscr... maybe requires supervisor mode? but the guide i was reading https://thinkingeek.com/arm-assembler-raspberry-pi/ didn't warn about that...

Thanks anyway ;)

User avatar
jahboater
Posts: 7033
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: How to change the len in FPSCR?

Sat May 01, 2021 9:57 pm

Jabon wrote:
Sat May 01, 2021 9:52 pm
Changed fmrx for vmrs and fmxr for vmsr still cant write the fpscr... maybe requires supervisor mode?
This trivial code works and does not require any special priviledge:

Code: Select all

/*
 *  The value zero resets everything to suitable defaults and at the
 *  same time clears all cumulative exception bits and status flags.
 */
#define hw_defaults() asm( "vmsr fpscr,%0" :: "r" (0) )
Just tried it on my Pi4.

Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

Re: How to change the len in FPSCR?

Sat May 01, 2021 10:06 pm

jahboater wrote:
Sat May 01, 2021 9:57 pm
...Just tried it on my Pi4.
Dunno, it seems to be cleared by default, my problem is that i can't set bit 16,17 and 18 (len). If you have time to spare mind trying to set a value and reading it after?
is bare metal?
I think so, yet i try it with c and asm() function and still i can't change the fpscr.

That code is from an .s file "$ as -mfpu=vfpv2 -o test.o test.s" "$gcc -o test test.o" run "./test | echo $?"

User avatar
jahboater
Posts: 7033
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: How to change the len in FPSCR?

Sat May 01, 2021 10:37 pm

Hmm, neither can I.

Code: Select all

#include <stdio.h>
#include <assert.h>

#define asm __asm__ __volatile__

static void
set( const int len )
{
  assert( len < 8 );
  asm( "vmrs r0,fpscr; orr r0,r0,%0,lsl #16; vmsr fpscr,r0" :: "r" (len) : "r0" );
}

static int
get( void )
{
  int len;
  asm( "vmrs r0,fpscr; mov %0,r0,lsr #16" : "=r" (len) :: "r0" );
  return len;
}

int
main( void )
{
  printf( "len defaults to %d\n", get() );
  set(3);
  printf( "len now %d\n", get() );
}
Sorry, I fear I cannot help.
My only suggestion is a careful read of the ARM ARM :(

Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

Re: How to change the len in FPSCR?

Sat May 01, 2021 11:02 pm

jahboater wrote:
Sat May 01, 2021 10:37 pm
Hmm, neither can I.
My only suggestion is a careful read of the ARM ARM :(
No worries, i feel a bit less dumb knowing that I am not the only one :)
Maybe some service or display driver is using/blocking it?

From the reference manual:
When an FMXR or FMRX instruction is executed to access the FPSCR, the register transfer is delayed until:
• all floating-point operations in progress have determined whether they are going to generate an
exception
• any trapped exception handling or other software processing of floating-point operations in progress
has completed
• all effects of floating-point operations in progress on system register contents (such as setting
cumulative exception flags for untrapped exceptions) have occurred
• all floating-point operations in progress are no longer affected by changes to system register contents
(for example, by rounding mode or Flush-to-zero mode changes).

LdB
Posts: 1689
Joined: Wed Dec 07, 2016 2:29 pm

Re: How to change the len in FPSCR?

Sun May 02, 2021 6:51 am

If this is baremetal does your boot code turn the FPU on?

It isn't on by default in 32bit mode :-)

Code: Select all

	mrc p15, 0, r0, c1, c0, #2							// R0 = Access Control Register
	orr r0, #(0x300000 + 0xC00000)						// Enable Single & Double Precision
	mcr p15,0,r0,c1,c0, #2								// Access Control Register = R0
	mov r0, #0x40000000									// R0 = Enable VFP
	vmsr fpexc, r0										// FPEXC = R0

Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

Re: How to change the len in FPSCR?

Sun May 02, 2021 9:20 am

LdB wrote:
Sun May 02, 2021 6:51 am
If this is baremetal does your boot code turn the FPU on?
It isn't on by default in 32bit mode :-)
Not right now. I am testing asm routines using raspbian-buster kernel 5.10.17-v7+ (pi3b+,pi3a+,pi0w). The fpu is on, its usable in scalar mode (= 'len=1' o '000').
Weird enough, I checked PiFox (a baremetal project on github) and they use ARMv6+VFP1 (i suppose they meant VFPv2, since VFPv1 is obsolete) and all their math ops (math.s) like matrix multiplication are in scalar mode...

Still good to know that FPU is off by default :)

LdB
Posts: 1689
Joined: Wed Dec 07, 2016 2:29 pm

Re: How to change the len in FPSCR?

Sun May 02, 2021 9:59 am

Usually same deal in user-space FPU mode would typically be disabled (unless Raspbian is unusal).. you would need to install a device driver.

You need to remember linux is doing context switches on which the FPU is part of the saved context registers.
So different tasks will have the FPU on or off and it goes on/off with the switch.
By default a user-space program would almost always be created with FPU off because many would not need it and it would save context register pushes and pops.

Even in a device driver you need to use kernel_fpu_begin() / kernel_fpu_end()

You have some reading to do and check how raspbian uses the FPU and accessibility from where and any pre-requist calls.

Jabon
Posts: 10
Joined: Sun Apr 04, 2021 11:07 pm

Re: How to change the len in FPSCR?

Sun May 02, 2021 1:25 pm

LdB wrote:
Sun May 02, 2021 9:59 am
Usually same deal in user-space FPU mode would typically be disabled (unless Raspbian is unusal).. you would need to install a device driver.
...
Indeed i must do a lot of reading... :cry:

:idea: I found the solution... and its not a kernel or Raspbian problem.
I will try to summarize:
1- VFPU is enable by default in raspbian and users can access without problem (default mode is scalar, which means no SIMD - single instruction multiple data).
2- PI's like 2, 3 and 4 ARM CPU use NEON for vfp (vector floating point which allows SIMD), yet they still have the VFPU (v3/v4 compatibility reasons i guess?) but only for scalar mode (yeah i should check the cpu's datasheet to confirm this)
3-PI's like 1 and zero ARM CPU doesn't have NEON and since both use an ARM1176JZF-S which has a VPFU v2, it has to support vfp... and guess what? it does i just tried the code in my pi zero and it works.

Conclusion for vfp:
-Pi 0/1 set len and stride in fpscr.
-Pi 2/3/4 use neon instructions.

So it goes to trash my idea of writing vfp code (SIMD) for pi 0 and use it in both my pi 0 and 3.

Return to “Bare metal, Assembly language”