Add a bconst instruction. (#116)

* Add a bconst instruction.
This commit is contained in:
Dan Gohman
2017-07-13 10:12:25 -07:00
committed by Jakob Stoklund Olesen
parent d8e2cb2b42
commit 3bcfb103b9
9 changed files with 64 additions and 2 deletions

View File

@@ -562,6 +562,7 @@ Constant materialization
.. autoinst:: iconst .. autoinst:: iconst
.. autoinst:: f32const .. autoinst:: f32const
.. autoinst:: f64const .. autoinst:: f64const
.. autoinst:: bconst
Live range splitting Live range splitting
-------------------- --------------------

View File

@@ -25,6 +25,23 @@ ebb0:
; nextln: $v2 = ishl $v0, $v1 ; nextln: $v2 = ishl $v0, $v1
; nextln: } ; nextln: }
; Create and use values.
; Polymorphic instructions with type suffix.
function %bvalues() {
ebb0:
v0 = bconst.b32 true
v1 = bconst.b8 false
v2 = bextend.b32 v1
v3 = bxor v0, v2
}
; sameln: function %bvalues() {
; nextln: ebb0:
; nextln: $v0 = bconst.b32 true
; nextln: $v1 = bconst.b8 false
; nextln: $v2 = bextend.b32 v1
; nextln: $v3 = bxor v0, v2
; nextln: }
; Polymorphic istruction controlled by second operand. ; Polymorphic istruction controlled by second operand.
function %select() { function %select() {
ebb0(v90: i32, v91: i32, v92: b1): ebb0(v90: i32, v91: i32, v92: b1):

View File

@@ -9,7 +9,7 @@ from __future__ import absolute_import
from cdsl.formats import InstructionFormat from cdsl.formats import InstructionFormat
from cdsl.operands import VALUE, VARIABLE_ARGS from cdsl.operands import VALUE, VARIABLE_ARGS
from .immediates import imm64, uimm8, ieee32, ieee64, offset32, uoffset32 from .immediates import imm64, uimm8, ieee32, ieee64, offset32, uoffset32
from .immediates import intcc, floatcc, memflags, regunit from .immediates import boolean, intcc, floatcc, memflags, regunit
from .entities import ebb, sig_ref, func_ref, jump_table, stack_slot from .entities import ebb, sig_ref, func_ref, jump_table, stack_slot
Nullary = InstructionFormat() Nullary = InstructionFormat()
@@ -18,6 +18,7 @@ Unary = InstructionFormat(VALUE)
UnaryImm = InstructionFormat(imm64) UnaryImm = InstructionFormat(imm64)
UnaryIeee32 = InstructionFormat(ieee32) UnaryIeee32 = InstructionFormat(ieee32)
UnaryIeee64 = InstructionFormat(ieee64) UnaryIeee64 = InstructionFormat(ieee64)
UnaryBool = InstructionFormat(boolean)
Binary = InstructionFormat(VALUE, VALUE) Binary = InstructionFormat(VALUE, VALUE)
BinaryImm = InstructionFormat(VALUE, imm64) BinaryImm = InstructionFormat(VALUE, imm64)

View File

@@ -45,6 +45,13 @@ ieee32 = ImmediateKind('ieee32', 'A 32-bit immediate floating point number.')
#: IEEE 754-2008 binary64 interchange format. #: IEEE 754-2008 binary64 interchange format.
ieee64 = ImmediateKind('ieee64', 'A 64-bit immediate floating point number.') ieee64 = ImmediateKind('ieee64', 'A 64-bit immediate floating point number.')
#: An immediate boolean operand.
#:
#: This type of immediate boolean can interact with SSA values with any
#: :py:class:`cretonne.BoolType` type.
boolean = ImmediateKind('boolean', 'An immediate boolean.',
rust_type='bool')
#: A condition code for comparing integer values. #: A condition code for comparing integer values.
#: #:
#: This enumerated operand kind is used for the :cton:inst:`icmp` instruction #: This enumerated operand kind is used for the :cton:inst:`icmp` instruction

View File

@@ -10,7 +10,7 @@ from cdsl.typevar import TypeVar
from cdsl.instructions import Instruction, InstructionGroup from cdsl.instructions import Instruction, InstructionGroup
from base.types import f32, f64, b1 from base.types import f32, f64, b1
from base.immediates import imm64, uimm8, ieee32, ieee64, offset32, uoffset32 from base.immediates import imm64, uimm8, ieee32, ieee64, offset32, uoffset32
from base.immediates import intcc, floatcc, memflags, regunit from base.immediates import boolean, intcc, floatcc, memflags, regunit
from base import entities from base import entities
from cdsl.ti import WiderOrEq from cdsl.ti import WiderOrEq
import base.formats # noqa import base.formats # noqa
@@ -18,6 +18,8 @@ import base.formats # noqa
GROUP = InstructionGroup("base", "Shared base instruction set") GROUP = InstructionGroup("base", "Shared base instruction set")
Int = TypeVar('Int', 'A scalar or vector integer type', ints=True, simd=True) Int = TypeVar('Int', 'A scalar or vector integer type', ints=True, simd=True)
Bool = TypeVar('Bool', 'A scalar or vector boolean type',
bools=True, simd=True)
iB = TypeVar('iB', 'A scalar integer type', ints=True) iB = TypeVar('iB', 'A scalar integer type', ints=True)
iAddr = TypeVar('iAddr', 'An integer address type', ints=(32, 64)) iAddr = TypeVar('iAddr', 'An integer address type', ints=(32, 64))
Testable = TypeVar( Testable = TypeVar(
@@ -417,6 +419,17 @@ f64const = Instruction(
""", """,
ins=N, outs=a) ins=N, outs=a)
N = Operand('N', boolean)
a = Operand('a', Bool, doc='A constant boolean scalar or vector value')
bconst = Instruction(
'bconst', r"""
Boolean constant.
Create a scalar boolean SSA value with an immediate constant value, or
a boolean vector where all the lanes have the same value.
""",
ins=N, outs=a)
# #
# Generics. # Generics.
# #

View File

@@ -107,6 +107,7 @@ pub enum InstructionData {
UnaryImm { opcode: Opcode, imm: Imm64 }, UnaryImm { opcode: Opcode, imm: Imm64 },
UnaryIeee32 { opcode: Opcode, imm: Ieee32 }, UnaryIeee32 { opcode: Opcode, imm: Ieee32 },
UnaryIeee64 { opcode: Opcode, imm: Ieee64 }, UnaryIeee64 { opcode: Opcode, imm: Ieee64 },
UnaryBool { opcode: Opcode, imm: bool },
Binary { opcode: Opcode, args: [Value; 2] }, Binary { opcode: Opcode, args: [Value; 2] },
BinaryImm { BinaryImm {
opcode: Opcode, opcode: Opcode,

View File

@@ -273,6 +273,7 @@ impl<'a> Verifier<'a> {
UnaryImm { .. } | UnaryImm { .. } |
UnaryIeee32 { .. } | UnaryIeee32 { .. } |
UnaryIeee64 { .. } | UnaryIeee64 { .. } |
UnaryBool { .. } |
Binary { .. } | Binary { .. } |
BinaryImm { .. } | BinaryImm { .. } |
Ternary { .. } | Ternary { .. } |

View File

@@ -243,6 +243,7 @@ pub fn write_operands(w: &mut Write,
UnaryImm { imm, .. } => write!(w, " {}", imm), UnaryImm { imm, .. } => write!(w, " {}", imm),
UnaryIeee32 { imm, .. } => write!(w, " {}", imm), UnaryIeee32 { imm, .. } => write!(w, " {}", imm),
UnaryIeee64 { imm, .. } => write!(w, " {}", imm), UnaryIeee64 { imm, .. } => write!(w, " {}", imm),
UnaryBool { imm, .. } => write!(w, " {}", imm),
Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]), Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]),
BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm), BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm),
Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]), Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]),

View File

@@ -498,6 +498,20 @@ impl<'a> Parser<'a> {
} }
} }
// Match and consume a boolean immediate.
fn match_bool(&mut self, err_msg: &str) -> Result<bool> {
if let Some(Token::Identifier(text)) = self.token() {
self.consume();
match text {
"true" => Ok(true),
"false" => Ok(false),
_ => err!(self.loc, err_msg),
}
} else {
err!(self.loc, err_msg)
}
}
// Match and consume an enumerated immediate, like one of the condition codes. // Match and consume an enumerated immediate, like one of the condition codes.
fn match_enum<T: FromStr>(&mut self, err_msg: &str) -> Result<T> { fn match_enum<T: FromStr>(&mut self, err_msg: &str) -> Result<T> {
if let Some(Token::Identifier(text)) = self.token() { if let Some(Token::Identifier(text)) = self.token() {
@@ -1483,6 +1497,12 @@ impl<'a> Parser<'a> {
imm: self.match_ieee64("expected immediate 64-bit float operand")?, imm: self.match_ieee64("expected immediate 64-bit float operand")?,
} }
} }
InstructionFormat::UnaryBool => {
InstructionData::UnaryBool {
opcode,
imm: self.match_bool("expected immediate boolean operand")?,
}
}
InstructionFormat::Binary => { InstructionFormat::Binary => {
let lhs = self.match_value("expected SSA value first operand")?; let lhs = self.match_value("expected SSA value first operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?; self.match_token(Token::Comma, "expected ',' between operands")?;