CDPEAC: Using GCC to Program in DPEAC Mario O. Bourgoin and Andrew J. Wilson Revision : 1.2 Revised on September 11, 1992

(Source: /proj/starlisp/cdpeac/doc/cdpeac-wip.tex)

\begin{matrix}c \\ ◯ \end{matrix}1991 Thinking Machines Corporation of Cambridge, Massachusetts. All rights reserved.

This notice is intended as a precaution against inadvertent publication and does not constitute an admission or acknowledgment that publication has occurred or constitute a waiver of confidentiality. The CM5 and the Data Path are the proprietary and confidential property of Thinking Machines Corporation.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 1992i

Contents

1 Introduction 1 1.1 Purpose of this Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Related Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Getting Started 1

3 How CDPEAC Works 1 3.1 GCC’s ASM Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3.2 ANSI C Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3.3 C functions and CDPEAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3.4 Compiling CDPEAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.5 More CDPEAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

4 DP Accessors 5

5 Instruction Formats 5 5.1 Computation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5.2 Memory Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 5.3 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.4 Population Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.5 Accumulated Context Count . . . . . . . . . . . . . . . . . . . . . . . . . . 9

6 Joining 9

7 Debugging 9 7.1 DPSIM Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 7.2 Viewing DPSIM VU Registers in pndbx . . . . . . . . . . . . . . . . . . . . 10

8 Instruction Set 11 8.1 Metasyntactic Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 1992ii

8.2 Standard Instruction Variants . . . . . . . . . . . . . . . . . . . . . . . . . . 11 8.3 Join Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 8.4 Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 8.5 Control Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 8.6 Mode Setting Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 8.7 Memory Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

8.7.1 Loading Into VU Registers . . . . . . . . . . . . . . . . . . . . . . . 19 8.7.2 Storing From VU Registers . . . . . . . . . . . . . . . . . . . . . . . 20 8.7.3 Register To Register Moves . . . . . . . . . . . . . . . . . . . . . . . 21

8.8 Monadic Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 8.9 Arithmetic Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

8.9.1 Dyadic Arithmetic Instructions . . . . . . . . . . . . . . . . . . . . . 23 8.9.2 Logical Shift Operations . . . . . . . . . . . . . . . . . . . . . . . . . 24 8.9.3 Bitwise Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . 25 8.9.4 Logical Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 8.9.5 The Merge Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . 27

8.10 Dyadic Two-operation Operations . . . . . . . . . . . . . . . . . . . . . . . 27 8.11 Triadic Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

8.11.1 Dyadic Multiply with Arithmetic Instructions . . . . . . . . . . . . . 29 8.11.2 Multiply with Logical Instructions . . . . . . . . . . . . . . . . . . . 29

8.12 Population Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 19921

1 Introduction

1.1 Purpose of this Document

This documents the use of GNU CC (GCC) to program the CM5/Data Path (DP) in DPEAC. GCC’s Extended ASM statement allows the use of an instruction pattern where C allows a string constant, and fills in the pattern variables with the names of the SPARC registers it has allocated to hold the requested values. This allows the programmer to concentrate on getting the DPEAC portion of his code correct while leaving the work of allocating SPARC registers and flow of control to GCC. When combined with the careful use of GCC’s ANSI C macro facility, the ASM statement can be used to simulate the existence of in-line DPEAC instructions as if they were C function calls, and work with them as such from source-level debuggers such as PNDBX. The result is a powerful tool for programming in DPEAC, and is called CDPEAC.

This document is not complete. Future revision of this document will include more information on how effects such as how instruction pipelining can be achieved in the CDPEAC framework.

1.2 Related Documents

The following is a list of related documents:

• DPEAC Language Specification,

• Using and Porting GNU CC,

• CDPEAC Macro Pacakage

• Makefile Changes for using CDPEAC

2 Getting Started

Assuming you already know DPEAC, to use CDPEAC as others have done at TMC, you should first read the next section to understand the basic workings of the macro package. This will help you understand how to locate errors in your CDPEAC programs. Then, you may setup or change your makefiles in the manner described in the file “cdp-makefile.txt”. Finally, you should look at examples that others have created, in the *Lisp run-time library for example.

3 How CDPEAC Works

This section sketches the way that GCC’s ASM and its macro facilities are used in combination with other tools to create CDPEAC.

3.1 GCC’s ASM Statement

The full description of GCC’s ASM statement is best left to the GCC manual referenced in Subsection 1.2. This section will concentrate on how it is currently used to facilitate DPEAC programming from C.

GCC’s ASM statement has the basic form:

asm(pattern : outputs : inputs : clobbered);

For CDPEAC purposes, we can ignore the outputs field. Here’s an example statement:

        asm("dfloadv %0, V5" :: "m" (*source) : "%g2", "%g3")

The DPEAC instruction DFLOADV directs each DP to load into vector register V5 a vector’s worth of data from its DP memory location “source.” GCC might translate this statement into the DPEAC statement:

        dfloadv [%i1], V5

In the ASM statement, the pattern is an instruction pattern string constant in which the “%0” is a pattern variable standing in for the SPARC register that holds the memory location. Inputs consists of as many pairs of C expressions and constraints as there are different pattern variables. In the example, “m” is a constraint specifying that “source” is a pointer into memory. Finally, clobbered consists of string constants naming the SPARC registers that are changed by use of the instruction, which for DPEAC are usually “%g2” and “%g3.”

3.2 ANSI C Macros

In ANSI C, macros allow the user to create string constants at compile time from other string constants and macro arguments. CDPEAC programming takes advantage of this to facilitate the creation of DPEAC instructions. The load ASM statement described in Subsection 3.1 could have been written:

        asm("df" "loadv %0, " "V5" :: "m" (*source) : "%g2", "%g3")

Because the pattern part of the ASM statement is assembled from parts, these parts can now be obtained from macros. The statement might have more generally been written as a C macro:

        #define loadv(type, source, data_register) \
         asm(#type "loadv %0, " data_register :: "m" (*source) : "%g2", "%g3")

and then used from C as:

        loadv(df, *source, V5)

For this example to work in CDPEAC, vector registers are named string constants:

        #define V5 "V5"

Because instruction types are not as variable as register names, they are arguments to macros but are then transformed into string constants with the “#” operator.

Such macros as described above are often useful for more than one instruction, so CDPEAC defines it as a general macro:

        #define mem(mnemonic, source, data_register) \
         asm(mnemonic " %0, " data_register :: "m" (*source) : "%g2", "\%g3")

which is then used to define other instructions:

        #define loadv(type, source, data_register) \
         mem(#type "loadv", source, data_register)
        #define storev(type, source, data_register) \
         mem(#type "storev", source, data_register)

3.3 C functions and CDPEAC

DPEAC expects a particular setup for SPARC registers in order to correctly execute. To insure that this setup exists for a function that contains DPEAC code, the DPEAC “dpregs” instruction must be used at the start of \underline{all} functions that contain DPEAC statements. To this end, CDPEAC defines the macro:

        #define dpsetup() asm("dpregs =, =,")

Also, although DP control registers can be set by the user, system functions expect that they be in a particular state. It is up to the DPEAC programmer to insure that CDPEAC routines that change control registers return them to the standard state. The CMCOM level provides a routine for doing this, and it is accessible as a macro:

        #define dpcleanup() CMPE_cmcom_pe_cleanup_after_rts()

3.4 Compiling CDPEAC

Compiling CDPEAC to object code happens in two passes. First, GNU CC is told to produce assembler source from the C file. Then, DPAS processes the result into an object file. Because DPEAC depends on the state of some SPARC registers to execute correctly, these must be protected from GCC’s register allocation during compilation, so GCC must be told that SPARC registers “%l6” and “%l7” are fixed. The following line first compiles “mycode.c” into a “.dp” and then uses DPAS to produce the “.o”:

        gcc -S -ffixed-%l6 -ffixed-%l7 -o mycode.dp mycode.c
        dpas -o mycode.o mycode.dp

To facilitate the inclusion of CDPEAC code in normal MAKEFILE makes, a new file extension, “.cdp”, is defined in makefiles:

        # Make .dp the preferred dependency for .o files.
        .SUFFIXES:
        .SUFFIXES: .dp .cdp $(SUFFIXES)
        # The standard DPEAC assembler.
        DPAS = /proj/dash/dpas/dpas
        DPFLAGS =
        COMPILE.dp = $(DPAS) $(DPFLAGS)
        OUTPUT_OPTION = -o $@

and a make recipe is created to compile the code:

                # Rule for the creation of a .o from a .cdp
        .cdp.o:
         gcc -S $(CFLAGS) -ffixed-%l6 -ffixed-%l7 -o $*.dp -x c $<
         $(COMPILE.dp) -o $@ $*.dp
         rm $*.dp

3.5 More CDPEAC

The sketchy nature of this section prevents the inclusion of more information on CDPEAC. Unexplained features include:

• debugging, • pipelining,

• conditionalization,

• memory striding,

and many other instruction modes. Future sections in this document may someday be created explain these features.

4 DP Accessors

This section explains the use of instructions such as DPWRT, DPRD, DPSET, and DPGET.

5 Instruction Formats

This section explains the use of instructions to performs computations and memory accesses.

5.1 Computation

The basic format for instructions that compute values, such as ADDV, SUBS, and MULV is:

operator(type, source, ... , destination)

Register Strides

In DPEAC, registers used in vector operations may specify the register stride that is used to reach the next register. Normally, this stride is determined by the data type of the operation, 1 for single precision and 2 for double precision, but it can be changed to another value. In CDPEAC, this is expressed with the form:

        dreg_s(V2, 2)

in place of the normal register specification, where the stride, 2, must be an immediate constant. This says that the elements of the vector starting at register V2 are found at every 2 registers.

One use of striding is to specify that a scalar register may be used in a vector operation, and this may be expressed with the form:

        dreg_s(V2, 0)

Because this use of scalar registers in vector operations is very useful and prevalent, there is a special form for making this specification:

        scalar(V2)

Register Indexing

In DPEAC, registers may be addressed as an index from another register, so that vector register 3, V3, can also be addressed as being 8 registers from vector register 2, V2[8]. In CDPEAC, this is expressed with the form:

        dreg_x(V2, 8)

in place of the normal register specification, where the index, 8, must be an immediate constant.

Register Indirection

In DPEAC, an alternative to striding vector register with a constant value, is to use the values in another vector register to specify which registers form the operand vector. For example, the elements of a vector beginning at V2 and indexed by V4 can be expressed as V2(V4). In CDPEAC, this is expressed with the form:

        dreg_i(V2, V4)

in place of the normal register specification. This form can be combined with the register striding form to specify the stride of the indexing register. For example, it is possible to say that V4 is a scalar register as in:

        dreg_i(V2, scalar(V4))

Immediate Operands

DPEAC allows the second operands of a computation to be either an immediate value or to be obtained from a SPARC register. In CDPEAC, each instruction has a variant whose name ends in ‘i’ and whose second argument is an immediate value. For example:

        addvi(df, V2, 1, V4);

adds the constant double float 1.0 to vector register V2 and stores it in vector register V4. Also:

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 19927

        shlvi(df, V2, computed_shift, V4);

shifts vector register V2 by the value in the C variable computed shift and stores the result into V4. Vector Length DPEAC allows the default vector length for an operation to be overridden. In CDPEAC, each instruction has a variant whose name ends in “ v” and has an additional argument that specifies the vector length to be used. For example:

addv_v(f, 4, V6, V8, V10);

adds together 4 vector registers beginning at V6 and V8 and stores the result in V10. The variant just described temporarily changes the vector length. DPEAC also allows the default vector length to be permanently changed, and this is done with the vs variant. For example:

addv_vs(f, 4, V6, V8, V10);

adds together 4 vector registers beginning at V6 and V8 and stores the result in V10 as before, but it also permenently sets the vector length to that value.

5.2 Memory Access

The basic format for instructions that move values between data registers and DP memory, such as LOADV and STORES, is:

operator(type, pointer, ... , register) For example:

        loadv(f, *source, V2);

will load single float values from source into vector register V2, while:

        stores(u, *destination, S4);

will store an unsigned value from scalar register S4 into the destination.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 19928 Memory Striding DPEAC supports the simultaneous overriding and setting of the stride over DP memory. In CDPEAC, each memory operation has a variant whose name ends in “ s” and has an additional argument that specifies the memory stride to be used. For example:

        loadv_s(f, *source, 4 * sizeof(float), V2);

will load into vector register V2 single floats from every fourth float in source, and:

        loads_s(u, *source, 4 * sizeof(double), S8);

will load into scalar register S8 an unsigned value from source while setting the default stride for later operations to four times the size of a double float.

        loadv_u(f, *source, 4, V2);

is for cases where a constant stride, either 4, 8, or 16 can be used.

Memory Indirection

loadv_i(u, *source, V4, V2);

loads from source indexed by the values in V4 into vector register V2.

Vector Length

loadv_v(u, 4, *source, V2);

loads 4 unsigned values from into vector register V2.

loadv_vs(u, 4, *source, V2);

loads 4 unsigned values from into vector register V2.

Combination of Formats Vector length and constant memory stride:

loadv_v_u(u, 4, *source, 8, V2);

loads 4 unsigned values from source strided by the constant length 8 into vector register

V2.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 19929

5.3 Conditionals

        ldvm(S4);

loads the vector mask from scalar register S4.

        vmnew;

copies the vector mask into the vector mask buffer.

5.4 Population Count

        epcv(u, V2, V4);

counts the number of 1 bits in each element of vector register V2 and stores the result in elements of vector register V4.

5.5 Accumulated Context Count

        vmcountv(V2);

stores in the elements of V2 the inclusive accumulated number of 1 bits in the vector mask at each step of the vector operation.

6 Joining

Many instruction forms can be combined together for reasons of speed and space. The join macros are used for this purpose. There is a variant for every number of operations that

can be joined: join2, join3, join4, join5.

Implementation note: Joins may not be used in joins. An attempt was made to create the right macro structure for this to happen, and it failed. It isn’t clear why it didn’t work, and more work than what currently seems warranted is needed to understand the problem.

7 Debugging

This section explains the use of PNDBX to debug CDPEAC routines, and describes in particular tools that can be used to debug routines under DPSIM, the DP simulator.

7.1 DPSIM Data

The DPSIM data are kept in arrays. The data and control registers are in statically allocated int arrays named “dpv data,heap regs 0,1,2,3.” The 10 main control registers begin at register 64:

   64 dp_alu_mode
   65 dp_vector_length
   66 dp_stride_memory
   67 dp_stride_rs1
   68 dp_vector_mask
   69 dp_vector_mask_buffer
   70 dp_vector_mask_mode
   71 dp_vector_mask_direction
   72 dp_status_enable
   73 dp_status

The content of the register arrays can be printed using pndbx’s array printing mode. For example:

 print dpv_data_regs_0(REGNUM : REGNUM + N - 1 : 1)

will print the contents of data registers REGNUM through REGNUM + N - 1. The final :1 is the stride over the registers.

Stack and heap data are located in dynamically allocated integer arrays named “dpv stack,heap data 0,1,2,3.” To convert a byte address to an offset into one of these arrays, the high-order 4 bits of the address should be masked out with 0xFFFFFFF, the address should be converted to an int offset with a /4, and an optional offset from the address can be added in. For example:

 print dpv_stack_data_0[((ADDRESS & 0xFFFFFFF) / 4) + 1]

will print the first word after address “ADDRESS”.

7.2 Viewing DPSIM VU Registers in pndbx

If you include in your .pndbxinit file aliases of the form:

 alias v0  "print dpv_data_regs_0(0:8:1)"

You can view the contents of the VU registers by typing their names at the pndbx prompt. There is a generic .pndbx file in /proj/starlisp/cdpeac/doc/.pndbxinit to start with. It also defines aliases for the control registers.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199211

8 Instruction Set

The following is a comprehensive listing of the macros available to the CDPEAC programmer.

8.1 Metasyntactic Conventions

There are two metasyntactic conventions used in the following instruction summary. The first is that curly brackets { and } indicate that one of the included options must be specified. For example add{s,v} means adds or addv. The other convention is that square brackets [ and ] indicate optional elements. For example, addv[i] means addv or addvi.

8.2 Standard Instruction Variants

Most CDPEAC instructions have the following variants, where inst is some basic operation:

 inst{s,v}[i](type, sdreg, ddreg)
 inst{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

This means that the following macros are available:

 insts(type, sdreg, ddreg)

Scalar; do the operation from a scalar register into a scalar register.

 instsi(type, sdreg, ddreg)

Scalar immediate; do the operation from an immediate value into a scalar register.

 insts_v(type, vlen, sdreg, ddreg)

Scalar with vector length; do the operation from a scalar register into a scalar register, temporarily setting the vector length to vlen.

 insts_vs(type, vlen, sdreg, ddreg)

Scalar vector length set; do the operation from a scalar register into a scalar register, using and setting the vector length to vlen.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199212

 insts_vh(type, vlen, sdreg, ddreg)

Scalar with vector length as register; do the operation from a scalar register into a scalar register, temporarily setting the vector length to bits 19:25 of vlen plus one.

 insts_vhs(type, vlen, sdreg, ddreg)

Scalar with vector length as register set; do the operation from a scalar register into a scalar register, using and setting the vector length to bits 19:25 of vlen plus one.

 instv(type, sdreg, ddreg)

Vector; do the operation from a vector register into a vector register.

 instvi(type, sdreg, ddreg)

Vector; do the operation from an immediate value into a vector register. The immediate value can be a real immediate value, or a register variable.

 instv_v(type, vlen, sdreg, ddreg)

Vector with vector length; do the operation from a vector register vector a vector register, temporarily setting the vector length to vlen.

 instv_vs(type, vlen, sdreg, ddreg)

Vector vector length set; do the operation from a vector register into a vector register, using and setting the vector length to vlen.

 instv_vh(type, vlen, sdreg, ddreg)

Vector with vector length as register; do the operation from a vector register into a vector register, temporarily setting the vector length to bits 19:25 of vlen plus one.

 instv_vhs(type, vlen, sdreg, ddreg)

Vector with vector length as register set; do the operation from a vector register into a vector register, using and setting the vector length to bits 19:25 of vlen plus one.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199213

8.3 Join Operations

In order to join instructions, they must generate a single dpas instruction.

 join(instruction1,instruction2);

Join two CDPEAC instructions so that they are executed simulataneously.

 join2(instruction1,instruction2);

Join two CDPEAC instructions so that they are executed simulataneously.

 join3(instruction1,instruction2,instruction3);

Join three CDPEAC instructions so that they are executed simulataneously.

 join4(instruction1,instruction2,instruction3,instruction4);

Join four CDPEAC instructions so that they are executed simulataneously.

 join5(instruction1,instruction2,instruction3,instruction4,instruction5);

Join five CDPEAC instructions so that they are executed simulataneously.

8.4 Accessors

 dpwrt(type, selector, src, dreg)

Write a value to the DP register dreg, synchronizing with previous vector unit instructions according to the current setting of the synchronization mode.

 dpwrt_sync(type, selector, src, dreg)

Write a value to the DP register dreg, synchronizing with previous vector unit instructions.

 dpwrt_nosync(type, selector, src, dreg)

Write a value to the DP register dreg, without synchronizing with previous vector unit instructions.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199214

 dprd(type, selector, dreg, dst)

Read a value from the DP register dreg, synchronizing with previous vector unit instructions according to the current setting of the synchronization mode.

 dprd_sync(type, selector, dreg, dst)

Read a value from the DP register dreg, synchronizing with previous vector unit instructions.

 dprd_nosync(type, selector, dreg, dst)

Read a value from the DP register dreg, wihtout synchronizing with previous vector unit instructions.

 dpset(type, selector, src, creg)

Write a value to the Datapath control register creg.

 dpset_supervisor(type, selector, src, creg)

Write a value to the Datapath control register creg. Use the virtual address at which the supervisor maps the Datapath control register into its address space. This should only be used in the supervisor mode.

 dpget(type, selector, creg, dst)

Read a value from the Datapath control register creg.

 dpget_supervisor(type, selector, creg, dst)

Read a value from the Datapath control register creg. Use the virtual address at which the supervisor maps the Datapath control register into its address space. This should only be used in the supervisor mode.

 dpld(type, src, dst)

Load a value from the Parallel Data Space into a C register variable.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199215

 dpst(type, src, dst)

Store a value into the Parallel Data Space from a C register variable.

 dpchgsp(src, dst)

Change space; convert a virtual address from a Parallel Instruction Space address into the corresponding Parallel Data Space address or vice versa.

 dpchgbk(src, selector, dst)

Change bank; convert a virtual address from the Parallel Instruction Space or the Parallel Data Space and poin to the corresponding address in the memory bank of another vector unit.

8.5 Control Instructions

 dpsync()

This instruction generates code to cause the previous and next DP instructions to be synchronized.

 ldvm(dreg)

Load the vector mask from the scalar register given.

 stvm(dreg)

Store the vector mask into the scalar register given.

 dpsetup()

Sets up the vector units so that they can interact with C code. This must be present in every CDPEAC function. Very nasty things will happen if you do not call this in every CDPEAC function.

 dpcleanup()

Cleans up the mode settings of the vector units that are set up in dpsetup.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199216

 dreg_x(dreg, index)

This specifies a register as an index from another register. The register that is index registers away from dreg is specified.

 dreg_i(dreg, ireg)

This specifies a register as indexed by another register. The register that is the number in ireg registers away from dreg is specified.

 dreg_u(dreg, stride)

This specifies the register stride that is used to reach the next register. If vlen is the value of the vector length register, the vector register made up of the vlen registers with a stride of stride starting with register dreg is specified.

 dreg_s(dreg, setstride)

This specifies the register stride that is used to reach the next register. If vlen is the value of the vector length register, the vector register made up of the vlen registers with a stride of setstride starting with register dreg is specified. The register stride is sticky set by this instruction.

 dreg_u_s(dreg, stride, setstride)

This specifies the register stride that is used to reach the next register. If vlen is the value of the vector length register, the vector register made up of the vlen registers with a stride of stride starting with register dreg is specified. As a side effect, the register stride is sticky set to setstride.

 scalar(dreg)

Use the scalar value as a constant vector in a vector instruction. The SCALAR macro is the same as this one.

 SCALAR(dreg)

Use the scalar value as a constant vector in a vector instruction. The scalar macro is the same as this one.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199217

8.6 Mode Setting Operations

 vmmode(mode)
 vmmode_s(mode)

These instructions set the vector mask mode. The s variant sticky sets the mode. The available modes are: always, condmem, condalu, cond.

 vmold
Copies the contents of dp vector mask buffer to dp vector mask.
 vmnew
Copies the contents of dp vector mask to dp vector mask buffer.
 vmnop

No copy. The vector mask and vector mask buffer are unchanged.

 vmcurrent

Write status to incrementing bit numbers in dp vector mask.

 vmrotate

Write status to rotating dp vector mask.

 vminvert

Invert sense of vector mask bits for conditionalization.

 vmtrue

Do not invert sense of vector mask bits.

 align

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199218 Declares that even though the memory operation is in single precision, that the memory address is doubleword aligned. Specifying this allows the generation of faster code.

 exchange

Exchange results with the other DP on the DASH chip.

 noexchange

Do not exchange results with the other DP on the DASH chip.

 nopad

Do not artificially pad the effective vector length.

 pad(n)

Execute instructions with an effective vector length of n, in order to avoid pipeline hazards.

 vmcount(dreg)

Enable vector mask count into register dreg.

 vmcountv(dreg)

Puts the result of a vector mask count into vector register dreg.

 vmcounts(dreg)

Puts the result of a vector mask count into scalar register dreg.

 set_vmmode(vmmode)

Sticky set the vector mask mode.

 set_mem_stride(stride)

Sticky set the memory stride.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199219

 set_rs1_stride(rs1_stride)

Sticky set the rs1 stride.

 set_vector_length(vlen)

Sticky set the vector length.

 set_vector_length_and_vmmode(vlen, vmmode)

Sticky set the vector length and vector mask mode.

 set_vector_length_and_rs1_stride(vlen, rs1_stride)

Sticky set the vector length and rs1 stride.

 set_vector_length_and_rs1_stride_and_vmmode(vlen, rs1_stride, vmmode)

Sticky set the vector length, rs1 stride, and vector mask mode.

8.7 Memory Operations

8.7.1 Loading Into VU Registers

 load{s,v}(type, memop, dreg)

Load a vector or scalar from the memory location memop into dreg.

 load{s,v}_i(type, memop, ireg, dreg)

Load the contents of dreg with the contents of the indirect memory address calculated by adding the contents of ireg to the memory location memop.

 load{s,v}_{v,vs,vh,vhs}(type, vlen, memop, dreg)

Load a vector or scalar from the memory location memop into dreg, using the vector length given. The vector length is set as in the standard instruction variants described above.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199220

 load{s,v}_u(type, memop, ustride, dreg)

Load a vector or scalar from the memory location memop into dreg. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types.

 load{s,v}_s(type, memop, sstride, dreg)

Load a vector or scalar from the memory location memop into dreg. The memory stride is set to the value of sstride.

 load{s,v}_u_s(type, memop, ustride, sstride, dreg)

Load a vector or scalar from the memory location memop into dreg. This operation simultaneously overrides and sets the memory stride. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types. The default memory stride is set to the value of sstride for later operations.

 load{s,v}_v_u(type, vlen, memop, ustride, dreg)

Load a vector or scalar from the memory location memop into dreg. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types. The vector length is temporarily set to the value of vlen. 8.7.2 Storing From VU Registers

 store{s,v}(type, memop, dreg)

Store a vector or scalar into the memory location memop from dreg.

 store{s,v}_i(type, memop, ireg, dreg)

Store the contents of dreg into the location of the indirect memory address calculated by adding the contents of ireg to the memory location memop.

 store{s,v}_{v,vs,vh,vhs}(type, vlen, memop, dreg)

Store a vector or scalar into the memory location memop from dreg, using the vector length given. The vector length is set as in the standard instruction variants described above.

 store{s,v}_u(type, memop, ustride, dreg)

Store a vector or scalar into the memory location memop from dreg. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types.

 store{s,v}_s(type, memop, sstride, dreg)

Store a vector or scalar into the memory location memop from dreg. The memory stride is set to the value of sstride.

 store{s,v}_u_s(type, memop, ustride, sstride, dreg)

Store a vector or scalar into the memory location memop from dreg. This operation simultaneously overrides and sets the memory stride. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types. The default memory stride is set to the value of sstride for later operations.

 store{s,v}_v_u(type, vlen, memop, ustride, dreg)

Store a vector or scalar into the memory location memop from dreg. The memory stride is temporarily set to the constant value of ustride, which must be 4 or 8 for single word data types, or 8 or 16 for double word data types. The vector length is temporarily set to the value of vlen.

 fnop{s,v}{i}()
 fnop{s,v}_{v,vs,vh,vhs}()

8.7.3 Register To Register Moves

 move{s,v}[i](type, sdreg, ddreg)
 move{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

Move the contents of sdreg to ddreg.

8.8 Monadic Operations

 test{s,v}[i](type, sdreg, ddreg)
 test{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199222 Adds the value in sdreg to zero and puts it in ddreg, asserting status outputs.

neg{s,v}[i](type, sdreg, ddreg)
neg{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

Subtracts the value in sdreg from zero, and puts the result in ddreg. Integer overflows will be signaled, but the result will not be saturated. Negative results for unsigned integers will be saturated to zero, and the negative-unsigned flag will be asserted.

abs{s,v}[i](type, sdreg, ddreg)
abs{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

Adds the absolute value of the value in sdreg to zero and puts it in ddreg.

not{s,v}[i](type, sdreg, ddreg)
not{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

The bitwise logical NOT of the value in sdreg is placed in ddreg.

tos{s,v}[i](type, sdreg, ddreg)
tos{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)
sqrt{s,v}[i](type, sdreg, ddreg)
sqrt{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

The square root of the value in sdreg is stored in dreg.

ffb{s,v}[i](type, sdreg, ddreg)
ffb{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

Find first bit – returns the bit position of the most significant 1 in the unsigned input as the distance from the most significant bit of a 64-bit integer. If the operand is equal to zero, the result is zero.

inv{s,v}[i](type, sdreg, ddreg)
inv{s,v}_{v,vs,vh,vhs}(type, vlen, sdreg, ddreg)

The reciprocal of the value in sdreg is put in ddreg.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199223

8.9 Arithmetic Instructions

8.9.1 Dyadic Arithmetic Instructions

add{s,v}[i](type, s1dreg, s2dreg, ddreg)
add{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Add the values in s1dreg and s2dreg, placing the result in ddreg.

addc{s,v}[i](type, s1dreg, s2dreg, ddreg)
addc{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Add the values in s1dreg and s2dreg, placing the result in ddreg. A carry bit is added depending on the contents of the vector mask.

sub{s,v}[i](type, s1dreg, s2dreg, ddreg)
sub{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Subtract the value in s2dreg from the value in s1dreg, placing the result in ddreg.

subc{s,v}[i](type, s1dreg, s2dreg, ddreg)
subc{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Subtract the value in s2dreg from the value in s1dreg, placing the result in ddreg, with carry bits in the vector mask.

subr{s,v}[i](type, s1dreg, s2dreg, ddreg)
subr{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Subtract the value in s1dreg from the value in s2dreg, placing the result in ddreg.

sbrc{s,v}[i](type, s1dreg, s2dreg, ddreg)
sbrc{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Subtract the value in s1dreg from the value in s2dreg, placing the result in ddreg, with carry bits in the vector mask.

mul{s,v}[i](type, s1dreg, s2dreg, ddreg)
mul{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Multiply the values in s1reg and s2reg, placing the result in ddreg. Multiplication of 32-bit integers will produce a 64-bit result. If the type 64-bit integer, the low 64 bits of the result is placed in ddreg.

 mulh{s,v}[i](type, s1dreg, s2dreg, ddreg)
 mulh{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Multiply the 64-bit integer values in s1reg and s2reg, placing the high-order 64 bits of the result in ddreg.

 div{s,v}[i](type, s1dreg, s2dreg, ddreg)
 div{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Divide the contents of s1dreg by the contents of s2dreg, placing the result in ddreg.

 enc{s,v}[i](type, s1dreg, s2dreg, ddreg)
 enc{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Generates a floating-point result by placing the value in s1dreg in the exponent field and the value of s2dreg in the mantissa field. The result is placed in ddreg.

8.9.2 Logical Shift Operations

 shl{s,v}[i](type, s1dreg, s2dreg, ddreg)
 shl{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Shift left the unsigned integer in s1dreg by the number of bits specified in the low 6 bits

of s2dreg.
 shlr{s,v}[i](type, s1dreg, s2dreg, ddreg)
 shlr{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Shift left reversed the unsigned integer in s1dreg by the number of bits specified in the low 6 bits of s2dreg.

 shr{s,v}[i](type, s1dreg, s2dreg, ddreg)
 shr{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Shift right the signed contents of s1dreg by the number of bits specified in the low 6 bits of s2dreg and sign extend the result.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199225

shrr{s,v}[i](type, s1dreg, s2dreg, ddreg)
shrr{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Shift right reversed the signed contents of s1dreg by the number of bits specified in the low 6 bits of s2dreg and sign extend the result. 8.9.3 Bitwise Logical Operators

and{s,v}[i](type, s1dreg, s2reg, ddreg)
and{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical AND of s1reg and s2reg.

nand{s,v}[i](type, s1dreg, s2dreg, ddreg)
nand{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical NAND of s1reg and s2reg.

andc{s,v}[i](type, s1dreg, s2dreg, ddreg)
andc{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical ANDC of s1reg and s2reg, equivalent to Ã & B.

or{s,v}[i](type, s1dreg, s2dreg, ddreg)
or{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical OR of s1reg and s2reg.

nor{s,v}[i](type, s1dreg, s2dreg, ddreg)
nor{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical NOR of s1reg and s2reg.

xor{s,v}[i](type, s1dreg, s2dreg, ddreg)
xor{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

Bitwise logical XOR (exclusive or) of s1reg and s2reg.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199226 8.9.4 Logical Comparison

gt{s,v}[i](type, s1dreg, s2dreg)
gt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is greater than the value in s2dreg.

ge{s,v}[i](type, s1dreg, s2dreg)
ge{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is greater than or equal to the value in s2dreg.

lt{s,v}[i](type, s1dreg, s2dreg)
lt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is less than the value in s2dreg.

le{s,v}[i](type, s1dreg, s2dreg)
le{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is less than or equal to the value in s2dreg.

eq{s,v}[i](type, s1dreg, s2dreg)
eq{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is equal to the value in s2dreg.

ne{s,v}[i](type, s1dreg, s2dreg)
ne{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the value in s1dreg is not equal to the value in s2dreg, or the values are unordered.

lg{s,v}[i](type, s1dreg, s2dreg)
lg{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the values in s1dreg and s2dreg are unordered and not equal.

un{s,v}[i](type, s1dreg, s2dreg)
un{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg)

Assert status if the values in s1dreg and s2dreg unordered.

 cmp{s,v}[i](type, s1dreg, s2dreg, odreg)
 cmp{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, odreg)

Compare the values in s1reg and s2dreg, asserting status. The comparison done depends on the value of the opcode in odreg as follows:

   0 greater than
   1 equal
   2 less than
   3 greater than or equal
   4 unordered
   5 less than or greater than
   6 not equal
   7 less than or equal

This instruction is supported only for completeness. The specific compares are preferred.

8.9.5 The Merge Instruction

 mrg{s,v}[i](type, s1dreg, s2dreg, ddreg)
 mrg{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The merge instruction; elements of s1dreg are copied to ddreg when the vector mask bit is 1, and elements if s2dreg are copied to ddreg when the vector mask bit is 0.

8.10 Dyadic Two-operation Operations

The legal types for these operations are: i, di, u, du, f, df

 mada{s,v}[i](type, s1dreg, s2dreg, ddreg)
 mada{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of adding the value in ddreg to the product of s1dreg and s2dreg is placed in

ddreg.
 msba{s,v}[i](type, s1dreg, s2dreg, ddreg)
 msba{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the value in ddreg from the product of s1dreg and s2dreg is placed in ddreg.

 msra{s,v}[i](type, s1dreg, s2dreg, ddreg)
 msra{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the product of s1dreg and s2dreg from the value in ddreg is placed in ddreg.

 nmaa{s,v}[i](type, s1dreg, s2dreg, ddreg)
 nmaa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the product of s1dreg and s2dreg from the negation of the value in ddreg is placed in ddreg.

 madi{s,v}[i](type, s1dreg, s2dreg, ddreg)
 madi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of adding the value in ddreg to the product of s1dreg and s2dreg is placed in

ddreg.
 madi{s,v}[i](type, s1dreg, s2dreg, ddreg)
 madi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the value in s1dreg from the product of ddreg and s2dreg is placed in ddreg.

 msri{s,v}[i](type, s1dreg, s2dreg, ddreg)
 msri{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the the product of ddreg and s2dreg from the value in s1dreg is placed in ddreg.

 nmai{s,v}[i](type, s1dreg, s2dreg, ddreg)
 nmai{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The result of subtracting the the product of ddreg and s2dreg from the negation of the value in s1dreg is placed in ddreg.

8.11 Triadic Operations

8.11.1 Dyadic Multiply with Arithmetic Instructions

The following operations combine a multiply operation with an addition or subtraction operation.

 madt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
 madt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)
The result of (s1dreg * s2dreg) + s3dreg is placed in ddreg.
 msbt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
 msbt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)
The result of (s1dreg * s2dreg) - s3dreg is placed in ddreg.
 msrt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
 msrt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)
The result of s3dreg - (s1dreg * s2dreg) is placed in ddreg.
 nmat{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
 nmat{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)
The the result of -s3dreg - (s1dreg * s2dreg) is placed in ddreg.

8.11.2 Multiply with Logical Instructions

These instructions combine a 64-bit multiply and a 64-bit bitwise logical operation. The pattern is as follows: the first letter of the mnemonic is always m. This is followed by an optional h; the h being present indicates that the high order 64 bits of the result of the operation are placed in ddreg. Otherwise the low order 64 bits are placed in ddreg.

The next letter in the mnemonic determines which logical operation is to be combined with a multiply operation. There are four logical operations that can be combined with a multiply, and these are select (AND), mask (AND-NOT), OR, and XOR. Their respective letters in the mnemonic are s, m, o, and x.

 msa{s,v}[i](type, s1dreg, s2dreg, ddreg)
 msa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199230 The low-order word of the result of (s1dreg * s2dreg) AND ddreg is placed in ddreg.

msi{s,v}[i](type, s1dreg, s2dreg, ddreg)
msi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) AND ddreg) is placed in

ddreg.
mma{s,v}[i](type, s1dreg, s2dreg, ddreg)
mma{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of (s1dreg * s2dreg) AND-NOT ddreg is placed in ddreg.

mmi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mmi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) AND-NOT ddreg) is placed in

ddreg.
moa{s,v}[i](type, s1dreg, s2dreg, ddreg)
moa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) OR ddreg) is placed in ddreg.

moi{s,v}[i](type, s1dreg, s2dreg, ddreg)
moi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) OR ddreg) is placed in ddreg.

mxa{s,v}[i](type, s1dreg, s2dreg, ddreg)
mxa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) XOR ddreg) is placed in

ddreg.
mxi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mxi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The low-order word of the result of NOT((s1dreg * s2dreg) XOR ddreg) is placed in

ddreg.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199231

mhsa{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhsa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg

The high-order word of the result of (s1dreg * s2dreg) AND ddreg is placed in ddreg.

mhsi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhsi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of NOT((s1dreg * s2dreg) AND ddreg) is placed in

ddreg.
mhma{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhma{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) AND-NOT ddreg is placed in

ddreg.
mhmi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhmi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of NOT((s1dreg * s2dreg) AND-NOT ddreg) is placed

in ddreg.
mhoa{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhoa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) OR ddreg is placed in ddreg.

mhoi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhoi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of NOT((s1dreg * s2dreg) OR ddreg) is placed in

ddreg.
mhxa{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhxa{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) XOR ddreg is placed in ddreg.

mhxi{s,v}[i](type, s1dreg, s2dreg, ddreg)
mhxi{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, ddreg)

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199232 The high-order word of the result of NOT((s1dreg * s2dreg) XOR ddreg) is placed in

ddreg.
mst{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mst{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The low-order word of the result of (s1dreg * s2dreg) AND s3dreg is placed in ddreg.

mmt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mmt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The low-order word of the result of (s1dreg * s2dreg) AND-NOT s3dreg is placed in

ddreg.
mot{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mot{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The low-order word of the result of (s1dreg * s2dreg) OR s3dreg is placed in ddreg.

mxt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mxt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The low-order word of the result of (s1dreg * s2dreg) XOR s3dreg is placed in ddreg.

mhst{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mhst{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) AND s3dreg is placed in ddreg.

mhmt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mhmt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) AND-NOT s3dreg is placed in

ddreg.
mhot{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mhot{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) OR s3dreg is placed in ddreg.

mhxt{s,v}[i](type, s1dreg, s2dreg, s3dreg, ddreg)
mhxt{s,v}_{v,vs,vh,vhs}(type, vlen, s1dreg, s2dreg, s3dreg, ddreg)

The high-order word of the result of (s1dreg * s2dreg) XOR s3dreg is placed in ddreg.

CDPEAC: Using GCC to Program in DPEAC – TMC Confidential – September 11, 199233

8.12 Population Count

 epc{s,v}(type, sdreg, ddreg)

A population count of the value in sdreg is placed in ddreg.