C54X Dependent Features
***********************

Options
=======

The 'c54x version of AS has a few machine-dependent options.

You can use the -mfar-mode option to enable extended addressing mode. All addresses will be assumed to be > 16 bits, and the appropriate relocation types will be used.  This option is equivalent to using the .far_mode directive in the assembly code.  If you do not use the -mfar-mode option, all references will be assumed to be 16 bits. This option may be abbreviated to -mf.

You can use the -mcpu option to specify a particular CPU. This option is equivalent to using the .version directive in the assembly code.  For recognized CPU codes, see .version.  The default CPU version is 542.

You can use the -merrors-to-file option to redirect error output to a file (this provided for those deficient environments which don't provide adequate output redirection).  This option may be abbreviated to -me.

Blocking
========

A blocked section or memory block is guaranteed not to cross the blocking boundary (usually a page, or 128 words) if it is smaller than the blocking size, or to start on a page boundary if it is larger than the blocking size.

Environment Settings
====================

C54XDSP_DIR and A_DIR are semicolon-separated paths which are added to the list of directories normally searched for source and include files.  C54XDSP_DIR will override A_DIR.

Constants Syntax
================

The C54X version of AS allows the following additional constant formats, using a suffix to indicate the radix:

     Binary                  000000B, 011000b
     Octal                   10Q, 224q
     Hexadecimal             45h, 0FH

String Substitution
===================

A subset of allowable symbols (which we'll call subsyms) may be assigned arbitrary string values.  This is roughly equivalent to C preprocessor #define macros.  When AS encounters one of these symbols, the symbol is replaced in the input stream by its string value. Subsym names must begin with a letter.

Subsyms may be defined using the .asg and .eval directives (see .asg, see .eval.

Expansion is recursive until a previously encountered symbol is seen, at which point substitution stops.

In this example, x is replaced with SYM2; SYM2 is replaced with SYM1, and SYM1 is replaced with x.  At this point, x has already been encountered and the substitution stops.

      .asg   "x",SYM1
      .asg   "SYM1",SYM2
      .asg   "SYM2",x
      add    x,a             ; final code assembled is "add  x, a"

Macro parameters are converted to subsyms; a side effect of this is the normal AS '\ARG' dereferencing syntax is unnecessary.  Subsyms defined within a macro will have global scope, unless the .var directive is used to identify the subsym as a local macro variable see .var.

Substitution may be forced in situations where replacement might be ambiguous by placing colons on either side of the subsym.  The following code:

      .eval  "10",x
     LAB:X:  add     #x, a

When assembled becomes:

     LAB10  add     #10, a

Smaller parts of the string assigned to a subsym may be accessed with the following syntax:

:SYMBOL(CHAR_INDEX):
     Evaluates to a single-character string, the character at CHAR_INDEX.

:SYMBOL(START,LENGTH):
     Evaluates to a substring of SYMBOL beginning at START with length LENGTH.

Local Labels
============

Local labels may be defined in two ways:

  * $N, where N is a decimal number between 0 and 9

  * LABEL?, where LABEL is any legal symbol name.

Local labels thus defined may be redefined or automatically generated. The scope of a local label is based on when it may be undefined or reset. This happens when one of the following situations is encountered:

  * .newblock directive see .newblock

  * The current section is changed (.sect, .text, or .data)

  * Entering or leaving an included file

  * The macro scope where the label was defined is exited

Math Builtins
=============

The following built-in functions may be used to generate a floating-point value.  All return a floating-point value except $cvi, $int, and $sgn, which return an integer value.

$acos(EXPR)
     Returns the floating point arccosine of EXPR.

$asin(EXPR)
     Returns the floating point arcsine of EXPR.

$atan(EXPR)
     Returns the floating point arctangent of EXPR.

$atan2(EXPR1,EXPR2)
     Returns the floating point arctangent of EXPR1 / EXPR2.

$ceil(EXPR)
     Returns the smallest integer not less than EXPR as floating point.

$cosh(EXPR)
     Returns the floating point hyperbolic cosine of EXPR.

$cos(EXPR)
     Returns the floating point cosine of EXPR.

$cvf(EXPR)
     Returns the integer value EXPR converted to floating-point.

$cvi(EXPR)
     Returns the floating point value EXPR converted to integer.

$exp(EXPR)
     Returns the floating point value e ^ EXPR.

$fabs(EXPR)
     Returns the floating point absolute value of EXPR.

$floor(EXPR)
     Returns the largest integer that is not greater than EXPR as floating point.

$fmod(EXPR1,EXPR2)
     Returns the floating point remainder of EXPR1 / EXPR2.

$int(EXPR)
     Returns 1 if EXPR evaluates to an integer, zero otherwise.

$ldexp(EXPR1,EXPR2)
     Returns the floating point value EXPR1 * 2 ^ EXPR2.

$log10(EXPR)
     Returns the base 10 logarithm of EXPR.

$log(EXPR)
     Returns the natural logarithm of EXPR.

$max(EXPR1,EXPR2)
     Returns the floating point maximum of EXPR1 and EXPR2.

$min(EXPR1,EXPR2)
     Returns the floating point minimum of EXPR1 and EXPR2.

$pow(EXPR1,EXPR2)
     Returns the floating point value EXPR1 ^ EXPR2.

$round(EXPR)
     Returns the nearest integer to EXPR as a floating point number.

$sgn(EXPR)
     Returns -1, 0, or 1 based on the sign of EXPR.

$sin(EXPR)
     Returns the floating point sine of EXPR.

$sinh(EXPR)
     Returns the floating point hyperbolic sine of EXPR.

$sqrt(EXPR)
     Returns the floating point square root of EXPR.

$tan(EXPR)
     Returns the floating point tangent of EXPR.

$tanh(EXPR)
     Returns the floating point hyperbolic tangent of EXPR.

$trunc(EXPR)
     Returns the integer value of EXPR truncated towards zero as floating point.

Extended Addressing
===================

The LDX pseudo-op is provided for loading the extended addressing bits of a label or address.  For example, if an address _label resides in extended program memory, the value of _label may be loaded as follows:

      ldx     #_label,16,a    ; loads extended bits of _label
      or      #_label,a       ; loads lower 16 bits of _label
      bacc    a               ; full address is in accumulator A

Directives
==========

.align [SIZE]
.even
     Align the section program counter on the next boundary, based on SIZE.  SIZE may be any power of 2.  .even is equivalent to .align with a SIZE of 2.

     1
          Align SPC to word boundary

     2
          Align SPC to longword boundary (same as .even)

     128
          Align SPC to page boundary

.asg STRING, NAME
     Assign NAME the string STRING.  String replacement is performed on STRING before assignment.

.eval STRING, NAME
     Evaluate the contents of string STRING and assign the result as a string to the subsym NAME.  String replacement is performed on STRING before assignment.

.bss SYMBOL, SIZE [, [BLOCKING_FLAG] [,ALIGNMENT_FLAG]]
     Reserve space for SYMBOL in the .bss section.  SIZE is in words.  If present, BLOCKING_FLAG indicates the allocated space should be aligned on a page boundary if it would otherwise cross a page boundary.  If present, ALIGNMENT_FLAG causes the assembler to allocate SIZE on a long word boundary.

.byte VALUE [,...,VALUE_N]
.ubyte VALUE [,...,VALUE_N]
.char VALUE [,...,VALUE_N]
.uchar VALUE [,...,VALUE_N]
     Place one or more bytes into consecutive words of the current section. The upper 8 bits of each word is zero-filled.  If a label is used, it points to the word allocated for the first byte encountered.

.clink ["SECTION_NAME"]
     Set STYP_CLINK flag for this section, which indicates to the linker that if no symbols from this section are referenced, the section should not be included in the link.  If SECTION_NAME is omitted, the current section is used.

.c_mode
     TBD.

.copy "FILENAME" | FILENAME
.include "FILENAME" | FILENAME
     Read source statements from FILENAME.  The normal include search path is used.  Normally .copy will cause statements from the included file to be printed in the assembly listing and .include will not, but this distinction is not currently implemented.

.data
     Begin assembling code into the .data section.

.double VALUE [,...,VALUE_N]
.ldouble VALUE [,...,VALUE_N]
.float VALUE [,...,VALUE_N]
.xfloat VALUE [,...,VALUE_N]
     Place an IEEE single-precision floating-point representation of one or more floating-point values into the current section.  All but .xfloat align the result on a longword boundary.  Values are stored most-significant word first.

.drlist
.drnolist
     Control printing of directives to the listing file.  Ignored.

.emsg STRING
.mmsg STRING
.wmsg STRING
     Emit a user-defined error, message, or warning, respectively.

.far_mode
     Use extended addressing when assembling statements.  This should appear only once per file, and is equivalent to the -mfar-mode option see -mfar-mode.

.fclist
.fcnolist
     Control printing of false conditional blocks to the listing file.

.field VALUE [,SIZE]
     Initialize a bitfield of SIZE bits in the current section.  If VALUE is relocatable, then SIZE must be 16.  SIZE defaults to 16 bits.  If VALUE does not fit into SIZE bits, the value will be truncated.  Successive .field directives will pack starting at the current word, filling the most significant bits first, and aligning to the start of the next word if the field size does not fit into the space remaining in the current word.  A .align directive with an operand of 1 will force the next .field directive to begin packing into a new word.  If a label is used, it points to the word that contains the specified field.

.global SYMBOL [,...,SYMBOL_N]
.def SYMBOL [,...,SYMBOL_N]
.ref SYMBOL [,...,SYMBOL_N]
     .def nominally identifies a symbol defined in the current file and availalbe to other files.  .ref identifies a symbol used in the current file but defined elsewhere.  Both map to the standard .global directive.

.half VALUE [,...,VALUE_N]
.uhalf VALUE [,...,VALUE_N]
.short VALUE [,...,VALUE_N]
.ushort VALUE [,...,VALUE_N]
.int VALUE [,...,VALUE_N]
.uint VALUE [,...,VALUE_N]
.word VALUE [,...,VALUE_N]
.uword VALUE [,...,VALUE_N]
     Place one or more values into consecutive words of the current section. If a label is used, it points to the word allocated for the first value encountered.

.label SYMBOL
     Define a special SYMBOL to refer to the load time address of the current section program counter.

.length
.width
     Set the page length and width of the output listing file.  Ignored.

.list
.nolist
     Control whether the source listing is printed.  Ignored.

.long VALUE [,...,VALUE_N]
.ulong VALUE [,...,VALUE_N]
.xlong VALUE [,...,VALUE_N]
     Place one or more 32-bit values into consecutive words in the current section.  The most significant word is stored first.  .long and .ulong align the result on a longword boundary; xlong does not.

.loop [COUNT]
.break [CONDITION]
.endloop
     Repeatedly assemble a block of code.  .loop begins the block, and .endloop marks its termination.  COUNT defaults to 1024, and indicates the number of times the block should be repeated. .break terminates the loop so that assembly begins after the .endloop directive.  The optional CONDITION will cause the loop to terminate only if it evaluates to zero.

MACRO_NAME .macro [PARAM1][,...PARAM_N]
[.mexit]
.endm
     See the section on macros for more explanation (see C54X-Macros.

.mlib "FILENAME" | FILENAME
     Load the macro library FILENAME.  FILENAME must be an archived library (BFD ar-compatible) of text files, expected to contain only macro definitions.   The standard include search path is used.

.mlist

.mnolist
     Control whether to include macro and loop block expansions in the listing output.  Ignored.

.mmregs
     Define global symbolic names for the 'c54x registers.  Supposedly equivalent to executing .set directives for each register with its memory-mapped value, but in reality is provided only for compatibility and does nothing.

.newblock
     This directive resets any C54X local labels currently defined.  Normal AS local labels are unaffected.

.option OPTION_LIST
     Set listing options.  Ignored.

.sblock "SECTION_NAME" | SECTION_NAME [,"NAME_N" | NAME_N]
     Designate SECTION_NAME for blocking.  Blocking guarantees that a section will start on a page boundary (128 words) if it would otherwise cross a page boundary.  Only initialized sections may be designated with this directive.  See also C54X-Block.

.sect "SECTION_NAME"
     Define a named initialized section and make it the current section.

SYMBOL .set "VALUE"
SYMBOL .equ "VALUE"
     Equate a constant VALUE to a SYMBOL, which is placed in the symbol table.  SYMBOL may not be previously defined.

.space SIZE_IN_BITS
.bes SIZE_IN_BITS
     Reserve the given number of bits in the current section and zero-fill them.  If a label is used with .space, it points to the first word reserved.  With .bes, the label points to the last word reserved.

.sslist
.ssnolist
     Controls the inclusion of subsym replacement in the listing output.  Ignored.

.string "STRING" [,...,"STRING_N"]
.pstring "STRING" [,...,"STRING_N"]
     Place 8-bit characters from STRING into the current section. .string zero-fills the upper 8 bits of each word, while .pstring puts two characters into each word, filling the most-significant bits first.  Unused space is zero-filled.  If a label is used, it points to the first word initialized.

[STAG] .struct [OFFSET]
[NAME_1] element [COUNT_1]
[NAME_2] element [COUNT_2]
[TNAME] .tag STAGX [TCOUNT]
...
[NAME_N] element [COUNT_N]
[SSIZE] .endstruct
LABEL .tag [STAG]
     Assign symbolic offsets to the elements of a structure.  STAG defines a symbol to use to reference the structure.  OFFSET indicates a starting value to use for the first element encountered; otherwise it defaults to zero.  Each element can have a named offset, NAME, which is a symbol assigned the value of the element's offset into the structure.  If STAG is missing, these become global symbols.  COUNT adjusts the offset that many times, as if element were an array.  element may be one of .byte, .word, .long, .float, or any equivalent of those, and the structure offset is adjusted accordingly. .field and .string are also allowed; the size of .field is one bit, and .string is considered to be one word in size.  Only element descriptors, structure/union tags, .align and conditional assembly directives are allowed within .struct/.endstruct.  .align aligns member offsets to word boundaries only.  SSIZE, if provided, will always be assigned the size of the structure.

     The .tag directive, in addition to being used to define a structure/union element within a structure, may be used to apply a structure to a symbol.  Once applied to LABEL, the individual structure elements may be applied to LABEL to produce the desired offsets using LABEL as the structure base.

.tab
     Set the tab size in the output listing.  Ignored.

[UTAG] .union
[NAME_1] element [COUNT_1]
[NAME_2] element [COUNT_2]
[TNAME] .tag UTAGX[,TCOUNT]
...
[NAME_N] element [COUNT_N]
[USIZE] .endstruct
LABEL .tag [UTAG]
     Similar to .struct, but the offset after each element is reset to zero, and the USIZE is set to the maximum of all defined elements. Starting offset for the union is always zero.

[SYMBOL] .usect "SECTION_NAME", SIZE, [,[BLOCKING_FLAG] [,ALIGNMENT_FLAG]]
     Reserve space for variables in a named, uninitialized section (similar to .bss).  .usect allows definitions sections independent of .bss. SYMBOL points to the first location reserved by this allocation. The symbol may be used as a variable name.  SIZE is the allocated size in words.  BLOCKING_FLAG indicates whether to block this section on a page boundary (128 words) (see C54X-Block). ALIGNMENT FLAG indicates whether the section should be longword-aligned.

.var SYM[,..., SYM_N]
     Define a subsym to be a local variable within a macro.  See C54X-Macros.

.version VERSION
     Set which processor to build instructions for.  Though the following values are accepted, the op is ignored.

     541
     542
     543
     545
     545LP
     546LP
     548
     549

Macros
======

Macros do not require explicit dereferencing of arguments (i.e. \ARG).

During macro expansion, the macro parameters are converted to subsyms. If the number of arguments passed the macro invocation exceeds the number of parameters defined, the last parameter is assigned the string equivalent of all remaining arguments.  If fewer arguments are given than parameters, the missing parameters are assigned empty strings.  To include a comma in an argument, you must enclose the argument in quotes.

The following built-in subsym functions allow examination of the string value of subsyms (or ordinary strings).  The arguments are strings unless otherwise indicated (subsyms passed as args will be replaced by the strings they represent).

$symlen(STR)
     Returns the length of STR.

$symcmp(STR1,STR2)
     Returns 0 if STR1 == STR2, non-zero otherwise.

$firstch(STR,CH)
     Returns index of the first occurrence of character constant CH in STR.

$lastch(STR,CH)
     Returns index of the last occurrence of character constant CH in STR.

$isdefed(SYMBOL)
     Returns zero if the symbol SYMBOL is not in the symbol table, non-zero otherwise.

$ismember(SYMBOL,LIST)
     Assign the first member of comma-separated string LIST to SYMBOL; LIST is reassigned the remainder of the list.  Returns zero if LIST is a null string.  Both arguments must be subsyms.

$iscons(EXPR)
     Returns 1 if string EXPR is binary, 2 if octal, 3 if hexadecimal, 4 if a character, 5 if decimal, and zero if not an integer.

$isname(NAME)
     Returns 1 if NAME is a valid symbol name, zero otherwise.

$isreg(REG)
     Returns 1 if REG is a valid predefined register name (AR0-AR7 only).

$structsz(STAG)
     Returns the size of the structure or union represented by STAG.

$structacc(STAG)
     Returns the reference point of the structure or union represented by STAG.   Always returns zero.

Memory-mapped Registers
=======================

The following symbols are recognized as memory-mapped registers: