simple assembly help

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi freaks, I'm not very good at assembly.  I need to load the floating point execution register with a value.  Cn you help? I have the following but it is not working...

 

unsigned int load = 0x40000000;

	asm volatile ("MOV R0, %[execution_reg]" :: [execution_reg] "r" (load));
	asm volatile ("VMSR FPEXC, R0");

Thanks Freaks...

 

Wm.

This topic has a solution.
Last Edited: Tue. Jul 7, 2020 - 03:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
I'm not very good at assembly

So why do it, then?

 

It's unlikely that a "not very good" assembler programmer is going to outperform a 'C' compiler.

 

So why not let the compiler show you how?

 

Write a simple 'C' function which does what you want, then examine the assembler that the compiler produces for that ...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Someone must have done this before? Maybe just google "VMSR FPEXC".

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This might be a solution... https://developer.arm.com/documentation/ddi0449/b/programmers-model/about-the-programmers-model/enabling-vfp-support

 

I'll post tomorrow the results...

 

EDITED:

Okay lads, when I compile the following assembly instruction from the link above I get a garbage error.

ORR r0, r0, #2_11<<10 ;

#2_11 is causing the error but this is how it is listed.

 

Any advise anyone?

Last Edited: Mon. Jul 6, 2020 - 03:08 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, I've the code for initialising the FPU, see below:

	/* Enable fpu */
	/* Grant non secure access for CP10 and CP11 */
	asm volatile (
			"mrc	p15, 0, r0, c1, c1, 2\n\t"
			"orr    r0, r0, #3 << 10\n\t"
			"mcr	p15, 0, r0, c1, c1, 2\n\t"

			"ldr	r0, =(0xF << 20)\n\t"
			"mcr	p15, 0, r0, c1, c0, 2\n\t"

			"mov	r1, #0x40000000\n\t"
			"vmsr	FPEXC, r1");

So when I first load a task it still fails after executing the above piece of code.

 

:(

 

 

EDITED: Got it working, system needed to be in system mode.

Thanks peeps!

Last Edited: Tue. Jul 7, 2020 - 03:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, last problem is after a context switch the task fails on floating point operations?  The context switch is as follows:

__attribute__((naked))void context_switch (void){

	#define OS_CPU_ARM_CONTROL_THUMB EQU  0x20

	__asm__ __volatile__(
			"STMFD   SP!, {LR}\n\t"			// SAVE CURRENT TASK'S CONTEXT:
			"STMFD   SP!, {LR}\n\t"			// Push return address,
			"STMFD   SP!, {R0-R12}\n\t"		// Push registers,

			"MRS     R0, CPSR\n\t"			// Push current CPSR,

			"TST     LR, #1\n\t"			// See if called from Thumb mode,
			"ORRNE   R0, R0, #0x20\n\t"		// OS_CPU_ARM_CONTROL_THUMB

			"STMFD   SP!, {R0}\n\t"


			"VMRS    r0, FPSCR\n\t"			//     ... Save current FPSCR
			"PUSH    {r0}\n\t"
			"FSTMDBS SP!, {S0-S31}\n\t"		//     ... Save general-purpose floating-point registers.
			"VMRS    r0, FPEXC\n\t"			//     ... Save Floating point exception register.
			"PUSH    {r0}\n\t"


			"CLREX\n\t"						// Clear exclusive monitor.



			"MOV     R0, %[current_tcb]\n\t"	// core_executing_task->StkPtr = SP;
			"LDR     R1, [R0]\n\t"
			"STR     SP, [R1]\n\t"

			"MOV     R0, %[current_tcb]\n\t"
			"MOV     R1, %[tcb_new]\n\t"
			"LDR     R2, [R1]\n\t"
			"STR     R2, [R0]\n\t"

			"LDR     SP, [R2]\n\t"

			"POP     {r0}\n\t"					// Pop new task's FPEXC
			"VMSR    FPEXC, r0\n\t"

			"FLDMIAS SP!, {S0-S31}\n\t"			//    ... Pop new task's General-Purpose floating point registers.
			"POP     {r0}\n\t"
			"VMSR    FPSCR, r0\n\t"				//    ... Pop new task's FPSCR.



			"LDMFD   SP!, {R0}\n\t"
//			"orr     r0, r0, #0x1f\n\t"

			"MSR     SPSR_cxsf, R0\n\t"

			"LDMFD   SP!, {R0-R12, LR, PC}" :: [current_tcb] "r" (&core_executing_task), [tcb_new] "r" (&OSTCBHighRdy));
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:

Okay, last problem is after a context switch the task fails on floating point operations?  The context switch is as follows:

			"LDMFD   SP!, {R0}\n\t"
//			"orr     r0, r0, #0x1f\n\t"

			"MSR     SPSR_cxsf, R0\n\t"

			"LDMFD   SP!, {R0-R12, LR, PC}" :: [current_tcb] "r" (&core_executing_task), [tcb_new] "r" (&OSTCBHighRdy));
}

 

Pretty sure those last two "LDMFD" need to be "LDMIA".

 

Steve

Maverick Embedded Technologies Ltd. Home of Maven and wAVR.

Maven: WiFi ARM Cortex-M Debugger/Programmer

wAVR: WiFi AVR ISP/PDI/uPDI Programmer

https://www.maverick-embedded.co...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm actually looking at the:

SPSR_cxsf

it should be CPSR_cxsf for system mode.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tested the context in isolation, it works.  That only leaves the interrupt context switch.  I'll look into it on Friday.  For now, I'm going on the rip.  

 

Slán

 

Wm.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, tested everything.  It appears that when an interrupt occurs the status register (I think) is being trashed when in system mode.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Found it.   The Stack pointers are properly initialized for each execution mode.

 

Slán Guys.