Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
308 changes: 308 additions & 0 deletions mlir/include/mlir/Dialect/DXSA/IR/DXSADoubleArithOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
//===- DXSADoubleArithOps.td - DXSA double arithmetic ops -*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Double-precision arithmetic instructions of the DXSA dialect.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_DXSA_IR_DXSADOUBLEARITHOPS
#define MLIR_DIALECT_DXSA_IR_DXSADOUBLEARITHOPS

include "mlir/Dialect/DXSA/IR/DXSAOpBase.td"

//===----------------------------------------------------------------------===//
// dxsa.dadd
//===----------------------------------------------------------------------===//

def DXSA_Dadd : DXSA_BinaryOp<"dadd"> {
let summary = "component-wise double-precision add";
let description = [{
The `dxsa.dadd` operation computes the component-wise double-precision
sum `$dst = $lhs + $rhs`. Each operand holds a vector of doubles, one
double per `xy` and `zw` component pair.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dadd r<0>, r<1>, r<2>
dxsa.dadd r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dadd_sat
//===----------------------------------------------------------------------===//

def DXSA_DaddSat : DXSA_BinaryOp<"dadd_sat"> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing in the documentation that _sat is an instruction modifier, these aren't actually separate instructions? In that case, would it make sense to find a way to avoid duplicating almost every instruction?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to support _sat as a separate instruction (s) and a lot of instructions already implemented in this manner.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems inconsistent with the logic @asl gave in #194 against structured MLIR: "This is a bytecode dialect." In the bytecode, these aren't separate opcodes, so if we're modelling the MLIR after what the bytecode looks like, they shouldn't be separate instructions.

If it's decided that we're doing things this way then I'm of course not going to hold up this PR over it; I'm just leaving this comment to make it clear to anyone reading that it's intentional.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asl what do you mean?

let summary = "component-wise double-precision add, saturated to [0, 1]";
let description = [{
The `dxsa.dadd_sat` operation computes the component-wise double-precision
sum of `$lhs` and `$rhs`, clamps each result component to `[0.0, 1.0]`,
and writes it to `$dst`.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dadd_sat r<0>, r<1>, r<2>
dxsa.dadd_sat r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.ddiv
//===----------------------------------------------------------------------===//

def DXSA_Ddiv : DXSA_BinaryOp<"ddiv"> {
let summary = "component-wise double-precision divide";
let description = [{
The `dxsa.ddiv` operation computes the component-wise double-precision
quotient `$dst = $lhs / $rhs`. Each operand holds a vector of doubles, one
double per `xy` and `zw` component pair.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.ddiv r<0>, r<1>, r<2>
dxsa.ddiv r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.ddiv_sat
//===----------------------------------------------------------------------===//

def DXSA_DdivSat : DXSA_BinaryOp<"ddiv_sat"> {
let summary = "component-wise double-precision divide, saturated to [0, 1]";
let description = [{
The `dxsa.ddiv_sat` operation computes the component-wise double-precision
quotient of `$lhs` and `$rhs`, clamps each result component to
`[0.0, 1.0]`, and writes it to `$dst`.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.ddiv_sat r<0>, r<1>, r<2>
dxsa.ddiv_sat r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmax
//===----------------------------------------------------------------------===//

def DXSA_Dmax : DXSA_BinaryOp<"dmax"> {
let summary = "component-wise double-precision maximum";
let description = [{
The `dxsa.dmax` operation computes the component-wise double-precision
maximum `$dst = $lhs >= $rhs ? $lhs : $rhs`. If one source component is
NaN, the other source component is returned.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmax r<0>, r<1>, r<2>
dxsa.dmax r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmax_sat
//===----------------------------------------------------------------------===//

def DXSA_DmaxSat : DXSA_BinaryOp<"dmax_sat"> {
let summary = "component-wise double-precision maximum, saturated to [0, 1]";
let description = [{
The `dxsa.dmax_sat` operation computes the component-wise double-precision
maximum of `$lhs` and `$rhs`, clamps each result component to `[0.0, 1.0]`,
and writes it to `$dst`. If one source component is NaN, the other source
component is used.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmax_sat r<0>, r<1>, r<2>
dxsa.dmax_sat r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmin
//===----------------------------------------------------------------------===//

def DXSA_Dmin : DXSA_BinaryOp<"dmin"> {
let summary = "component-wise double-precision minimum";
let description = [{
The `dxsa.dmin` operation computes the component-wise double-precision
minimum `$dst = $lhs < $rhs ? $lhs : $rhs`. If one source component is
NaN, the other source component is returned.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmin r<0>, r<1>, r<2>
dxsa.dmin r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmin_sat
//===----------------------------------------------------------------------===//

def DXSA_DminSat : DXSA_BinaryOp<"dmin_sat"> {
let summary = "component-wise double-precision minimum, saturated to [0, 1]";
let description = [{
The `dxsa.dmin_sat` operation computes the component-wise double-precision
minimum of `$lhs` and `$rhs`, clamps each result component to `[0.0, 1.0]`,
and writes it to `$dst`. If one source component is NaN, the other source
component is used.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmin_sat r<0>, r<1>, r<2>
dxsa.dmin_sat r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmul
//===----------------------------------------------------------------------===//

def DXSA_Dmul : DXSA_BinaryOp<"dmul"> {
let summary = "component-wise double-precision multiply";
let description = [{
The `dxsa.dmul` operation computes the component-wise double-precision
product `$dst = $lhs * $rhs`. Each operand holds a vector of doubles, one
double per `xy` and `zw` component pair.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmul r<0>, r<1>, r<2>
dxsa.dmul r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.dmul_sat
//===----------------------------------------------------------------------===//

def DXSA_DmulSat : DXSA_BinaryOp<"dmul_sat"> {
let summary = "component-wise double-precision multiply, saturated to [0, 1]";
let description = [{
The `dxsa.dmul_sat` operation computes the component-wise double-precision
product of `$lhs` and `$rhs`, clamps each result component to `[0.0, 1.0]`,
and writes it to `$dst`.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and each source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.dmul_sat r<0>, r<1>, r<2>
dxsa.dmul_sat r<0, <x, y>>, r<1, <z, w, x, y>>, -r<2>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.drcp
//===----------------------------------------------------------------------===//

def DXSA_Drcp : DXSA_UnaryOp<"drcp"> {
let summary = "component-wise double-precision reciprocal";
let description = [{
The `dxsa.drcp` operation computes the component-wise double-precision
reciprocal `$dst = 1.0 / $src`. Each operand holds a vector of doubles, one
double per `xy` and `zw` component pair.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and the source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.drcp r<0>, r<1>
dxsa.drcp r<0, <x, y>>, -r<1, <z, w, x, y>>
```
}];
}

//===----------------------------------------------------------------------===//
// dxsa.drcp_sat
//===----------------------------------------------------------------------===//

def DXSA_DrcpSat : DXSA_UnaryOp<"drcp_sat"> {
let summary = "component-wise double-precision reciprocal, saturated to [0, 1]";
let description = [{
The `dxsa.drcp_sat` operation computes the component-wise double-precision
reciprocal of `$src`, clamps each result component to `[0.0, 1.0]`, and
writes it to `$dst`.

Because each double spans a component pair, the destination write mask must
be `<x, y>`, `<z, w>`, or `<x, y, z, w>`, and the source swizzle must be
one of `<x, y, z, w>`, `<x, y, x, y>`, `<z, w, x, y>`, or `<z, w, z, w>`.

Example:

```mlir
dxsa.drcp_sat r<0>, r<1>
dxsa.drcp_sat r<0, <x, y>>, -r<1, <z, w, x, y>>
```
}];
}

#endif // MLIR_DIALECT_DXSA_IR_DXSADOUBLEARITHOPS
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
include "mlir/Dialect/DXSA/IR/DXSAOpBase.td"
include "mlir/Dialect/DXSA/IR/DXSATypes.td"
include "mlir/Dialect/DXSA/IR/DXSAFPArithOps.td"
include "mlir/Dialect/DXSA/IR/DXSADoubleArithOps.td"
include "mlir/Dialect/DXSA/IR/DXSAConditionOps.td"
include "mlir/Dialect/DXSA/IR/DXSABitwiseOps.td"
include "mlir/Dialect/DXSA/IR/DXSATypeConversionOps.td"
Expand Down
13 changes: 13 additions & 0 deletions mlir/lib/Target/DXSA/BinaryParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2426,6 +2426,19 @@ class Parser {
return PLAIN_OP(AtomicUMax, 1, 2, HasPreciseAttr::No);
case D3D11_SB_OPCODE_ATOMIC_UMIN:
return PLAIN_OP(AtomicUMin, 1, 2, HasPreciseAttr::No);
// Double-precision arithmetic instructions
case D3D11_SB_OPCODE_DADD:
return SATURABLE_OP(Dadd, 1, 2, HasPreciseAttr::Yes);
case D3D11_SB_OPCODE_DMAX:
return SATURABLE_OP(Dmax, 1, 2, HasPreciseAttr::Yes);
case D3D11_SB_OPCODE_DMIN:
return SATURABLE_OP(Dmin, 1, 2, HasPreciseAttr::Yes);
case D3D11_SB_OPCODE_DMUL:
return SATURABLE_OP(Dmul, 1, 2, HasPreciseAttr::Yes);
case D3D11_1_SB_OPCODE_DDIV:
return SATURABLE_OP(Ddiv, 1, 2, HasPreciseAttr::Yes);
case D3D11_1_SB_OPCODE_DRCP:
return SATURABLE_OP(Drcp, 1, 1, HasPreciseAttr::Yes);
}
#undef SATURABLE_OP
#undef PLAIN_OP
Expand Down
Loading