IBM S/390 Dependent Features
****************************

The s390 version of AS supports two architectures modes and seven chip levels. The architecture modes are the Enterprise System Architecture (ESA) and the newer z/Architecture mode. The chip levels are g5, g6, z900, z990, z9-109, z9-ec, z10 and z196.

Options
=======

The following table lists all available s390 specific options:

-m31 | -m64
     Select 31- or 64-bit ABI implying a word size of 32- or 64-bit.

     These options are only available with the ELF object file format, and require that the necessary BFD support has been included (on a 31-bit platform you must add --enable-64-bit-bfd on the call to the configure script to enable 64-bit usage and use s390x as target platform).

-mesa | -mzarch
     Select the architecture mode, either the Enterprise System Architecture (esa) mode or the z/Architecture mode (zarch).

     The 64-bit instructions are only available with the z/Architecture mode. The combination of -m64 and -mesa results in a warning message.

-march=CPU
     This option specifies the target processor. The following processor names are recognized: g5, g6, z900, z990, z9-109, z9-ec, z10 and z196. Assembling an instruction that is not supported on the target processor results in an error message. Do not specify g5 or g6 with -mzarch.

-mregnames
     Allow symbolic names for registers.

-mno-regnames
     Do not allow symbolic names for registers.

-mwarn-areg-zero
     Warn whenever the operand for a base or index register has been specified but evaluates to zero. This can indicate the misuse of general purpose register 0 as an address register.

Special Characters
==================

# is the line comment character.

Instruction syntax
==================

The assembler syntax closely follows the syntax outlined in Enterprise Systems Architecture/390 Principles of Operation (SA22-7201) and the z/Architecture Principles of Operation (SA22-7832).

Each instruction has two major parts, the instruction mnemonic and the instruction operands. The instruction format varies.

Register naming
---------------

The AS recognizes a number of predefined symbols for the various processor registers. A register specification in one of the instruction formats is an unsigned integer between 0 and 15. The specific instruction and the position of the register in the instruction format denotes the type of the register. The register symbols are prefixed with %:

     %rN   the 16 general purpose registers, 0 <= N <= 15
     %fN   the 16 floating point registers, 0 <= N <= 15
     %aN   the 16 access registers, 0 <= N <= 15
     %cN   the 16 control registers, 0 <= N <= 15
     %lit   an alias for the general purpose register %r13
     %sp   an alias for the general purpose register %r15

Instruction Mnemonics
---------------------

All instructions documented in the Principles of Operation are supported with the mnemonic and order of operands as described. The instruction mnemonic identifies the instruction format (s390 Formats) and the specific operation code for the instruction. For example, the lr mnemonic denotes the instruction format RR with the operation code 0x18.

The definition of the various mnemonics follows a scheme, where the first character usually hint at the type of the instruction:

     a   add instruction, for example al for add logical 32-bit
     b   branch instruction, for example bc for branch on condition
     c   compare or convert instruction, for example cr for compare
     register 32-bit
     d   divide instruction, for example dlr devide logical register
     64-bit to 32-bit
     i   insert instruction, for example ic insert character
     l   load instruction, for example ltr load and test register
     mv   move instruction, for example mvc move character
     m   multiply instruction, for example mh multiply halfword
     n   and instruction, for example ni and immediate
     o   or instruction, for example oc or character
     sla, sll   shift left single instruction
     sra, srl   shift right single instruction
     st   store instruction, for example stm store multiple
     s   subtract instruction, for example slr subtract
     logical 32-bit
     t   test or translate instruction, of example tm test under mask
     x   exclusive or instruction, for example xc exclusive or
     character

Certain characters at the end of the mnemonic may describe a property of the instruction:

     c   the instruction uses a 8-bit character operand
     f   the instruction extends a 32-bit operand to 64 bit
     g   the operands are treated as 64-bit values
     h   the operand uses a 16-bit halfword operand
     i   the instruction uses an immediate operand
     l   the instruction uses unsigned, logical operands
     m   the instruction uses a mask or operates on multiple values
     r   if r is the last character, the instruction operates on registers
     y   the instruction uses 20-bit displacements

There are many exceptions to the scheme outlined in the above lists, in particular for the priviledged instructions. For non-priviledged instruction it works quite well, for example the instruction clgfr c: compare instruction, l: unsigned operands, g: 64-bit operands, f: 32- to 64-bit extension, r: register operands. The instruction compares an 64-bit value in a register with the zero extended 32-bit value from a second register. For a complete list of all mnemonics see appendix B in the Principles of Operation.

Instruction Operands
--------------------

Instruction operands can be grouped into three classes, operands located in registers, immediate operands, and operands in storage.

A register operand can be located in general, floating-point, access, or control register. The register is identified by a four-bit field. The field containing the register operand is called the R field.

Immediate operands are contained within the instruction and can have 8, 16 or 32 bits. The field containing the immediate operand is called the I field. Dependent on the instruction the I field is either signed or unsigned.

A storage operand consists of an address and a length. The address of a storage operands can be specified in any of these ways:

  * The content of a single general R

  * The sum of the content of a general register called the base register B plus the content of a displacement field D

  * The sum of the contents of two general registers called the index register X and the base register B plus the content of a displacement field

  * The sum of the current instruction address and a 32-bit signed immediate field multiplied by two.

The length of a storage operand can be:

  * Implied by the instruction

  * Specified by a bitmask

  * Specified by a four-bit or eight-bit length field L

  * Specified by the content of a general register

The notation for storage operand addresses formed from multiple fields is as follows:

Dn(Bn)
     the address for operand number n is formed from the content of general register Bn called the base register and the displacement field Dn.

Dn(Xn,Bn)
     the address for operand number n is formed from the content of general register Xn called the index register, general register Bn called the base register and the displacement field Dn.

Dn(Ln,Bn)
     the address for operand number n is formed from the content of general regiser Bn called the base register and the displacement field Dn. The length of the operand n is specified by the field Ln.

The base registers Bn and the index registers Xn of a storage operand can be skipped. If Bn and Xn are skipped, a zero will be stored to the operand field. The notation changes as follows:

     full notation   short notation
     Dn(0,Bn)   Dn(Bn)
     Dn(0,0)   Dn
     Dn(0)   Dn
     Dn(Ln,0)   Dn(Ln)

Instruction Formats
-------------------

The Principles of Operation manuals lists 26 instruction formats where some of the formats have multiple variants. For the .insn pseudo directive the assembler recognizes some of the formats. Typically, the most general variant of the instruction format is used by the .insn directive.

The following table lists the abbreviations used in the table of instruction formats:

     OpCode / OpCd   Part of the op code.
     Bx   Base register number for operand x.
     Dx   Displacement for operand x.
     DLx   Displacement lower 12 bits for operand x.
     DHx   Displacement higher 8-bits for operand x.
     Rx   Register number for operand x.
     Xx   Index register number for operand x.
     Ix   Signed immediate for operand x.
     Ux   Unsigned immediate for operand x.

An instruction is two, four, or six bytes in length and must be aligned on a 2 byte boundary. The first two bits of the instruction specify the length of the instruction, 00 indicates a two byte instruction, 01 and 10 indicates a four byte instruction, and 11 indicates a six byte instruction.

The following table lists the s390 instruction formats that are available with the .insn pseudo directive:

E format
     +-------------+
     |    OpCode   |
     +-------------+
     0            15

RI format: <insn> R1,I2
     +--------+----+----+------------------+
     | OpCode | R1 |OpCd|        I2        |
     +--------+----+----+------------------+
     0        8    12   16                31

RIE format: <insn> R1,R3,I2
     +--------+----+----+------------------+--------+--------+
     | OpCode | R1 | R3 |        I2        |////////| OpCode |
     +--------+----+----+------------------+--------+--------+
     0        8    12   16                 32       40      47

RIL format: <insn> R1,I2
     +--------+----+----+------------------------------------+
     | OpCode | R1 |OpCd|                  I2                |
     +--------+----+----+------------------------------------+
     0        8    12   16                                  47

RILU format: <insn> R1,U2
     +--------+----+----+------------------------------------+
     | OpCode | R1 |OpCd|                  U2                |
     +--------+----+----+------------------------------------+
     0        8    12   16                                  47

RIS format: <insn> R1,I2,M3,D4(B4)
     +--------+----+----+----+-------------+--------+--------+
     | OpCode | R1 | M3 | B4 |     D4      |   I2   | Opcode |
     +--------+----+----+----+-------------+--------+--------+
     0        8    12   16   20            32       36      47

RR format: <insn> R1,R2
     +--------+----+----+
     | OpCode | R1 | R2 |
     +--------+----+----+
     0        8    12  15

RRE format: <insn> R1,R2
     +------------------+--------+----+----+
     |      OpCode      |////////| R1 | R2 |
     +------------------+--------+----+----+
     0                  16       24   28  31

RRF format: <insn> R1,R2,R3,M4
     +------------------+----+----+----+----+
     |      OpCode      | R3 | M4 | R1 | R2 |
     +------------------+----+----+----+----+
     0                  16   20   24   28  31

RRS format: <insn> R1,R2,M3,D4(B4)
     +--------+----+----+----+-------------+----+----+--------+
     | OpCode | R1 | R3 | B4 |     D4      | M3 |////| OpCode |
     +--------+----+----+----+-------------+----+----+--------+
     0        8    12   16   20            32   36   40      47

RS format: <insn> R1,R3,D2(B2)
     +--------+----+----+----+-------------+
     | OpCode | R1 | R3 | B2 |     D2      |
     +--------+----+----+----+-------------+
     0        8    12   16   20           31

RSE format: <insn> R1,R3,D2(B2)
     +--------+----+----+----+-------------+--------+--------+
     | OpCode | R1 | R3 | B2 |     D2      |////////| OpCode |
     +--------+----+----+----+-------------+--------+--------+
     0        8    12   16   20            32       40      47

RSI format: <insn> R1,R3,I2
     +--------+----+----+------------------------------------+
     | OpCode | R1 | R3 |                  I2                |
     +--------+----+----+------------------------------------+
     0        8    12   16                                  47

RSY format: <insn> R1,R3,D2(B2)
     +--------+----+----+----+-------------+--------+--------+
     | OpCode | R1 | R3 | B2 |    DL2      |  DH2   | OpCode |
     +--------+----+----+----+-------------+--------+--------+
     0        8    12   16   20            32       40      47

RX format: <insn> R1,D2(X2,B2)
     +--------+----+----+----+-------------+
     | OpCode | R1 | X2 | B2 |     D2      |
     +--------+----+----+----+-------------+
     0        8    12   16   20           31

RXE format: <insn> R1,D2(X2,B2)
     +--------+----+----+----+-------------+--------+--------+
     | OpCode | R1 | X2 | B2 |     D2      |////////| OpCode |
     +--------+----+----+----+-------------+--------+--------+
     0        8    12   16   20            32       40      47

RXF format: <insn> R1,R3,D2(X2,B2)
     +--------+----+----+----+-------------+----+---+--------+
     | OpCode | R3 | X2 | B2 |     D2      | R1 |///| OpCode |
     +--------+----+----+----+-------------+----+---+--------+
     0        8    12   16   20            32   36  40      47

RXY format: <insn> R1,D2(X2,B2)
     +--------+----+----+----+-------------+--------+--------+
     | OpCode | R1 | X2 | B2 |     DL2     |   DH2  | OpCode |
     +--------+----+----+----+-------------+--------+--------+
     0        8    12   16   20            32   36   40      47

S format: <insn> D2(B2)
     +------------------+----+-------------+
     |      OpCode      | B2 |     D2      |
     +------------------+----+-------------+
     0                  16   20           31

SI format: <insn> D1(B1),I2
     +--------+---------+----+-------------+
     | OpCode |   I2    | B1 |     D1      |
     +--------+---------+----+-------------+
     0        8         16   20           31

SIY format: <insn> D1(B1),U2
     +--------+---------+----+-------------+--------+--------+
     | OpCode |   I2    | B1 |     DL1     |  DH1   | OpCode |
     +--------+---------+----+-------------+--------+--------+
     0        8         16   20            32   36   40      47

SIL format: <insn> D1(B1),I2
     +------------------+----+-------------+-----------------+
     |      OpCode      | B1 |      D1     |       I2        |
     +------------------+----+-------------+-----------------+
     0                  16   20            32               47

SS format: <insn> D1(R1,B1),D2(B3),R3
     +--------+----+----+----+-------------+----+------------+
     | OpCode | R1 | R3 | B1 |     D1      | B2 |     D2     |
     +--------+----+----+----+-------------+----+------------+
     0        8    12   16   20            32   36          47

SSE format: <insn> D1(B1),D2(B2)
     +------------------+----+-------------+----+------------+
     |      OpCode      | B1 |     D1      | B2 |     D2     |
     +------------------+----+-------------+----+------------+
     0        8    12   16   20            32   36           47

SSF format: <insn> D1(B1),D2(B2),R3
     +--------+----+----+----+-------------+----+------------+
     | OpCode | R3 |OpCd| B1 |     D1      | B2 |     D2     |
     +--------+----+----+----+-------------+----+------------+
     0        8    12   16   20            32   36           47

For the complete list of all instruction format variants see the Principles of Operation manuals.

Instruction Aliases
-------------------

A specific bit pattern can have multiple mnemonics, for example the bit pattern 0xa7000000 has the mnemonics tmh and tmlh. In addition, there are a number of mnemonics recognized by AS that are not present in the Principles of Operation. These are the short forms of the branch instructions, where the condition code mask operand is encoded in the mnemonic. This is relevant for the branch instructions, the compare and branch instructions, and the compare and trap instructions.

For the branch instructions there are 20 condition code strings that can be used as part of the mnemonic in place of a mask operand in the instruction format:

     instruction   short form
     bcr   M1,R2     b<m>r  R2
     bc    M1,D2(X2,B2)    b<m>   D2(X2,B2)
     brc   M1,I2   j<m>   I2
     brcl  M1,I2   jg<m>  I2

In the mnemonic for a branch instruction the condition code string <m> can be any of the following:

     o   jump on overflow / if ones
     h   jump on A high
     p   jump on plus
     nle   jump on not low or equal
     l   jump on A low
     m   jump on minus
     nhe   jump on not high or equal
     lh   jump on low or high
     ne   jump on A not equal B
     nz   jump on not zero / if not zeros
     e   jump on A equal B
     z   jump on zero / if zeroes
     nlh   jump on not low or high
     he   jump on high or equal
     nl   jump on A not low
     nm   jump on not minus / if not mixed
     le   jump on low or equal
     nh   jump on A not high
     np   jump on not plus
     no   jump on not overflow / if not ones

For the compare and branch, and compare and trap instructions there are 12 condition code strings that can be used as part of the mnemonic in place of a mask operand in the instruction format:

     instruction   short form
     crb    R1,R2,M3,D4(B4)     crb<m>    R1,R2,D4(B4)
     cgrb   R1,R2,M3,D4(B4)     cgrb<m>   R1,R2,D4(B4)
     crj    R1,R2,M3,I4     crj<m>    R1,R2,I4
     cgrj   R1,R2,M3,I4     cgrj<m>   R1,R2,I4
     cib    R1,I2,M3,D4(B4)     cib<m>    R1,I2,D4(B4)
     cgib   R1,I2,M3,D4(B4)     cgib<m>   R1,I2,D4(B4)
     cij    R1,I2,M3,I4     cij<m>    R1,I2,I4
     cgij   R1,I2,M3,I4     cgij<m>   R1,I2,I4
     crt    R1,R2,M3     crt<m>    R1,R2
     cgrt   R1,R2,M3     cgrt<m>   R1,R2
     cit    R1,I2,M3     cit<m>    R1,I2
     cgit   R1,I2,M3     cgit<m>   R1,I2
     clrb   R1,R2,M3,D4(B4)     clrb<m>   R1,R2,D4(B4)
     clgrb  R1,R2,M3,D4(B4)     clgrb<m>  R1,R2,D4(B4)
     clrj   R1,R2,M3,I4     clrj<m>   R1,R2,I4
     clgrj  R1,R2,M3,I4     clgrj<m>  R1,R2,I4
     clib   R1,I2,M3,D4(B4)     clib<m>   R1,I2,D4(B4)
     clgib  R1,I2,M3,D4(B4)     clgib<m>  R1,I2,D4(B4)
     clij   R1,I2,M3,I4     clij<m>   R1,I2,I4
     clgij  R1,I2,M3,I4     clgij<m>  R1,I2,I4
     clrt   R1,R2,M3     clrt<m>   R1,R2
     clgrt  R1,R2,M3     clgrt<m>  R1,R2
     clfit  R1,I2,M3     clfit<m>  R1,I2
     clgit  R1,I2,M3     clgit<m>  R1,I2

In the mnemonic for a compare and branch and compare and trap instruction the condition code string <m> can be any of the following:

     h   jump on A high
     nle   jump on not low or equal
     l   jump on A low
     nhe   jump on not high or equal
     ne   jump on A not equal B
     lh   jump on low or high
     e   jump on A equal B
     nlh   jump on not low or high
     nl   jump on A not low
     he   jump on high or equal
     nh   jump on A not high
     le   jump on low or equal

Instruction Operand Modifier
----------------------------

If a symbol modifier is attached to a symbol in an expression for an instruction operand field, the symbol term is replaced with a reference to an object in the global offset table (GOT) or the procedure linkage table (PLT). The following expressions are allowed: symbol@modifier + constant, symbol@modifier + label + constant, and symbol@modifier - label + constant. The term symbol is the symbol that will be entered into the GOT or PLT, label is a local label, and constant is an arbitrary expression that the assembler can evaluate to a constant value.

The term (symbol + constant1)@modifier +/- label + constant2 is also accepted but a warning message is printed and the term is converted to symbol@modifier +/- label + constant1 + constant2.

@got
@got12
     The @got modifier can be used for displacement fields, 16-bit immediate fields and 32-bit pc-relative immediate fields. The @got12 modifier is synonym to @got. The symbol is added to the GOT. For displacement fields and 16-bit immediate fields the symbol term is replaced with the offset from the start of the GOT to the GOT slot for the symbol. For a 32-bit pc-relative field the pc-relative offset to the GOT slot from the current instruction address is used.

@gotent
     The @gotent modifier can be used for 32-bit pc-relative immediate fields. The symbol is added to the GOT and the symbol term is replaced with the pc-relative offset from the current instruction to the GOT slot for the symbol.

@gotoff
     The @gotoff modifier can be used for 16-bit immediate fields. The symbol term is replaced with the offset from the start of the GOT to the address of the symbol.

@gotplt
     The @gotplt modifier can be used for displacement fields, 16-bit immediate fields, and 32-bit pc-relative immediate fields. A procedure linkage table entry is generated for the symbol and a jump slot for the symbol is added to the GOT. For displacement fields and 16-bit immediate fields the symbol term is replaced with the offset from the start of the GOT to the jump slot for the symbol. For a 32-bit pc-relative field the pc-relative offset to the jump slot from the current instruction address is used.

@plt
     The @plt modifier can be used for 16-bit and 32-bit pc-relative immediate fields. A procedure linkage table entry is generated for the symbol. The symbol term is replaced with the relative offset from the current instruction to the PLT entry for the symbol.

@pltoff
     The @pltoff modifier can be used for 16-bit immediate fields. The symbol term is replaced with the offset from the start of the PLT to the address of the symbol.

@gotntpoff
     The @gotntpoff modifier can be used for displacement fields. The symbol is added to the static TLS block and the negated offset to the symbol in the static TLS block is added to the GOT. The symbol term is replaced with the offset to the GOT slot from the start of the GOT.

@indntpoff
     The @indntpoff modifier can be used for 32-bit pc-relative immediate fields. The symbol is added to the static TLS block and the negated offset to the symbol in the static TLS block is added to the GOT. The symbol term is replaced with the pc-relative offset to the GOT slot from the current instruction address.

For more information about the thread local storage modifiers gotntpoff and indntpoff see the ELF extension documentation ELF Handling For Thread-Local Storage.

Instruction Marker
------------------

The thread local storage instruction markers are used by the linker to perform code optimization.

:tls_load
     The :tls_load marker is used to flag the load instruction in the initial exec TLS model that retrieves the offset from the thread pointer to a thread local storage variable from the GOT.

:tls_gdcall
     The :tls_gdcall marker is used to flag the branch-and-save instruction to the __tls_get_offset function in the global dynamic TLS model.

:tls_ldcall
     The :tls_ldcall marker is used to flag the branch-and-save instruction to the __tls_get_offset function in the local dynamic TLS model.

For more information about the thread local storage instruction marker and the linker optimizations see the ELF extension documentation ELF Handling For Thread-Local Storage.

Literal Pool Entries
--------------------

A literal pool is a collection of values. To access the values a pointer to the literal pool is loaded to a register, the literal pool register. Usually, register %r13 is used as the literal pool register (s390 Register). Literal pool entries are created by adding the suffix :lit1, :lit2, :lit4, or :lit8 to the end of an expression for an instruction operand. The expression is added to the literal pool and the operand is replaced with the offset to the literal in the literal pool.

:lit1
     The literal pool entry is created as an 8-bit value. An operand modifier must not be used for the original expression.

:lit2
     The literal pool entry is created as a 16 bit value. The operand modifier @got may be used in the original expression. The term x@got:lit2 will put the got offset for the global symbol x to the literal pool as 16 bit value.

:lit4
     The literal pool entry is created as a 32-bit value. The operand modifier @got and @plt may be used in the original expression. The term x@got:lit4 will put the got offset for the global symbol x to the literal pool as a 32-bit value. The term x@plt:lit4 will put the plt offset for the global symbol x to the literal pool as a 32-bit value.

:lit8
     The literal pool entry is created as a 64-bit value. The operand modifier @got and @plt may be used in the original expression. The term x@got:lit8 will put the got offset for the global symbol x to the literal pool as a 64-bit value. The term x@plt:lit8 will put the plt offset for the global symbol x to the literal pool as a 64-bit value.

The assembler directive .ltorg is used to emit all literal pool entries to the current position.

Assembler Directives
====================

AS for s390 supports all of the standard ELF assembler directives as outlined in the main part of this document. Some directives have been extended and there are some additional directives, which are only available for the s390 AS.

.insn
     This directive permits the numeric representation of an instructions and makes the assembler insert the operands according to one of the instructions formats for .insn (s390 Formats). For example, the instruction l %r1,24(%r15) could be written as .insn rx,0x58000000,%r1,24(%r15).

.short
.long
.quad
     This directive places one or more 16-bit (.short), 32-bit (.long), or 64-bit (.quad) values into the current section. If an ELF or TLS modifier is used only the following expressions are allowed: symbol@modifier + constant, symbol@modifier + label + constant, and symbol@modifier - label + constant. The following modifiers are available:

     @got
     @got12
          The @got modifier can be used for .short, .long and .quad. The @got12 modifier is synonym to @got. The symbol is added to the GOT. The symbol term is replaced with offset from the start of the GOT to the GOT slot for the symbol.

     @gotoff
          The @gotoff modifier can be used for .short, .long and .quad. The symbol term is replaced with the offset from the start of the GOT to the address of the symbol.

     @gotplt
          The @gotplt modifier can be used for .long and .quad. A procedure linkage table entry is generated for the symbol and a jump slot for the symbol is added to the GOT. The symbol term is replaced with the offset from the start of the GOT to the jump slot for the symbol.

     @plt
          The @plt modifier can be used for .long and .quad. A procedure linkage table entry us generated for the symbol. The symbol term is replaced with the address of the PLT entry for the symbol.

     @pltoff
          The @pltoff modifier can be used for .short, .long and .quad. The symbol term is replaced with the offset from the start of the PLT to the address of the symbol.

     @tlsgd
     @tlsldm
          The @tlsgd and @tlsldm modifier can be used for .long and .quad. A tls_index structure for the symbol is added to the GOT. The symbol term is replaced with the offset from the start of the GOT to the tls_index structure.

     @gotntpoff
     @indntpoff
          The @gotntpoff and @indntpoff modifier can be used for .long and .quad. The symbol is added to the static TLS block and the negated offset to the symbol in the static TLS block is added to the GOT. For @gotntpoff the symbol term is replaced with the offset from the start of the GOT to the GOT slot, for @indntpoff the symbol term is replaced with the address of the GOT slot.

     @dtpoff
          The @dtpoff modifier can be used for .long and .quad. The symbol term is replaced with the offset of the symbol relative to the start of the TLS block it is contained in.

     @ntpoff
          The @ntpoff modifier can be used for .long and .quad. The symbol term is replaced with the offset of the symbol relative to the TCB pointer.

     For more information about the thread local storage modifiers see the ELF extension documentation ELF Handling For Thread-Local Storage.

.ltorg
     This directive causes the current contents of the literal pool to be dumped to the current location (s390 Literal Pool Entries).

.machine string
     This directive allows you to change the machine for which code is generated.  string may be any of the -march= selection options (without the -march=), push, or pop. .machine push saves the currently selected cpu, which may be restored with .machine pop.  Be aware that the cpu string has to be put into double quotes in case it contains characters not appropriate for identifiers.  So you have to write "z9-109" instead of just z9-109.

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

The assembler recognizes both the IEEE floating-point instruction and the hexadecimal floating-point instructions. The floating-point constructors .float, .single, and .double always emit the IEEE format. To assemble hexadecimal floating-point constants the .long and .quad directives must be used.