vmad GPU Virtual ISA NVIDIA

vmad Scalar Video Instructions

// 32-bit scalar operation
vmad.dtype.atype.btype{.sat}{.scale} d, {-}a{.asel}, {-}b{.bsel},
{-}c;

Calculate (a*b) + c, with optional operand negates, plus one mode, and scaling. The source operands support optional negation with some restrictions.

Encoding

PTX is a virtual instruction set. It has no single, stable native binary encoding - the compiler lowers this instruction to different native machine code depending on the selected NVIDIA target architecture (compute capability). This page intentionally shows no bit-diagram; see the target/version requirements below for what governs how this instruction compiles.
PTX ISA Version Introduced PTX ISA 2.0
Minimum Target sm_20

Syntax Forms

One mnemonic covers many type / state-space / scope / modifier combinations - each row below is an independently valid form.

Syntax Data Types State Space(s) Modifiers Min. Target Description
// 32-bit scalar operation vmad.dtype.atype.btype{.sat}{.scale} d, {-}a{.asel}, {-}b{.bsel}, {-}c; sm_20 Calculate (a*b) + c, with optional operand negates, plus one mode, and scaling. The source operands support optional negation with some restrictions. (see the official PTX ISA docs for the full description)

Operands

At a Glance

Data Types -

Related

More in Scalar Video Instructions

Reference

NVIDIA PTX ISA

Description

Calculate (a*b) + c, with optional operand negates, plus one mode, and scaling. The source operands support optional negation with some restrictions. Although PTX syntax allows separate negation of the a and b operands, internally this is represented as negation of the product (a*b). That is, (a*b) is negated if and only if exactly one of a or b is negated. PTX allows negation of either (a*b) or c. The plus one mode (.po ) computes (a*b) + c + 1, which is used in computing averages. Source operands may not be negated in.po mode. The intermediate result of (a*b) is unsigned if atype and btype are unsigned and the product (a*b) is not negated; otherwise, the intermediate result is signed. (see the official PTX ISA docs for the full description)

Semantics

// extract byte/half-word/word and sign- or zero-extend // based on source operand type ta = partSelectSignExtend( a, atype, asel ); tb = partSelectSignExtend( b, btype, bsel ); signedFinal = isSigned(atype) || isSigned(btype) || (a.negate ^ b.negate) || c.negate; tmp[127:0] = ta * tb; lsb = 0; if ( .po ) { lsb = 1; } else if ( a.negate ^ b.negate ) { tmp = ~tmp; lsb = 1; } else if ( c.negate ) { c = ~c; lsb = 1; } c128[127:0] = (signedFinal) sext32( c ) : zext ( c ); tmp = tmp + c128 + lsb; switch( scale ) { case .shr7: result = (tmp >> 7) & 0xffffffffffffffff; case .shr15: result = (tmp >> 15) & 0xffffffffffffffff; } if ( .sat ) { if (signedFinal) result = CLAMP(result, S32_MAX, S32_MIN); else result = CLAMP(result, U32_MAX, U32_MIN); }

Examples

vmad.s32.s32.u32.sat    r0, r1, r2, -r3;
vmad.u32.u32.u32.shr15  r0, r1.h0, r2.h0, r3;

Reproduced from NVIDIA's official PTX ISA documentation for technical accuracy.

Sources