Search code examples
assemblygnu-assemblersparcembedded-v8

GNU AS SPARC V8E partial WRPSR


The SPARC V8 Processor State Register (PSR) contains a bit to enable/disable traps (ET) as detailed in the SPARC Architecture Manual version 8 available at http://sparc.org/technical-documents/

Disabling traps is a non atomic operation as explicitly stated in the manual:

If traps are enabled (ET=1), care must be taken if software is to disable them (ET=0). Since the “RDPSR, WRPSR” sequence is interruptible — allowing the PSR to be changed between the two instructions — this sequence is not a reliable mechanism to disable traps.

Embedded Supplement to SPARC-V8 SPARC-V8E adds an partial WRPSR instruction to mitigate this:

When a WRPSR instruction with a non null RD is executed, only some fields of PSR are written rather than all the defined fields of PSR. The mapping “RD => fields” is tbd. However:

RD = 0 : all fields written (for compatibility)

RD = tbd : only ET is written.

The second point allows to overcome the explicitly stated weakness of V8 (programming note of the WRPSR instruction stated above).

I have a implementation on my desk supporting it, but I wonder how to make use of it, because, as far as I understand, the GNU Assembler (GAS) does not support this instruction. The only way I know to write an immediate or register value to %psr is with mov:

mov %g0, %psr / mov 0, %psr

By looking at the GNU binutils GAS sources, I understand that there is no syntax to specify the RD part of the instruction code, and therefore no way to atomically set ET=0 with GNU AS. Or do I miss something?

I noticed some -Av8plusX command line options in the GAS manual, but none of them seems related to V8E or partial WRPSR.

Is there any GAS syntax or other way to emit this instruction to the output? If not possible, what would I need to know to create a patch? How should the syntax look like?

Is there any compiler supporting partial WRPSR at all? I checked LLVM recently for SPARC support, but it was still experimental/incomplete.

Thanks.


Solution

  • In the meanwhile I learned that one can insert it directly into assembler code using a constant in place of the instruction, for example as below to disable traps:

    .word 0x83880000
    

    Note that if you use the partial wrpsr feature on a processor that doesn't have it then it will act as a normal wrpsr so you will need to be careful when moving software between systems.

    Credit: https://groups.yahoo.com/neo/groups/LEON_SPARC/conversations/topics/24733