Add meta definitions for floating point operations.
Rename the Select instruction format to Ternary since it is also used by the fma instruction.
This commit is contained in:
@@ -771,73 +771,48 @@ Floating point operations
|
|||||||
These operations generally follow IEEE 754-2008 semantics.
|
These operations generally follow IEEE 754-2008 semantics.
|
||||||
|
|
||||||
.. autoinst:: fcmp
|
.. autoinst:: fcmp
|
||||||
|
.. autoinst:: fadd
|
||||||
|
.. autoinst:: fsub
|
||||||
|
.. autoinst:: fmul
|
||||||
|
.. autoinst:: fdiv
|
||||||
|
.. autoinst:: sqrt
|
||||||
|
.. autoinst:: fma
|
||||||
|
|
||||||
.. inst:: fadd x,y
|
Sign bit manipulations
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Floating point addition.
|
The sign manipulating instructions work as bitwise operations, so they don't
|
||||||
|
have special behavior for signaling NaN operands. The exponent and trailing
|
||||||
|
significand bits are always preserved.
|
||||||
|
|
||||||
.. inst:: fsub x,y
|
.. autoinst:: fneg
|
||||||
|
.. autoinst:: fabs
|
||||||
|
.. autoinst:: fcopysign
|
||||||
|
|
||||||
Floating point subtraction.
|
Minimum and maximum
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. inst:: fneg x
|
These instructions return the larger or smaller of their operands. They differ
|
||||||
|
in their handling of quiet NaN inputs. Note that signaling NaN operands always
|
||||||
|
cause a NaN result.
|
||||||
|
|
||||||
Floating point negation.
|
When comparing zeroes, these instructions behave as if :math:`-0.0 < 0.0`.
|
||||||
|
|
||||||
:result: ``x`` with its sign bit inverted.
|
.. autoinst:: fmin
|
||||||
|
.. autoinst:: fminnum
|
||||||
|
.. autoinst:: fmax
|
||||||
|
.. autoinst:: fmaxnum
|
||||||
|
|
||||||
Note that this is a pure bitwise operation.
|
Rounding
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
.. inst:: fabs x
|
These instructions round their argument to a nearby integral value, still
|
||||||
|
represented as a floating point number.
|
||||||
|
|
||||||
Floating point absolute value.
|
.. autoinst:: ceil
|
||||||
|
.. autoinst:: floor
|
||||||
:result: ``x`` with its sign bit cleared.
|
.. autoinst:: trunc
|
||||||
|
.. autoinst:: nearest
|
||||||
Note that this is a pure bitwise operation.
|
|
||||||
|
|
||||||
.. inst:: a = fcopysign x, y
|
|
||||||
|
|
||||||
Floating point copy sign.
|
|
||||||
|
|
||||||
:result: ``x`` with its sign changed to that of ``y``.
|
|
||||||
|
|
||||||
Note that this is a pure bitwise operation. The sign bit from ``y`` is
|
|
||||||
copied to the sign bit of ``x``.
|
|
||||||
|
|
||||||
.. inst:: a = fmul x, y
|
|
||||||
.. inst:: a = fdiv x, y
|
|
||||||
.. inst:: a = fmin x, y
|
|
||||||
.. inst:: a = fminnum x, y
|
|
||||||
.. inst:: a = fmax x, y
|
|
||||||
.. inst:: a = fmaxnum x, y
|
|
||||||
|
|
||||||
.. inst:: a = ceil x
|
|
||||||
|
|
||||||
Round floating point round to integral, towards positive infinity.
|
|
||||||
|
|
||||||
.. inst:: floor x
|
|
||||||
|
|
||||||
Round floating point round to integral, towards negative infinity.
|
|
||||||
|
|
||||||
.. inst:: trunc x
|
|
||||||
|
|
||||||
Round floating point round to integral, towards zero.
|
|
||||||
|
|
||||||
.. inst:: nearest x
|
|
||||||
|
|
||||||
Round floating point round to integral, towards nearest with ties to even.
|
|
||||||
|
|
||||||
.. inst:: sqrt x
|
|
||||||
|
|
||||||
Floating point square root.
|
|
||||||
|
|
||||||
.. inst:: a = fma x, y, z
|
|
||||||
|
|
||||||
Floating point fused multiply-and-add.
|
|
||||||
|
|
||||||
Computes :math:`a := xy+z` wihtout any intermediate rounding of the
|
|
||||||
product.
|
|
||||||
|
|
||||||
Conversion operations
|
Conversion operations
|
||||||
---------------------
|
---------------------
|
||||||
|
|||||||
@@ -548,7 +548,7 @@ popcnt = Instruction(
|
|||||||
#
|
#
|
||||||
|
|
||||||
Float = TypeVar(
|
Float = TypeVar(
|
||||||
'Float', 'A scalar or vector floating point type type',
|
'Float', 'A scalar or vector floating point number',
|
||||||
floats=True, simd=True)
|
floats=True, simd=True)
|
||||||
|
|
||||||
Cond = Operand('Cond', floatcc)
|
Cond = Operand('Cond', floatcc)
|
||||||
@@ -620,4 +620,145 @@ fcmp = Instruction(
|
|||||||
""",
|
""",
|
||||||
ins=(Cond, x, y), outs=a)
|
ins=(Cond, x, y), outs=a)
|
||||||
|
|
||||||
|
x = Operand('x', Float)
|
||||||
|
y = Operand('y', Float)
|
||||||
|
z = Operand('z', Float)
|
||||||
|
a = Operand('a', Float, 'Result of applying operator to each lane')
|
||||||
|
|
||||||
|
fadd = Instruction(
|
||||||
|
'fadd', r"""
|
||||||
|
Floating point addition.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
fsub = Instruction(
|
||||||
|
'fsub', r"""
|
||||||
|
Floating point subtraction.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
fmul = Instruction(
|
||||||
|
'fmul', r"""
|
||||||
|
Floating point multiplication.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
fdiv = Instruction(
|
||||||
|
'fdiv', r"""
|
||||||
|
Floating point division.
|
||||||
|
|
||||||
|
Unlike the integer division instructions :cton:inst:`sdiv` and
|
||||||
|
:cton:inst:`udiv`, this can't trap. Division by zero is infinity or
|
||||||
|
NaN, depending on the dividend.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
sqrt = Instruction(
|
||||||
|
'sqrt', r"""
|
||||||
|
Floating point square root.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
fma = Instruction(
|
||||||
|
'fma', r"""
|
||||||
|
Floating point fused multiply-and-add.
|
||||||
|
|
||||||
|
Computes :math:`a := xy+z` wihtout any intermediate rounding of the
|
||||||
|
product.
|
||||||
|
""",
|
||||||
|
ins=(x, y, z), outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, '``x`` with its sign bit inverted')
|
||||||
|
fneg = Instruction(
|
||||||
|
'fneg', r"""
|
||||||
|
Floating point negation.
|
||||||
|
|
||||||
|
Note that this is a pure bitwise operation.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, '``x`` with its sign bit cleared')
|
||||||
|
fabs = Instruction(
|
||||||
|
'fabs', r"""
|
||||||
|
Floating point absolute value.
|
||||||
|
|
||||||
|
Note that this is a pure bitwise operation.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, '``x`` with its sign bit changed to that of ``y``')
|
||||||
|
fcopysign = Instruction(
|
||||||
|
'fcopysign', r"""
|
||||||
|
Floating point copy sign.
|
||||||
|
|
||||||
|
Note that this is a pure bitwise operation. The sign bit from ``y`` is
|
||||||
|
copied to the sign bit of ``x``.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, 'The smaller of ``x`` and ``y``')
|
||||||
|
|
||||||
|
fmin = Instruction(
|
||||||
|
'fmin', r"""
|
||||||
|
Floating point minimum, propagating NaNs.
|
||||||
|
|
||||||
|
If either operand is NaN, this returns a NaN.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
fminnum = Instruction(
|
||||||
|
'fminnum', r"""
|
||||||
|
Floating point minimum, suppressing quiet NaNs.
|
||||||
|
|
||||||
|
If either operand is a quiet NaN, the other operand is returned. If
|
||||||
|
either operand is a signaling NaN, NaN is returned.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, 'The larger of ``x`` and ``y``')
|
||||||
|
|
||||||
|
fmax = Instruction(
|
||||||
|
'fmax', r"""
|
||||||
|
Floating point maximum, propagating NaNs.
|
||||||
|
|
||||||
|
If either operand is NaN, this returns a NaN.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
fmaxnum = Instruction(
|
||||||
|
'fmaxnum', r"""
|
||||||
|
Floating point maximum, suppressing quiet NaNs.
|
||||||
|
|
||||||
|
If either operand is a quiet NaN, the other operand is returned. If
|
||||||
|
either operand is a signaling NaN, NaN is returned.
|
||||||
|
""",
|
||||||
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
a = Operand('a', Float, '``x`` rounded to integral value')
|
||||||
|
|
||||||
|
ceil = Instruction(
|
||||||
|
'ceil', r"""
|
||||||
|
Round floating point round to integral, towards positive infinity.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
floor = Instruction(
|
||||||
|
'floor', r"""
|
||||||
|
Round floating point round to integral, towards negative infinity.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
trunc = Instruction(
|
||||||
|
'trunc', r"""
|
||||||
|
Round floating point round to integral, towards zero.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
nearest = Instruction(
|
||||||
|
'nearest', r"""
|
||||||
|
Round floating point round to integral, towards nearest with ties to
|
||||||
|
even.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
instructions.close()
|
instructions.close()
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ BinaryImmRev = InstructionFormat(imm64, value)
|
|||||||
BinaryOverflow = InstructionFormat(value, value, multiple_results=True)
|
BinaryOverflow = InstructionFormat(value, value, multiple_results=True)
|
||||||
|
|
||||||
# The select instructions are controlled by the second value operand.
|
# The select instructions are controlled by the second value operand.
|
||||||
# The first value operand is the controlling flag whisch has a derived type.
|
# The first value operand is the controlling flag which has a derived type.
|
||||||
Select = InstructionFormat(value, value, value, typevar_operand=1)
|
# The fma instruction has the same constraint on all inputs.
|
||||||
|
Ternary = InstructionFormat(value, value, value, typevar_operand=1)
|
||||||
|
|
||||||
InsertLane = InstructionFormat(value, uimm8, value)
|
InsertLane = InstructionFormat(value, uimm8, value)
|
||||||
ExtractLane = InstructionFormat(value, uimm8)
|
ExtractLane = InstructionFormat(value, uimm8)
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ pub enum InstructionData {
|
|||||||
second_result: Value,
|
second_result: Value,
|
||||||
args: [Value; 2],
|
args: [Value; 2],
|
||||||
},
|
},
|
||||||
Select {
|
Ternary {
|
||||||
opcode: Opcode,
|
opcode: Opcode,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
args: [Value; 3],
|
args: [Value; 3],
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ pub fn write_instruction(w: &mut Write, func: &Function, inst: Inst) -> Result {
|
|||||||
BinaryImm { arg, imm, .. } => writeln!(w, " {}, {}", arg, imm),
|
BinaryImm { arg, imm, .. } => writeln!(w, " {}, {}", arg, imm),
|
||||||
BinaryImmRev { imm, arg, .. } => writeln!(w, " {}, {}", imm, arg),
|
BinaryImmRev { imm, arg, .. } => writeln!(w, " {}, {}", imm, arg),
|
||||||
BinaryOverflow { args, .. } => writeln!(w, " {}, {}", args[0], args[1]),
|
BinaryOverflow { args, .. } => writeln!(w, " {}, {}", args[0], args[1]),
|
||||||
Select { args, .. } => writeln!(w, " {}, {}, {}", args[0], args[1], args[2]),
|
Ternary { args, .. } => writeln!(w, " {}, {}, {}", args[0], args[1], args[2]),
|
||||||
InsertLane { lane, args, .. } => writeln!(w, " {}, {}, {}", args[0], lane, args[1]),
|
InsertLane { lane, args, .. } => writeln!(w, " {}, {}, {}", args[0], lane, args[1]),
|
||||||
ExtractLane { lane, arg, .. } => writeln!(w, " {}, {}", arg, lane),
|
ExtractLane { lane, arg, .. } => writeln!(w, " {}, {}", arg, lane),
|
||||||
IntCompare { cond, args, .. } => writeln!(w, " {}, {}, {}", cond, args[0], args[1]),
|
IntCompare { cond, args, .. } => writeln!(w, " {}, {}, {}", cond, args[0], args[1]),
|
||||||
|
|||||||
@@ -815,13 +815,15 @@ impl<'a> Parser<'a> {
|
|||||||
args: [lhs, rhs],
|
args: [lhs, rhs],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstructionFormat::Select => {
|
InstructionFormat::Ternary => {
|
||||||
|
// Names here refer to the `select` instruction.
|
||||||
|
// This format is also use by `fma`.
|
||||||
let ctrl_arg = try!(self.match_value("expected SSA value control operand"));
|
let ctrl_arg = try!(self.match_value("expected SSA value control operand"));
|
||||||
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
||||||
let true_arg = try!(self.match_value("expected SSA value true operand"));
|
let true_arg = try!(self.match_value("expected SSA value true operand"));
|
||||||
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
||||||
let false_arg = try!(self.match_value("expected SSA value false operand"));
|
let false_arg = try!(self.match_value("expected SSA value false operand"));
|
||||||
InstructionData::Select {
|
InstructionData::Ternary {
|
||||||
opcode: opcode,
|
opcode: opcode,
|
||||||
ty: VOID,
|
ty: VOID,
|
||||||
args: [ctrl_arg, true_arg, false_arg],
|
args: [ctrl_arg, true_arg, false_arg],
|
||||||
|
|||||||
Reference in New Issue
Block a user