Browse Source

Add meta definitions for floating point operations.

Rename the Select instruction format to Ternary since it is also used by the fma
instruction.
pull/3/head
Jakob Stoklund Olesen 8 years ago
parent
commit
2bfb4ca5b7
  1. 89
      docs/langref.rst
  2. 143
      meta/cretonne/base.py
  3. 5
      meta/cretonne/formats.py
  4. 2
      src/libcretonne/instructions.rs
  5. 2
      src/libcretonne/write.rs
  6. 6
      src/libreader/parser.rs

89
docs/langref.rst

@ -771,73 +771,48 @@ Floating point operations
These operations generally follow IEEE 754-2008 semantics.
.. 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.
:result: ``x`` with its sign bit cleared.
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.
.. autoinst:: ceil
.. autoinst:: floor
.. autoinst:: trunc
.. autoinst:: nearest
Conversion operations
---------------------

143
meta/cretonne/base.py

@ -548,7 +548,7 @@ popcnt = Instruction(
#
Float = TypeVar(
'Float', 'A scalar or vector floating point type type',
'Float', 'A scalar or vector floating point number',
floats=True, simd=True)
Cond = Operand('Cond', floatcc)
@ -620,4 +620,145 @@ fcmp = Instruction(
""",
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()

5
meta/cretonne/formats.py

@ -27,8 +27,9 @@ BinaryImmRev = InstructionFormat(imm64, value)
BinaryOverflow = InstructionFormat(value, value, multiple_results=True)
# The select instructions are controlled by the second value operand.
# The first value operand is the controlling flag whisch has a derived type.
Select = InstructionFormat(value, value, value, typevar_operand=1)
# The first value operand is the controlling flag which has a derived type.
# The fma instruction has the same constraint on all inputs.
Ternary = InstructionFormat(value, value, value, typevar_operand=1)
InsertLane = InstructionFormat(value, uimm8, value)
ExtractLane = InstructionFormat(value, uimm8)

2
src/libcretonne/instructions.rs

@ -159,7 +159,7 @@ pub enum InstructionData {
second_result: Value,
args: [Value; 2],
},
Select {
Ternary {
opcode: Opcode,
ty: Type,
args: [Value; 3],

2
src/libcretonne/write.rs

@ -194,7 +194,7 @@ pub fn write_instruction(w: &mut Write, func: &Function, inst: Inst) -> Result {
BinaryImm { arg, imm, .. } => writeln!(w, " {}, {}", arg, imm),
BinaryImmRev { imm, arg, .. } => writeln!(w, " {}, {}", imm, arg),
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]),
ExtractLane { lane, arg, .. } => writeln!(w, " {}, {}", arg, lane),
IntCompare { cond, args, .. } => writeln!(w, " {}, {}, {}", cond, args[0], args[1]),

6
src/libreader/parser.rs

@ -815,13 +815,15 @@ impl<'a> Parser<'a> {
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"));
try!(self.match_token(Token::Comma, "expected ',' between operands"));
let true_arg = try!(self.match_value("expected SSA value true operand"));
try!(self.match_token(Token::Comma, "expected ',' between operands"));
let false_arg = try!(self.match_value("expected SSA value false operand"));
InstructionData::Select {
InstructionData::Ternary {
opcode: opcode,
ty: VOID,
args: [ctrl_arg, true_arg, false_arg],

Loading…
Cancel
Save