Add vector instructions.

Use derived type variables with the 'LaneOf' function.

Add u8 immediates to be used for lane indexes and bit shifts.
This commit is contained in:
Jakob Stoklund Olesen
2016-05-20 15:36:03 -07:00
parent b44d6c6541
commit b1dd4ad373
8 changed files with 73 additions and 38 deletions

View File

@@ -669,37 +669,9 @@ Vector operations
Build a vector value from the provided lanes.
.. inst:: a = splat x
Vector splat.
Return a vector whose lanes are all ``x``.
:arg T x: Scalar value to be replicated.
:result TxN a: Vector with identical lanes.
.. inst:: a = insertlane x, Idx, y
Insert ``y`` as lane ``Idx`` in x.
The lane index, ``Idx``, is an immediate value, not an SSA value. It must
indicate a valid lane index for the type of ``x``.
:arg TxN x: Vector to modify.
:arg Idx: Lane index smaller than N.
:arg T y: New lane value.
:result TxN y: Updated vector.
.. inst:: a = extractlane x, Idx
Extract lane ``Idx`` from ``x``.
The lane index, ``Idx``, is an immediate value, not an SSA value. It must
indicate a valid lane index for the type of ``x``.
:arg TxN x: Source vector
:arg Idx: Lane index
:result T a: Lane value.
.. autoinst:: splat
.. autoinst:: insertlane
.. autoinst:: extractlane
Integer operations
------------------

View File

@@ -296,7 +296,7 @@ class TypeVar(object):
def __str__(self):
return "`{}`".format(self.name)
def lane(self):
def lane_of(self):
"""
Return a derived type variable that is the scalar lane type of this
type variable.
@@ -304,7 +304,7 @@ class TypeVar(object):
When this type variable assumes a scalar type, the derived type will be
the same scalar type.
"""
return TypeVar(None, None, base=self, derived_func='Lane')
return TypeVar(None, None, base=self, derived_func='LaneOf')
def as_bool(self):
"""

View File

@@ -6,7 +6,7 @@ support.
"""
from . import TypeVar, Operand, Instruction, InstructionGroup, variable_args
from types import i8, f32, f64
from immediates import imm64, ieee32, ieee64, immvector
from immediates import imm64, uimm8, ieee32, ieee64, immvector
import entities
instructions = InstructionGroup("base", "Shared base instruction set")
@@ -17,7 +17,7 @@ Testable = TypeVar(
'Testable', 'A scalar boolean or integer type',
ints=True, bools=True)
TxN = TypeVar(
'%Tx%N', 'A SIMD vector type',
'TxN', 'A SIMD vector type',
ints=True, floats=True, bools=True, scalars=False, simd=True)
Any = TypeVar(
'Any', 'Any integer, float, or boolean scalar or vector type',
@@ -177,6 +177,42 @@ vselect = Instruction(
vector ``c``.
""",
ins=(c, x, y), outs=a)
x = Operand('x', TxN.lane_of())
splat = Instruction(
'splat', r"""
Vector splat.
Return a vector whose lanes are all ``x``.
""",
ins=x, outs=a)
x = Operand('x', TxN, doc='SIMD vector to modify')
y = Operand('y', TxN.lane_of(), doc='New lane value')
Idx = Operand('Idx', uimm8, doc='Lane index')
insertlane = Instruction(
'insertlane', r"""
Insert ``y`` as lane ``Idx`` in x.
The lane index, ``Idx``, is an immediate value, not an SSA value. It
must indicate a valid lane index for the type of ``x``.
""",
ins=(x, Idx, y), outs=a)
x = Operand('x', TxN)
a = Operand('a', TxN.lane_of())
extractlane = Instruction(
'extractlane', r"""
Extract lane ``Idx`` from ``x``.
The lane index, ``Idx``, is an immediate value, not an SSA value. It
must indicate a valid lane index for the type of ``x``.
""",
ins=(x, Idx), outs=a)
#
# Integer arithmetic
#

View File

@@ -8,7 +8,7 @@ in this module.
from . import InstructionFormat, value, variable_args
from immediates import imm64, ieee32, ieee64, immvector
from immediates import imm64, uimm8, ieee32, ieee64, immvector
from entities import ebb, function, jump_table
Nullary = InstructionFormat()
@@ -30,6 +30,9 @@ BinaryOverflow = InstructionFormat(value, value, multiple_results=True)
# The first value operand is the controlling flag whisch has a derived type.
Select = InstructionFormat(value, value, value, typevar_operand=1)
InsertLane = InstructionFormat(value, uimm8, value)
ExtractLane = InstructionFormat(value, uimm8)
Jump = InstructionFormat(ebb, variable_args, boxed_storage=True)
Branch = InstructionFormat(value, ebb, variable_args, boxed_storage=True)
BranchTable = InstructionFormat(value, jump_table)

View File

@@ -11,6 +11,12 @@ from . import ImmediateKind
#: :py:class:`cretonne.IntType` type.
imm64 = ImmediateKind('imm64', 'A 64-bit immediate integer.')
#: An unsigned 8-bit immediate integer operand.
#:
#: This small operand is used to indicate lane indexes in SIMD vectors and
#: immediate bit counts on shift instructions.
uimm8 = ImmediateKind('uimm8', 'An 8-bit immediate unsigned integer.')
#: A 32-bit immediate floating point operand.
#:
#: IEEE 754-2008 binary32 interchange format.

View File

@@ -163,6 +163,18 @@ pub enum InstructionData {
ty: Type,
args: [Value; 3],
},
InsertLane {
opcode: Opcode,
ty: Type,
lane: u8,
args: [Value; 2],
},
ExtractLane {
opcode: Opcode,
ty: Type,
lane: u8,
arg: Value,
},
Jump {
opcode: Opcode,
ty: Type,
@@ -401,7 +413,7 @@ enum OperandConstraint {
Same,
/// This operand is `ctrlType.lane_type()`.
Lane,
LaneOf,
/// This operand is `ctrlType.as_bool()`.
AsBool,
@@ -418,7 +430,7 @@ impl OperandConstraint {
Concrete(t) => Some(t),
Free(_) => None,
Same => Some(ctrl_type),
Lane => Some(ctrl_type.lane_type()),
LaneOf => Some(ctrl_type.lane_type()),
AsBool => Some(ctrl_type.as_bool()),
}
}

View File

@@ -159,6 +159,10 @@ pub fn write_instruction(w: &mut Write, func: &Function, inst: Inst) -> Result {
Select { opcode, args, .. } => {
writeln!(w, "{} {}, {}, {}", opcode, args[0], args[1], args[2])
}
InsertLane { opcode, lane, args, .. } => {
writeln!(w, "{} {}, {}, {}", opcode, args[0], lane, args[1])
}
ExtractLane { opcode, lane, arg, .. } => writeln!(w, "{} {}, {}", opcode, arg, lane),
Jump { opcode, ref data, .. } => writeln!(w, "{} {}", opcode, data),
Branch { opcode, ref data, .. } => writeln!(w, "{} {}", opcode, data),
BranchTable { opcode, arg, table, .. } => writeln!(w, "{} {}, {}", opcode, arg, table),

View File

@@ -669,6 +669,8 @@ impl<'a> Parser<'a> {
}
}
InstructionFormat::Select |
InstructionFormat::InsertLane |
InstructionFormat::ExtractLane |
InstructionFormat::Jump |
InstructionFormat::Branch |
InstructionFormat::BranchTable |