OPENRISC Dependent Features
***************************

OpenRISC Syntax
===============

The assembler syntax follows the OpenRISC 1000 Architecture Manual.

Special Characters
------------------

A # character appearing anywhere on a line indicates the start of a comment that extends to the end of that line.

; can be used instead of a newline to separate statements.

Register Names
--------------

The OpenRISC register file contains 32 general pupose registers.

  * The 32 general purpose registers are referred to as rN.

  * The stack pointer register r1 can be referenced using the alias sp.

  * The frame pointer register r2 can be referenced using the alias fp.

  * The link register r9 can be referenced using the alias lr.

Floating point operations use the same general purpose registers.  The instructions lf.itof.s (single precision) and lf.itof.d (double precision) can be used to convert integer values to floating point. Likewise, instructions lf.ftoi.s (single precision) and lf.ftoi.d (double precision) can be used to convert floating point to integer.

OpenRISC also contains privileged special purpose registers (SPRs).  The SPRs are accessed using the l.mfspr and l.mtspr instructions.

Relocations
-----------

ELF relocations are available as defined in the OpenRISC architecture specification.

R_OR1K_HI_16_IN_INSN is obtained using hi and R_OR1K_LO_16_IN_INSN and R_OR1K_SLO16 are obtained using lo.  For signed offsets R_OR1K_AHI16 is obtained from ha.  For example:

     l.movhi r5, hi(symbol)
     l.ori   r5, r5, lo(symbol)

     l.movhi r5, ha(symbol)
     l.addi  r5, r5, lo(symbol)

These ``high'' mnemonics extract bits 31:16 of their operand, and the ``low'' mnemonics extract bits 15:0 of their operand.

The PC relative relocation R_OR1K_GOTPC_HI16 can be obtained by enclosing an operand inside of gotpchi.  Likewise, the R_OR1K_GOTPC_LO16 relocation can be obtained using gotpclo. These are mostly used when assembling PIC code.  For example, the standard PIC sequence on OpenRISC to get the base of the global offset table, PC relative, into a register, can be performed as:

     l.jal   0x8
      l.movhi r17, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
     l.ori   r17, r17, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
     l.add   r17, r17, r9

Several relocations exist to allow the link editor to perform GOT data references.  The R_OR1K_GOT16 relocation can obtained by enclosing an operand inside of got.  For example, assuming the GOT base is in register r17.

     l.lwz   r19, got(a)(r17)
     l.lwz   r21, 0(r19)

Also, several relocations exist for local GOT references.  The R_OR1K_GOTOFF_AHI16 relocation can obtained by enclosing an operand inside of gotoffha.  Likewise, R_OR1K_GOTOFF_LO16 and R_OR1K_GOTOFF_SLO16 can be obtained by enclosing an operand inside of gotofflo.  For example, assuming the GOT base is in register rl7:

     l.movhi r19, gotoffha(symbol)
     l.add   r19, r19, r17
     l.lwz   r19, gotofflo(symbol)(r19)

The above PC relative relocations use a l.jal (jump) instruction and reading of the link register to load the PC.  OpenRISC also supports page offset PC relative locations without a jump instruction using the l.adrp instruction.  By default the l.adrp instruction will create an R_OR1K_PCREL_PG21 relocation. Likewise, BFD_RELOC_OR1K_LO13 and BFD_RELOC_OR1K_SLO13 can be obtained by enclosing an operand inside of po.  For example:

     l.adrp  r3, symbol
     l.ori   r4, r3, po(symbol)
     l.lbz   r5, po(symbol)(r3)
     l.sb    po(symbol)(r3), r6

Likewise the page offset relocations can be used with GOT references.  The relocation R_OR1K_GOT_PG21 can be obtained by enclosing an l.adrp immediate operand inside of got.  Likewise, R_OR1K_GOT_LO13 can be obtained by enclosing an operand inside of gotpo.  For example to load the value of a GOT symbol into register r5 we can do:

     l.adrp  r17, got(_GLOBAL_OFFSET_TABLE_)
     l.lwz   r5, gotpo(symbol)(r17)

There are many relocations that can be requested for access to thread local storage variables.  All of the OpenRISC TLS mnemonics are supported:

  * R_OR1K_TLS_GD_HI16 is requested using tlsgdhi.

  * R_OR1K_TLS_GD_LO16 is requested using tlsgdlo.

  * R_OR1K_TLS_GD_PG21 is requested using tldgd.

  * R_OR1K_TLS_GD_LO13 is requested using tlsgdpo.

  * R_OR1K_TLS_LDM_HI16 is requested using tlsldmhi.

  * R_OR1K_TLS_LDM_LO16 is requested using tlsldmlo.

  * R_OR1K_TLS_LDM_PG21 is requested using tldldm.

  * R_OR1K_TLS_LDM_LO13 is requested using tlsldmpo.

  * R_OR1K_TLS_LDO_HI16 is requested using dtpoffhi.

  * R_OR1K_TLS_LDO_LO16 is requested using dtpofflo.

  * R_OR1K_TLS_IE_HI16 is requested using gottpoffhi.

  * R_OR1K_TLS_IE_AHI16 is requested using gottpoffha.

  * R_OR1K_TLS_IE_LO16 is requested using gottpofflo.

  * R_OR1K_TLS_IE_PG21 is requested using gottp.

  * R_OR1K_TLS_IE_LO13 is requested using gottppo.

  * R_OR1K_TLS_LE_HI16 is requested using tpoffhi.

  * R_OR1K_TLS_LE_AHI16 is requested using tpoffha.

  * R_OR1K_TLS_LE_LO16 is requested using tpofflo.

  * R_OR1K_TLS_LE_SLO16 also is requested using tpofflo depending on the instruction format.

Here are some example TLS model sequences.

First, General Dynamic:

     l.movhi r17, tlsgdhi(symbol)
     l.ori   r17, r17, tlsgdlo(symbol)
     l.add   r17, r17, r16
     l.or    r3, r17, r17
     l.jal   plt(__tls_get_addr)
      l.nop

Initial Exec:

     l.movhi r17, gottpoffhi(symbol)
     l.add   r17, r17, r16
     l.lwz   r17, gottpofflo(symbol)(r17)
     l.add   r17, r17, r10
     l.lbs   r17, 0(r17)

And finally, Local Exec:

     l.movhi r17, tpoffha(symbol)
     l.add   r17, r17, r10
     l.addi  r17, r17, tpofflo(symbol)
     l.lbs   r17, 0(r17)

Floating Point
==============

OpenRISC uses IEEE floating-point numbers.

OpenRISC Machine Directives
===========================

The OpenRISC version of AS supports the following additional machine directives:

.align
     This must be followed by the desired alignment in bytes.

.word
     On the OpenRISC, the .word directive produces a 32 bit value.

.nodelay
     On the OpenRISC, the .nodelay directive sets a flag in elf binaries indicating that the binary is generated catering for no delay slots.

.proc
     This directive is ignored.  Any text following it on the same line is also ignored.

.endproc
     This directive is ignored.  Any text following it on the same line is also ignored.

Opcodes
=======

For detailed information on the OpenRISC machine instruction set, see http://www.openrisc.io/architecture/.

AS implements all the standard OpenRISC opcodes.