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 cc71744b74
commit 96cfb40507
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. Build a vector value from the provided lanes.
.. inst:: a = splat x .. autoinst:: splat
.. autoinst:: insertlane
Vector splat. .. autoinst:: extractlane
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.
Integer operations Integer operations
------------------ ------------------

View File

@@ -163,6 +163,18 @@ pub enum InstructionData {
ty: Type, ty: Type,
args: [Value; 3], args: [Value; 3],
}, },
InsertLane {
opcode: Opcode,
ty: Type,
lane: u8,
args: [Value; 2],
},
ExtractLane {
opcode: Opcode,
ty: Type,
lane: u8,
arg: Value,
},
Jump { Jump {
opcode: Opcode, opcode: Opcode,
ty: Type, ty: Type,
@@ -401,7 +413,7 @@ enum OperandConstraint {
Same, Same,
/// This operand is `ctrlType.lane_type()`. /// This operand is `ctrlType.lane_type()`.
Lane, LaneOf,
/// This operand is `ctrlType.as_bool()`. /// This operand is `ctrlType.as_bool()`.
AsBool, AsBool,
@@ -418,7 +430,7 @@ impl OperandConstraint {
Concrete(t) => Some(t), Concrete(t) => Some(t),
Free(_) => None, Free(_) => None,
Same => Some(ctrl_type), Same => Some(ctrl_type),
Lane => Some(ctrl_type.lane_type()), LaneOf => Some(ctrl_type.lane_type()),
AsBool => Some(ctrl_type.as_bool()), 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, .. } => { Select { opcode, args, .. } => {
writeln!(w, "{} {}, {}, {}", opcode, args[0], args[1], args[2]) 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), Jump { opcode, ref data, .. } => writeln!(w, "{} {}", opcode, data),
Branch { opcode, ref data, .. } => writeln!(w, "{} {}", opcode, data), Branch { opcode, ref data, .. } => writeln!(w, "{} {}", opcode, data),
BranchTable { opcode, arg, table, .. } => writeln!(w, "{} {}, {}", opcode, arg, table), BranchTable { opcode, arg, table, .. } => writeln!(w, "{} {}, {}", opcode, arg, table),

View File

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

View File

@@ -296,7 +296,7 @@ class TypeVar(object):
def __str__(self): def __str__(self):
return "`{}`".format(self.name) return "`{}`".format(self.name)
def lane(self): def lane_of(self):
""" """
Return a derived type variable that is the scalar lane type of this Return a derived type variable that is the scalar lane type of this
type variable. type variable.
@@ -304,7 +304,7 @@ class TypeVar(object):
When this type variable assumes a scalar type, the derived type will be When this type variable assumes a scalar type, the derived type will be
the same scalar type. 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): def as_bool(self):
""" """

View File

@@ -6,7 +6,7 @@ support.
""" """
from . import TypeVar, Operand, Instruction, InstructionGroup, variable_args from . import TypeVar, Operand, Instruction, InstructionGroup, variable_args
from types import i8, f32, f64 from types import i8, f32, f64
from immediates import imm64, ieee32, ieee64, immvector from immediates import imm64, uimm8, ieee32, ieee64, immvector
import entities import entities
instructions = InstructionGroup("base", "Shared base instruction set") instructions = InstructionGroup("base", "Shared base instruction set")
@@ -17,7 +17,7 @@ Testable = TypeVar(
'Testable', 'A scalar boolean or integer type', 'Testable', 'A scalar boolean or integer type',
ints=True, bools=True) ints=True, bools=True)
TxN = TypeVar( TxN = TypeVar(
'%Tx%N', 'A SIMD vector type', 'TxN', 'A SIMD vector type',
ints=True, floats=True, bools=True, scalars=False, simd=True) ints=True, floats=True, bools=True, scalars=False, simd=True)
Any = TypeVar( Any = TypeVar(
'Any', 'Any integer, float, or boolean scalar or vector type', 'Any', 'Any integer, float, or boolean scalar or vector type',
@@ -177,6 +177,42 @@ vselect = Instruction(
vector ``c``. vector ``c``.
""", """,
ins=(c, x, y), outs=a) 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 # Integer arithmetic
# #

View File

@@ -8,7 +8,7 @@ in this module.
from . import InstructionFormat, value, variable_args 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 from entities import ebb, function, jump_table
Nullary = InstructionFormat() 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. # The first value operand is the controlling flag whisch has a derived type.
Select = InstructionFormat(value, value, value, typevar_operand=1) 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) Jump = InstructionFormat(ebb, variable_args, boxed_storage=True)
Branch = InstructionFormat(value, ebb, variable_args, boxed_storage=True) Branch = InstructionFormat(value, ebb, variable_args, boxed_storage=True)
BranchTable = InstructionFormat(value, jump_table) BranchTable = InstructionFormat(value, jump_table)

View File

@@ -11,6 +11,12 @@ from . import ImmediateKind
#: :py:class:`cretonne.IntType` type. #: :py:class:`cretonne.IntType` type.
imm64 = ImmediateKind('imm64', 'A 64-bit immediate integer.') 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. #: A 32-bit immediate floating point operand.
#: #:
#: IEEE 754-2008 binary32 interchange format. #: IEEE 754-2008 binary32 interchange format.