Copyright Digital Equipment Corp. All rights reserved.

ASM (Alpha only)

 ASM (character [, any-type-arg])

 Class:  Nonelemental function - Generic

 Lets you use assembler instructions in an executable program.

 The first argument is a character constant or a concatenation of
 character constants containing the assembler instructions.  The
 optional second argument can be of any type.  It can be a source or
 destination argument for the instruction, for example.

 Arguments are passed by value.  If you want to pass an argument by
 reference (for example, a whole array, a character string, or a
 record structure), you can use the %REF built-in function.

 Labels are allowed, but all references must be from within the same
 ASM function.  This lets you set up looping constructs, for
 example.  Cross-jumping between ASM functions is not permitted.

 In general, an ASM function can appear anywhere that an intrinsic
 function can be used.  Since the supplied assembly code, assembly
 directives, or assembly data is integrated into the code stream,
 the compiler may choose to use different registers, better code
 sequences, and so on, just as if the code were written in Fortran.

 You do not have absolute control over instruction sequences and
 registers, and the compiler may intersperse other code together
 with the ASM code for better performance.  Better code sequences
 may be substituted by the optimizer if it chooses to do so.

 Only register names beginning with a dollar sign ($) or percent
 sign (%) are permitted.  For more information on register name
 conventions, see the OpenVMS operating system documentation set.

   +---------+-------------------+-------------+
   | Generic | Specific          | Result Type |
   +---------+-------------------+-------------+
   |  ASM    | ASM (see Note1)   | INTEGER*8   |
   |         | FASM (see Note2)  | REAL*4      |
   |         | DASM (see Note2)  | REAL*8      |
   +---------+-------------------+-------------+

 Note1: The value must be stored in register $0 by the user code.
 Note2: The value must be stored in register $F0 by the user code.

 Example:

 Consider the following:

  ! Concatenation is recommended for clarity.
  ! Notice that ";" separates instructions.
  !
  nine=9

  type *, asm('addq %0, $17, $0;'//  ! Adds the first two arguments
   1    'ldq $22, %6;'//             !   and puts the answer in
   1    'ldq $23, %7;'//             !   register $0
   1    'ldq $24, %8;'//             !
   1    'mov $0, %fp;'//             ! Comments are not allowed in the
   1    'addq $18, %fp, $0;'//       !   constant, but are allowed here
   1     'addq $19, $0, $0;'//
   1     'addq $20, $0, $0;'//
   1     'addq $21, $0, $0;'//
   1     'addq $22, $0, $0;'//
   1     'addq $23, $0, $0;'//
   1    'addq $24, $0, $0;',
   1 1,2,3,4,5,6,7,8,nine)           ! The actual arguments to the
                                     !   ASM (usually by value)
  end

 This example shows an integer ASM function that adds up 9 values
 and returns the sum as its result.  Note that the user stores the
 function result in register $0.

 All arguments are passed by value.  The arguments not passed in
 registers can be named %6, %7, and %8, which correspond to the
 actual arguments 7, 8, and 9 (since %0 is the first argument).
 Notice that you can reference reserved registers like %fp.

 The compiler creates the appropriate argument list.  So, in this
 example, the first argument value (1) will be available in register
 $16, and the eighth argument value (8) will be available in %7,
 which is actually 8($30).