mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
Add two new instructions to the llvm IR, vicmp and vfcmp. see updated LangRef
for details. CodeGen support coming in a follow up patch git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50985 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7c2e4f2fc5
commit
ac80ade158
@ -140,6 +140,8 @@
|
||||
<ol>
|
||||
<li><a href="#i_icmp">'<tt>icmp</tt>' Instruction</a></li>
|
||||
<li><a href="#i_fcmp">'<tt>fcmp</tt>' Instruction</a></li>
|
||||
<li><a href="#i_vicmp">'<tt>vicmp</tt>' Instruction</a></li>
|
||||
<li><a href="#i_vfcmp">'<tt>vfcmp</tt>' Instruction</a></li>
|
||||
<li><a href="#i_phi">'<tt>phi</tt>' Instruction</a></li>
|
||||
<li><a href="#i_select">'<tt>select</tt>' Instruction</a></li>
|
||||
<li><a href="#i_call">'<tt>call</tt>' Instruction</a></li>
|
||||
@ -1680,6 +1682,12 @@ following is the syntax for constant expressions:</p>
|
||||
<dt><b><tt>fcmp COND ( VAL1, VAL2 )</tt></b></dt>
|
||||
<dd>Performs the <a href="#i_fcmp">fcmp operation</a> on constants.</dd>
|
||||
|
||||
<dt><b><tt>vicmp COND ( VAL1, VAL2 )</tt></b></dt>
|
||||
<dd>Performs the <a href="#i_vicmp">vicmp operation</a> on constants.</dd>
|
||||
|
||||
<dt><b><tt>vfcmp COND ( VAL1, VAL2 )</tt></b></dt>
|
||||
<dd>Performs the <a href="#i_vfcmp">vfcmp operation</a> on constants.</dd>
|
||||
|
||||
<dt><b><tt>extractelement ( VAL, IDX )</tt></b></dt>
|
||||
|
||||
<dd>Perform the <a href="#i_extractelement">extractelement
|
||||
@ -3672,9 +3680,9 @@ a value, just a keyword. The possible condition code are:
|
||||
<a href="#t_floating">floating point</a> typed. They must have identical
|
||||
types.</p>
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>fcmp</tt>' compares <tt>var1</tt> and <tt>var2</tt> according to
|
||||
the condition code given as <tt>cond</tt>. The comparison performed always
|
||||
yields a <a href="#t_primitive">i1</a> result, as follows:
|
||||
<p>The '<tt>fcmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
|
||||
according to the condition code given as <tt>cond</tt>. The comparison performed
|
||||
always yields a <a href="#t_primitive">i1</a> result, as follows:
|
||||
<ol>
|
||||
<li><tt>false</tt>: always yields <tt>false</tt>, regardless of operands.</li>
|
||||
<li><tt>oeq</tt>: yields <tt>true</tt> if both operands are not a QNAN and
|
||||
@ -3714,6 +3722,106 @@ yields a <a href="#t_primitive">i1</a> result, as follows:
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_vicmp">'<tt>vicmp</tt>' Instruction</a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<h5>Syntax:</h5>
|
||||
<pre> <result> = vicmp <cond> <ty> <var1>, <var2> <i>; yields {ty}:result</i>
|
||||
</pre>
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>vicmp</tt>' instruction returns an integer vector value based on
|
||||
element-wise comparison of its two integer vector operands.</p>
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>vicmp</tt>' instruction takes three operands. The first operand is
|
||||
the condition code indicating the kind of comparison to perform. It is not
|
||||
a value, just a keyword. The possible condition code are:
|
||||
<ol>
|
||||
<li><tt>eq</tt>: equal</li>
|
||||
<li><tt>ne</tt>: not equal </li>
|
||||
<li><tt>ugt</tt>: unsigned greater than</li>
|
||||
<li><tt>uge</tt>: unsigned greater or equal</li>
|
||||
<li><tt>ult</tt>: unsigned less than</li>
|
||||
<li><tt>ule</tt>: unsigned less or equal</li>
|
||||
<li><tt>sgt</tt>: signed greater than</li>
|
||||
<li><tt>sge</tt>: signed greater or equal</li>
|
||||
<li><tt>slt</tt>: signed less than</li>
|
||||
<li><tt>sle</tt>: signed less or equal</li>
|
||||
</ol>
|
||||
<p>The remaining two arguments must be <a href="#t_vector">vector</a> of
|
||||
<a href="#t_integer">integer</a> typed. They must also be identical types.</p>
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>vicmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
|
||||
according to the condition code given as <tt>cond</tt>. The comparison yields a
|
||||
<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, of
|
||||
identical type as the values being compared. The most significant bit in each
|
||||
element is 1 if the element-wise comparison evaluates to true, and is 0
|
||||
otherwise. All other bits of the result are undefined. The condition codes
|
||||
are evaluated identically to the <a href="#i_icmp">'<tt>icmp</tt>'
|
||||
instruction</a>.
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
<result> = vicmp eq <2 x i32> < i32 4, i32 0 >, < i32 5, i32 0 > <i>; yields: result=<2 x i32> < i32 0, i32 -1 ></i>
|
||||
<result> = vicmp ult <2 x i8> < i8 1, i8 2 >, < i8 2, i8 2> <i>; yields: result=<2 x i8> < i8 -1, i8 0 ></i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_vfcmp">'<tt>vfcmp</tt>' Instruction</a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<h5>Syntax:</h5>
|
||||
<pre> <result> = vfcmp <cond> <ty> <var1>, <var2></pre>
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>vfcmp</tt>' instruction returns an integer vector value based on
|
||||
element-wise comparison of its two floating point vector operands. The output
|
||||
elements have the same width as the input elements.</p>
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>vfcmp</tt>' instruction takes three operands. The first operand is
|
||||
the condition code indicating the kind of comparison to perform. It is not
|
||||
a value, just a keyword. The possible condition code are:
|
||||
<ol>
|
||||
<li><tt>false</tt>: no comparison, always returns false</li>
|
||||
<li><tt>oeq</tt>: ordered and equal</li>
|
||||
<li><tt>ogt</tt>: ordered and greater than </li>
|
||||
<li><tt>oge</tt>: ordered and greater than or equal</li>
|
||||
<li><tt>olt</tt>: ordered and less than </li>
|
||||
<li><tt>ole</tt>: ordered and less than or equal</li>
|
||||
<li><tt>one</tt>: ordered and not equal</li>
|
||||
<li><tt>ord</tt>: ordered (no nans)</li>
|
||||
<li><tt>ueq</tt>: unordered or equal</li>
|
||||
<li><tt>ugt</tt>: unordered or greater than </li>
|
||||
<li><tt>uge</tt>: unordered or greater than or equal</li>
|
||||
<li><tt>ult</tt>: unordered or less than </li>
|
||||
<li><tt>ule</tt>: unordered or less than or equal</li>
|
||||
<li><tt>une</tt>: unordered or not equal</li>
|
||||
<li><tt>uno</tt>: unordered (either nans)</li>
|
||||
<li><tt>true</tt>: no comparison, always returns true</li>
|
||||
</ol>
|
||||
<p>The remaining two arguments must be <a href="#t_vector">vector</a> of
|
||||
<a href="#t_floating">floating point</a> typed. They must also be identical
|
||||
types.</p>
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>vfcmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
|
||||
according to the condition code given as <tt>cond</tt>. The comparison yields a
|
||||
<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, with
|
||||
an identical number of elements as the values being compared, and each element
|
||||
having identical with to the width of the floating point elements. The most
|
||||
significant bit in each element is 1 if the element-wise comparison evaluates to
|
||||
true, and is 0 otherwise. All other bits of the result are undefined. The
|
||||
condition codes are evaluated identically to the
|
||||
<a href="#i_fcmp">'<tt>fcmp</tt>' instruction</a>.
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
<result> = vfcmp oeq <2 x float> < float 4, float 0 >, < float 5, float 0 > <i>; yields: result=<2 x i32> < i32 0, i32 -1 ></i>
|
||||
<result> = vfcmp ult <2 x double> < double 1, double 2 >, < double 2, double 2> <i>; yields: result=<2 x i64> < i64 -1, i64 0 ></i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="i_phi">'<tt>phi</tt>'
|
||||
Instruction</a> </div>
|
||||
|
@ -689,6 +689,8 @@ public:
|
||||
static Constant *getXor(Constant *C1, Constant *C2);
|
||||
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getVICmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getVFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getShl(Constant *C1, Constant *C2);
|
||||
static Constant *getLShr(Constant *C1, Constant *C2);
|
||||
static Constant *getAShr(Constant *C1, Constant *C2);
|
||||
|
@ -349,6 +349,16 @@ public:
|
||||
///
|
||||
static VectorType *get(const Type *ElementType, unsigned NumElements);
|
||||
|
||||
/// VectorType::getInteger - This static method gets a VectorType with the
|
||||
/// same number of elements as the input type, and the element type is an
|
||||
/// integer type of the same width as the input element type.
|
||||
///
|
||||
static VectorType *getInteger(const VectorType *VTy) {
|
||||
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
|
||||
const Type *EltTy = IntegerType::get(EltBits);
|
||||
return VectorType::get(EltTy, VTy->getNumElements());
|
||||
}
|
||||
|
||||
/// @brief Return the number of elements in the Vector type.
|
||||
inline unsigned getNumElements() const { return NumElements; }
|
||||
|
||||
|
@ -498,13 +498,55 @@ class CmpInst: public Instruction {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
CmpInst(); // do not implement
|
||||
protected:
|
||||
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
|
||||
const std::string &Name = "", Instruction *InsertBefore = 0);
|
||||
CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred,
|
||||
Value *LHS, Value *RHS, const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
|
||||
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd);
|
||||
CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred,
|
||||
Value *LHS, Value *RHS, const std::string &Name,
|
||||
BasicBlock *InsertAtEnd);
|
||||
|
||||
public:
|
||||
/// This enumeration lists the possible predicates for CmpInst subclasses.
|
||||
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
|
||||
/// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
|
||||
/// predicate values are not overlapping between the classes.
|
||||
enum Predicate {
|
||||
// Opcode U L G E Intuitive operation
|
||||
FCMP_FALSE = 0, /// 0 0 0 0 Always false (always folded)
|
||||
FCMP_OEQ = 1, /// 0 0 0 1 True if ordered and equal
|
||||
FCMP_OGT = 2, /// 0 0 1 0 True if ordered and greater than
|
||||
FCMP_OGE = 3, /// 0 0 1 1 True if ordered and greater than or equal
|
||||
FCMP_OLT = 4, /// 0 1 0 0 True if ordered and less than
|
||||
FCMP_OLE = 5, /// 0 1 0 1 True if ordered and less than or equal
|
||||
FCMP_ONE = 6, /// 0 1 1 0 True if ordered and operands are unequal
|
||||
FCMP_ORD = 7, /// 0 1 1 1 True if ordered (no nans)
|
||||
FCMP_UNO = 8, /// 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
||||
FCMP_UEQ = 9, /// 1 0 0 1 True if unordered or equal
|
||||
FCMP_UGT = 10, /// 1 0 1 0 True if unordered or greater than
|
||||
FCMP_UGE = 11, /// 1 0 1 1 True if unordered, greater than, or equal
|
||||
FCMP_ULT = 12, /// 1 1 0 0 True if unordered or less than
|
||||
FCMP_ULE = 13, /// 1 1 0 1 True if unordered, less than, or equal
|
||||
FCMP_UNE = 14, /// 1 1 1 0 True if unordered or not equal
|
||||
FCMP_TRUE = 15, /// 1 1 1 1 Always true (always folded)
|
||||
FIRST_FCMP_PREDICATE = FCMP_FALSE,
|
||||
LAST_FCMP_PREDICATE = FCMP_TRUE,
|
||||
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
|
||||
ICMP_EQ = 32, /// equal
|
||||
ICMP_NE = 33, /// not equal
|
||||
ICMP_UGT = 34, /// unsigned greater than
|
||||
ICMP_UGE = 35, /// unsigned greater or equal
|
||||
ICMP_ULT = 36, /// unsigned less than
|
||||
ICMP_ULE = 37, /// unsigned less or equal
|
||||
ICMP_SGT = 38, /// signed greater than
|
||||
ICMP_SGE = 39, /// signed greater or equal
|
||||
ICMP_SLT = 40, /// signed less than
|
||||
ICMP_SLE = 41, /// signed less or equal
|
||||
FIRST_ICMP_PREDICATE = ICMP_EQ,
|
||||
LAST_ICMP_PREDICATE = ICMP_SLE,
|
||||
BAD_ICMP_PREDICATE = ICMP_SLE + 1
|
||||
};
|
||||
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 2);
|
||||
@ -576,7 +618,9 @@ public:
|
||||
static inline bool classof(const CmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::ICmp ||
|
||||
I->getOpcode() == Instruction::FCmp;
|
||||
I->getOpcode() == Instruction::FCmp ||
|
||||
I->getOpcode() == Instruction::VICmp ||
|
||||
I->getOpcode() == Instruction::VFCmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
|
@ -166,7 +166,10 @@ HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector
|
||||
HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||
HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value
|
||||
//from aggregate result
|
||||
LAST_OTHER_INST(51)
|
||||
HANDLE_OTHER_INST(52, VICmp , VICmpInst ) // Vec Int comparison instruction.
|
||||
HANDLE_OTHER_INST(53, VFCmp , VFCmpInst ) // Vec FP point comparison instr.
|
||||
|
||||
LAST_OTHER_INST(53)
|
||||
|
||||
#undef FIRST_TERM_INST
|
||||
#undef HANDLE_TERM_INST
|
||||
|
@ -610,31 +610,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This instruction compares its operands according to the predicate given
|
||||
/// to the constructor. It only operates on integers, pointers, or packed
|
||||
/// vectors of integrals. The two operands must be the same type.
|
||||
/// to the constructor. It only operates on integers or pointers. The operands
|
||||
/// must be identical types.
|
||||
/// @brief Represent an integer comparison operator.
|
||||
class ICmpInst: public CmpInst {
|
||||
public:
|
||||
/// This enumeration lists the possible predicates for the ICmpInst. The
|
||||
/// values in the range 0-31 are reserved for FCmpInst while values in the
|
||||
/// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
|
||||
/// predicate values are not overlapping between the classes.
|
||||
enum Predicate {
|
||||
ICMP_EQ = 32, ///< equal
|
||||
ICMP_NE = 33, ///< not equal
|
||||
ICMP_UGT = 34, ///< unsigned greater than
|
||||
ICMP_UGE = 35, ///< unsigned greater or equal
|
||||
ICMP_ULT = 36, ///< unsigned less than
|
||||
ICMP_ULE = 37, ///< unsigned less or equal
|
||||
ICMP_SGT = 38, ///< signed greater than
|
||||
ICMP_SGE = 39, ///< signed greater or equal
|
||||
ICMP_SLT = 40, ///< signed less than
|
||||
ICMP_SLE = 41, ///< signed less or equal
|
||||
FIRST_ICMP_PREDICATE = ICMP_EQ,
|
||||
LAST_ICMP_PREDICATE = ICMP_SLE,
|
||||
BAD_ICMP_PREDICATE = ICMP_SLE + 1
|
||||
};
|
||||
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
ICmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
@ -642,7 +622,18 @@ public:
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertBefore) {
|
||||
) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, Name,
|
||||
InsertBefore) {
|
||||
assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
|
||||
pred <= CmpInst::LAST_ICMP_PREDICATE &&
|
||||
"Invalid ICmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to ICmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
|
||||
"Invalid operand types for ICmp instruction");
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
@ -652,7 +643,18 @@ public:
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertAtEnd) {
|
||||
) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, Name,
|
||||
InsertAtEnd) {
|
||||
assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
|
||||
pred <= CmpInst::LAST_ICMP_PREDICATE &&
|
||||
"Invalid ICmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to ICmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
|
||||
"Invalid operand types for ICmp instruction");
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
@ -783,31 +785,6 @@ public:
|
||||
/// @brief Represents a floating point comparison operator.
|
||||
class FCmpInst: public CmpInst {
|
||||
public:
|
||||
/// This enumeration lists the possible predicates for the FCmpInst. Values
|
||||
/// in the range 0-31 are reserved for FCmpInst.
|
||||
enum Predicate {
|
||||
// Opcode U L G E Intuitive operation
|
||||
FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
|
||||
FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
|
||||
FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
|
||||
FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
|
||||
FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
|
||||
FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
|
||||
FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
|
||||
FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
|
||||
FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
||||
FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
|
||||
FCMP_UGT =10, ///< 1 0 1 0 True if unordered or greater than
|
||||
FCMP_UGE =11, ///< 1 0 1 1 True if unordered, greater than, or equal
|
||||
FCMP_ULT =12, ///< 1 1 0 0 True if unordered or less than
|
||||
FCMP_ULE =13, ///< 1 1 0 1 True if unordered, less than, or equal
|
||||
FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal
|
||||
FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded)
|
||||
FIRST_FCMP_PREDICATE = FCMP_FALSE,
|
||||
LAST_FCMP_PREDICATE = FCMP_TRUE,
|
||||
BAD_FCMP_PREDICATE = FCMP_TRUE + 1
|
||||
};
|
||||
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
FCmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
@ -815,7 +792,17 @@ public:
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertBefore) {
|
||||
) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, Name,
|
||||
InsertBefore) {
|
||||
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
|
||||
"Invalid FCmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to FCmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert(Op0Ty->isFloatingPoint() &&
|
||||
"Invalid operand types for FCmp instruction");
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
@ -825,7 +812,17 @@ public:
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertAtEnd) {
|
||||
) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, Name,
|
||||
InsertAtEnd) {
|
||||
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
|
||||
"Invalid FCmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to FCmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert(Op0Ty->isFloatingPoint() &&
|
||||
"Invalid operand types for FCmp instruction");
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
@ -897,6 +894,100 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VICmpInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This instruction compares its operands according to the predicate given
|
||||
/// to the constructor. It only operates on vectors of integers.
|
||||
/// The operands must be identical types.
|
||||
/// @brief Represents a vector integer comparison operator.
|
||||
class VICmpInst: public CmpInst {
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
VICmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(LHS->getType(), Instruction::VICmp, pred, LHS, RHS, Name,
|
||||
InsertBefore) {
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
VICmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(LHS->getType(), Instruction::VICmp, pred, LHS, RHS, Name,
|
||||
InsertAtEnd) {
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
Predicate getPredicate() const { return Predicate(SubclassData); }
|
||||
|
||||
virtual VICmpInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const VICmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::VICmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VFCmpInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This instruction compares its operands according to the predicate given
|
||||
/// to the constructor. It only operates on vectors of floating point values.
|
||||
/// The operands must be identical types.
|
||||
/// @brief Represents a vector floating point comparison operator.
|
||||
class VFCmpInst: public CmpInst {
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
VFCmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(VectorType::getInteger(cast<VectorType>(LHS->getType())),
|
||||
Instruction::VFCmp, pred, LHS, RHS, Name, InsertBefore) {
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
VFCmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(VectorType::getInteger(cast<VectorType>(LHS->getType())),
|
||||
Instruction::VFCmp, pred, LHS, RHS, Name, InsertAtEnd) {
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
Predicate getPredicate() const { return Predicate(SubclassData); }
|
||||
|
||||
virtual VFCmpInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const VFCmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::VFCmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CallInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1908,8 +1999,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
|
||||
// InvokeInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===---------------------------------------------------------------------------
|
||||
|
||||
/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the
|
||||
/// calling convention of the call.
|
||||
///
|
||||
|
@ -169,6 +169,8 @@ public:
|
||||
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitVICmpInst(VICmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitVFCmpInst(VFCmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
|
||||
|
@ -566,6 +566,8 @@ int LLLexer::LexIdentifier() {
|
||||
INSTKEYWORD("xor", BinaryOpVal, Xor, XOR);
|
||||
INSTKEYWORD("icmp", OtherOpVal, ICmp, ICMP);
|
||||
INSTKEYWORD("fcmp", OtherOpVal, FCmp, FCMP);
|
||||
INSTKEYWORD("vicmp", OtherOpVal, VICmp, VICMP);
|
||||
INSTKEYWORD("vfcmp", OtherOpVal, VFCmp, VFCMP);
|
||||
|
||||
INSTKEYWORD("phi", OtherOpVal, PHI, PHI_TOK);
|
||||
INSTKEYWORD("call", OtherOpVal, Call, CALL);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -127,66 +127,68 @@
|
||||
ASHR = 343,
|
||||
ICMP = 344,
|
||||
FCMP = 345,
|
||||
EQ = 346,
|
||||
NE = 347,
|
||||
SLT = 348,
|
||||
SGT = 349,
|
||||
SLE = 350,
|
||||
SGE = 351,
|
||||
ULT = 352,
|
||||
UGT = 353,
|
||||
ULE = 354,
|
||||
UGE = 355,
|
||||
OEQ = 356,
|
||||
ONE = 357,
|
||||
OLT = 358,
|
||||
OGT = 359,
|
||||
OLE = 360,
|
||||
OGE = 361,
|
||||
ORD = 362,
|
||||
UNO = 363,
|
||||
UEQ = 364,
|
||||
UNE = 365,
|
||||
MALLOC = 366,
|
||||
ALLOCA = 367,
|
||||
FREE = 368,
|
||||
LOAD = 369,
|
||||
STORE = 370,
|
||||
GETELEMENTPTR = 371,
|
||||
TRUNC = 372,
|
||||
ZEXT = 373,
|
||||
SEXT = 374,
|
||||
FPTRUNC = 375,
|
||||
FPEXT = 376,
|
||||
BITCAST = 377,
|
||||
UITOFP = 378,
|
||||
SITOFP = 379,
|
||||
FPTOUI = 380,
|
||||
FPTOSI = 381,
|
||||
INTTOPTR = 382,
|
||||
PTRTOINT = 383,
|
||||
PHI_TOK = 384,
|
||||
SELECT = 385,
|
||||
VAARG = 386,
|
||||
EXTRACTELEMENT = 387,
|
||||
INSERTELEMENT = 388,
|
||||
SHUFFLEVECTOR = 389,
|
||||
GETRESULT = 390,
|
||||
SIGNEXT = 391,
|
||||
ZEROEXT = 392,
|
||||
NORETURN = 393,
|
||||
INREG = 394,
|
||||
SRET = 395,
|
||||
NOUNWIND = 396,
|
||||
NOALIAS = 397,
|
||||
BYVAL = 398,
|
||||
NEST = 399,
|
||||
READNONE = 400,
|
||||
READONLY = 401,
|
||||
GC = 402,
|
||||
DEFAULT = 403,
|
||||
HIDDEN = 404,
|
||||
PROTECTED = 405
|
||||
VICMP = 346,
|
||||
VFCMP = 347,
|
||||
EQ = 348,
|
||||
NE = 349,
|
||||
SLT = 350,
|
||||
SGT = 351,
|
||||
SLE = 352,
|
||||
SGE = 353,
|
||||
ULT = 354,
|
||||
UGT = 355,
|
||||
ULE = 356,
|
||||
UGE = 357,
|
||||
OEQ = 358,
|
||||
ONE = 359,
|
||||
OLT = 360,
|
||||
OGT = 361,
|
||||
OLE = 362,
|
||||
OGE = 363,
|
||||
ORD = 364,
|
||||
UNO = 365,
|
||||
UEQ = 366,
|
||||
UNE = 367,
|
||||
MALLOC = 368,
|
||||
ALLOCA = 369,
|
||||
FREE = 370,
|
||||
LOAD = 371,
|
||||
STORE = 372,
|
||||
GETELEMENTPTR = 373,
|
||||
TRUNC = 374,
|
||||
ZEXT = 375,
|
||||
SEXT = 376,
|
||||
FPTRUNC = 377,
|
||||
FPEXT = 378,
|
||||
BITCAST = 379,
|
||||
UITOFP = 380,
|
||||
SITOFP = 381,
|
||||
FPTOUI = 382,
|
||||
FPTOSI = 383,
|
||||
INTTOPTR = 384,
|
||||
PTRTOINT = 385,
|
||||
PHI_TOK = 386,
|
||||
SELECT = 387,
|
||||
VAARG = 388,
|
||||
EXTRACTELEMENT = 389,
|
||||
INSERTELEMENT = 390,
|
||||
SHUFFLEVECTOR = 391,
|
||||
GETRESULT = 392,
|
||||
SIGNEXT = 393,
|
||||
ZEROEXT = 394,
|
||||
NORETURN = 395,
|
||||
INREG = 396,
|
||||
SRET = 397,
|
||||
NOUNWIND = 398,
|
||||
NOALIAS = 399,
|
||||
BYVAL = 400,
|
||||
NEST = 401,
|
||||
READNONE = 402,
|
||||
READONLY = 403,
|
||||
GC = 404,
|
||||
DEFAULT = 405,
|
||||
HIDDEN = 406,
|
||||
PROTECTED = 407
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@ -278,73 +280,75 @@
|
||||
#define ASHR 343
|
||||
#define ICMP 344
|
||||
#define FCMP 345
|
||||
#define EQ 346
|
||||
#define NE 347
|
||||
#define SLT 348
|
||||
#define SGT 349
|
||||
#define SLE 350
|
||||
#define SGE 351
|
||||
#define ULT 352
|
||||
#define UGT 353
|
||||
#define ULE 354
|
||||
#define UGE 355
|
||||
#define OEQ 356
|
||||
#define ONE 357
|
||||
#define OLT 358
|
||||
#define OGT 359
|
||||
#define OLE 360
|
||||
#define OGE 361
|
||||
#define ORD 362
|
||||
#define UNO 363
|
||||
#define UEQ 364
|
||||
#define UNE 365
|
||||
#define MALLOC 366
|
||||
#define ALLOCA 367
|
||||
#define FREE 368
|
||||
#define LOAD 369
|
||||
#define STORE 370
|
||||
#define GETELEMENTPTR 371
|
||||
#define TRUNC 372
|
||||
#define ZEXT 373
|
||||
#define SEXT 374
|
||||
#define FPTRUNC 375
|
||||
#define FPEXT 376
|
||||
#define BITCAST 377
|
||||
#define UITOFP 378
|
||||
#define SITOFP 379
|
||||
#define FPTOUI 380
|
||||
#define FPTOSI 381
|
||||
#define INTTOPTR 382
|
||||
#define PTRTOINT 383
|
||||
#define PHI_TOK 384
|
||||
#define SELECT 385
|
||||
#define VAARG 386
|
||||
#define EXTRACTELEMENT 387
|
||||
#define INSERTELEMENT 388
|
||||
#define SHUFFLEVECTOR 389
|
||||
#define GETRESULT 390
|
||||
#define SIGNEXT 391
|
||||
#define ZEROEXT 392
|
||||
#define NORETURN 393
|
||||
#define INREG 394
|
||||
#define SRET 395
|
||||
#define NOUNWIND 396
|
||||
#define NOALIAS 397
|
||||
#define BYVAL 398
|
||||
#define NEST 399
|
||||
#define READNONE 400
|
||||
#define READONLY 401
|
||||
#define GC 402
|
||||
#define DEFAULT 403
|
||||
#define HIDDEN 404
|
||||
#define PROTECTED 405
|
||||
#define VICMP 346
|
||||
#define VFCMP 347
|
||||
#define EQ 348
|
||||
#define NE 349
|
||||
#define SLT 350
|
||||
#define SGT 351
|
||||
#define SLE 352
|
||||
#define SGE 353
|
||||
#define ULT 354
|
||||
#define UGT 355
|
||||
#define ULE 356
|
||||
#define UGE 357
|
||||
#define OEQ 358
|
||||
#define ONE 359
|
||||
#define OLT 360
|
||||
#define OGT 361
|
||||
#define OLE 362
|
||||
#define OGE 363
|
||||
#define ORD 364
|
||||
#define UNO 365
|
||||
#define UEQ 366
|
||||
#define UNE 367
|
||||
#define MALLOC 368
|
||||
#define ALLOCA 369
|
||||
#define FREE 370
|
||||
#define LOAD 371
|
||||
#define STORE 372
|
||||
#define GETELEMENTPTR 373
|
||||
#define TRUNC 374
|
||||
#define ZEXT 375
|
||||
#define SEXT 376
|
||||
#define FPTRUNC 377
|
||||
#define FPEXT 378
|
||||
#define BITCAST 379
|
||||
#define UITOFP 380
|
||||
#define SITOFP 381
|
||||
#define FPTOUI 382
|
||||
#define FPTOSI 383
|
||||
#define INTTOPTR 384
|
||||
#define PTRTOINT 385
|
||||
#define PHI_TOK 386
|
||||
#define SELECT 387
|
||||
#define VAARG 388
|
||||
#define EXTRACTELEMENT 389
|
||||
#define INSERTELEMENT 390
|
||||
#define SHUFFLEVECTOR 391
|
||||
#define GETRESULT 392
|
||||
#define SIGNEXT 393
|
||||
#define ZEROEXT 394
|
||||
#define NORETURN 395
|
||||
#define INREG 396
|
||||
#define SRET 397
|
||||
#define NOUNWIND 398
|
||||
#define NOALIAS 399
|
||||
#define BYVAL 400
|
||||
#define NEST 401
|
||||
#define READNONE 402
|
||||
#define READONLY 403
|
||||
#define GC 404
|
||||
#define DEFAULT 405
|
||||
#define HIDDEN 406
|
||||
#define PROTECTED 407
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 949 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
#line 949 "/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
{
|
||||
llvm::Module *ModuleVal;
|
||||
llvm::Function *FunctionVal;
|
||||
@ -392,7 +396,7 @@ typedef union YYSTYPE
|
||||
llvm::FCmpInst::Predicate FPredicate;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 396 "llvmAsmParser.tab.h"
|
||||
#line 400 "llvmAsmParser.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
@ -1075,7 +1075,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
|
||||
%token <BinaryOpVal> SHL LSHR ASHR
|
||||
|
||||
%token <OtherOpVal> ICMP FCMP
|
||||
%token <OtherOpVal> ICMP FCMP VICMP VFCMP
|
||||
%type <IPredicate> IPredicates
|
||||
%type <FPredicate> FPredicates
|
||||
%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
|
||||
@ -1939,6 +1939,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||
GEN_ERROR("fcmp operand types must match");
|
||||
$$ = ConstantExpr::getFCmp($2, $4, $6);
|
||||
}
|
||||
| VICMP IPredicates '(' ConstVal ',' ConstVal ')' {
|
||||
if ($4->getType() != $6->getType())
|
||||
GEN_ERROR("vicmp operand types must match");
|
||||
$$ = ConstantExpr::getVICmp($2, $4, $6);
|
||||
}
|
||||
| VFCMP FPredicates '(' ConstVal ',' ConstVal ')' {
|
||||
if ($4->getType() != $6->getType())
|
||||
GEN_ERROR("vfcmp operand types must match");
|
||||
$$ = ConstantExpr::getVFCmp($2, $4, $6);
|
||||
}
|
||||
| EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
|
||||
if (!ExtractElementInst::isValidOperands($3, $5))
|
||||
GEN_ERROR("Invalid extractelement operands");
|
||||
@ -2891,6 +2901,34 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
GEN_ERROR("fcmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| VICMP IPredicates Types ValueRef ',' ValueRef {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||
if (!isa<VectorType>((*$3).get()))
|
||||
GEN_ERROR("Scalar types not supported by vicmp instruction");
|
||||
Value* tmpVal1 = getVal(*$3, $4);
|
||||
CHECK_FOR_ERROR
|
||||
Value* tmpVal2 = getVal(*$3, $6);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
||||
if ($$ == 0)
|
||||
GEN_ERROR("icmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| VFCMP FPredicates Types ValueRef ',' ValueRef {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||
if (!isa<VectorType>((*$3).get()))
|
||||
GEN_ERROR("Scalar types not supported by vfcmp instruction");
|
||||
Value* tmpVal1 = getVal(*$3, $4);
|
||||
CHECK_FOR_ERROR
|
||||
Value* tmpVal2 = getVal(*$3, $6);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
||||
if ($$ == 0)
|
||||
GEN_ERROR("fcmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| CastOps ResolvedVal TO Types {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());
|
||||
|
@ -1075,7 +1075,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
|
||||
%token <BinaryOpVal> SHL LSHR ASHR
|
||||
|
||||
%token <OtherOpVal> ICMP FCMP
|
||||
%token <OtherOpVal> ICMP FCMP VICMP VFCMP
|
||||
%type <IPredicate> IPredicates
|
||||
%type <FPredicate> FPredicates
|
||||
%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
|
||||
@ -1939,6 +1939,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||
GEN_ERROR("fcmp operand types must match");
|
||||
$$ = ConstantExpr::getFCmp($2, $4, $6);
|
||||
}
|
||||
| VICMP IPredicates '(' ConstVal ',' ConstVal ')' {
|
||||
if ($4->getType() != $6->getType())
|
||||
GEN_ERROR("vicmp operand types must match");
|
||||
$$ = ConstantExpr::getVICmp($2, $4, $6);
|
||||
}
|
||||
| VFCMP FPredicates '(' ConstVal ',' ConstVal ')' {
|
||||
if ($4->getType() != $6->getType())
|
||||
GEN_ERROR("vfcmp operand types must match");
|
||||
$$ = ConstantExpr::getVFCmp($2, $4, $6);
|
||||
}
|
||||
| EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
|
||||
if (!ExtractElementInst::isValidOperands($3, $5))
|
||||
GEN_ERROR("Invalid extractelement operands");
|
||||
@ -2891,6 +2901,34 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
GEN_ERROR("fcmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| VICMP IPredicates Types ValueRef ',' ValueRef {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||
if (!isa<VectorType>((*$3).get()))
|
||||
GEN_ERROR("Scalar types not supported by vicmp instruction");
|
||||
Value* tmpVal1 = getVal(*$3, $4);
|
||||
CHECK_FOR_ERROR
|
||||
Value* tmpVal2 = getVal(*$3, $6);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
||||
if ($$ == 0)
|
||||
GEN_ERROR("icmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| VFCMP FPredicates Types ValueRef ',' ValueRef {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||
if (!isa<VectorType>((*$3).get()))
|
||||
GEN_ERROR("Scalar types not supported by vfcmp instruction");
|
||||
Value* tmpVal1 = getVal(*$3, $4);
|
||||
CHECK_FOR_ERROR
|
||||
Value* tmpVal2 = getVal(*$3, $6);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
||||
if ($$ == 0)
|
||||
GEN_ERROR("fcmp operator returned null");
|
||||
delete $3;
|
||||
}
|
||||
| CastOps ResolvedVal TO Types {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());
|
||||
|
@ -818,8 +818,12 @@ bool BitcodeReader::ParseConstants() {
|
||||
|
||||
if (OpTy->isFloatingPoint())
|
||||
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
|
||||
else
|
||||
else if (OpTy->isInteger())
|
||||
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
|
||||
else if (OpTy->isFPOrFPVector())
|
||||
V = ConstantExpr::getVFCmp(Record[3], Op0, Op1);
|
||||
else
|
||||
V = ConstantExpr::getVICmp(Record[3], Op0, Op1);
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_INLINEASM: {
|
||||
@ -1355,10 +1359,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
OpNum+1 != Record.size())
|
||||
return Error("Invalid CMP record");
|
||||
|
||||
if (LHS->getType()->isFPOrFPVector())
|
||||
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
else
|
||||
if (LHS->getType()->isInteger())
|
||||
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
else if (LHS->getType()->isFloatingPoint())
|
||||
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
else if (LHS->getType()->isFPOrFPVector())
|
||||
I = new VFCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
else
|
||||
I = new VICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n]
|
||||
|
@ -635,6 +635,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||
break;
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
case Instruction::VICmp:
|
||||
case Instruction::VFCmp:
|
||||
Code = bitc::CST_CODE_CE_CMP;
|
||||
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||
@ -740,6 +742,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||
break;
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
case Instruction::VICmp:
|
||||
case Instruction::VFCmp:
|
||||
Code = bitc::FUNC_CODE_INST_CMP;
|
||||
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
||||
Vals.push_back(VE.getValueID(I.getOperand(1)));
|
||||
|
@ -1251,11 +1251,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
Out << I.getOpcodeName();
|
||||
|
||||
// Print out the compare instruction predicates
|
||||
if (const FCmpInst *FCI = dyn_cast<FCmpInst>(&I)) {
|
||||
Out << " " << getPredicateText(FCI->getPredicate());
|
||||
} else if (const ICmpInst *ICI = dyn_cast<ICmpInst>(&I)) {
|
||||
Out << " " << getPredicateText(ICI->getPredicate());
|
||||
}
|
||||
if (const CmpInst *CI = dyn_cast<CmpInst>(&I))
|
||||
Out << " " << getPredicateText(CI->getPredicate());
|
||||
|
||||
// Print out the type of the operands...
|
||||
const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
|
||||
|
@ -557,9 +557,9 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
|
||||
return User::operator new(s, 2);
|
||||
}
|
||||
unsigned short predicate;
|
||||
CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred,
|
||||
Constant* LHS, Constant* RHS)
|
||||
: ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) {
|
||||
CompareConstantExpr(const Type *ty, Instruction::OtherOps opc,
|
||||
unsigned short pred, Constant* LHS, Constant* RHS)
|
||||
: ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
|
||||
Op<0>().init(LHS, this);
|
||||
Op<1>().init(RHS, this);
|
||||
}
|
||||
@ -690,7 +690,10 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
|
||||
return get(Instruction::Xor, C1, C2);
|
||||
}
|
||||
unsigned ConstantExpr::getPredicate() const {
|
||||
assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
|
||||
assert(getOpcode() == Instruction::FCmp ||
|
||||
getOpcode() == Instruction::ICmp ||
|
||||
getOpcode() == Instruction::VFCmp ||
|
||||
getOpcode() == Instruction::VICmp);
|
||||
return ((const CompareConstantExpr*)this)->predicate;
|
||||
}
|
||||
Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
|
||||
@ -1564,10 +1567,16 @@ namespace llvm {
|
||||
// value and it is combined with the instruction opcode by multiplying
|
||||
// the opcode by one hundred. We must decode this to get the predicate.
|
||||
if (V.opcode == Instruction::ICmp)
|
||||
return new CompareConstantExpr(Instruction::ICmp, V.predicate,
|
||||
return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate,
|
||||
V.operands[0], V.operands[1]);
|
||||
if (V.opcode == Instruction::FCmp)
|
||||
return new CompareConstantExpr(Instruction::FCmp, V.predicate,
|
||||
return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate,
|
||||
V.operands[0], V.operands[1]);
|
||||
if (V.opcode == Instruction::VICmp)
|
||||
return new CompareConstantExpr(Ty, Instruction::VICmp, V.predicate,
|
||||
V.operands[0], V.operands[1]);
|
||||
if (V.opcode == Instruction::VFCmp)
|
||||
return new CompareConstantExpr(Ty, Instruction::VFCmp, V.predicate,
|
||||
V.operands[0], V.operands[1]);
|
||||
assert(0 && "Invalid ConstantExpr!");
|
||||
return 0;
|
||||
@ -2029,6 +2038,79 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
|
||||
return ExprConstants->getOrCreate(Type::Int1Ty, Key);
|
||||
}
|
||||
|
||||
Constant *
|
||||
ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
|
||||
assert(isa<VectorType>(LHS->getType()) &&
|
||||
"Tried to create vicmp operation on non-vector type!");
|
||||
assert(LHS->getType() == RHS->getType());
|
||||
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
|
||||
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate");
|
||||
|
||||
const Type *VTy = cast<VectorType>(LHS->getType());
|
||||
const Type *EltTy = VTy->getElementType();
|
||||
unsigned NumElts = VTy->getNumElements();
|
||||
|
||||
SmallVector<Constant *, 8> Elts;
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
|
||||
RHS->getOperand(i));
|
||||
if (FC) {
|
||||
uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
|
||||
if (Val != 0ULL)
|
||||
Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
|
||||
else
|
||||
Elts.push_back(ConstantInt::get(EltTy, 0ULL));
|
||||
}
|
||||
}
|
||||
if (Elts.size() == NumElts)
|
||||
return ConstantVector::get(&Elts[0], Elts.size());
|
||||
|
||||
// Look up the constant in the table first to ensure uniqueness
|
||||
std::vector<Constant*> ArgVec;
|
||||
ArgVec.push_back(LHS);
|
||||
ArgVec.push_back(RHS);
|
||||
// Get the key type with both the opcode and predicate
|
||||
const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred);
|
||||
return ExprConstants->getOrCreate(LHS->getType(), Key);
|
||||
}
|
||||
|
||||
Constant *
|
||||
ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
|
||||
assert(isa<VectorType>(LHS->getType()) &&
|
||||
"Tried to create vfcmp operation on non-vector type!");
|
||||
assert(LHS->getType() == RHS->getType());
|
||||
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid VFCmp Predicate");
|
||||
|
||||
const VectorType *VTy = cast<VectorType>(LHS->getType());
|
||||
unsigned NumElts = VTy->getNumElements();
|
||||
const Type *EltTy = VTy->getElementType();
|
||||
const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits());
|
||||
const Type *ResultTy = VectorType::get(REltTy, NumElts);
|
||||
|
||||
SmallVector<Constant *, 8> Elts;
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
|
||||
RHS->getOperand(i));
|
||||
if (FC) {
|
||||
uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
|
||||
if (Val != 0ULL)
|
||||
Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
|
||||
else
|
||||
Elts.push_back(ConstantInt::get(REltTy, 0ULL));
|
||||
}
|
||||
}
|
||||
if (Elts.size() == NumElts)
|
||||
return ConstantVector::get(&Elts[0], Elts.size());
|
||||
|
||||
// Look up the constant in the table first to ensure uniqueness
|
||||
std::vector<Constant*> ArgVec;
|
||||
ArgVec.push_back(LHS);
|
||||
ArgVec.push_back(RHS);
|
||||
// Get the key type with both the opcode and predicate
|
||||
const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred);
|
||||
return ExprConstants->getOrCreate(ResultTy, Key);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
|
||||
Constant *Idx) {
|
||||
if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
|
||||
|
@ -128,6 +128,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
|
||||
// Other instructions...
|
||||
case ICmp: return "icmp";
|
||||
case FCmp: return "fcmp";
|
||||
case VICmp: return "vicmp";
|
||||
case VFCmp: return "vfcmp";
|
||||
case PHI: return "phi";
|
||||
case Select: return "select";
|
||||
case Call: return "call";
|
||||
|
@ -2332,9 +2332,10 @@ BitCastInst::BitCastInst(
|
||||
// CmpInst Classes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
|
||||
const std::string &Name, Instruction *InsertBefore)
|
||||
: Instruction(Type::Int1Ty, op,
|
||||
CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
|
||||
Value *LHS, Value *RHS, const std::string &Name,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(ty, op,
|
||||
OperandTraits<CmpInst>::op_begin(this),
|
||||
OperandTraits<CmpInst>::operands(this),
|
||||
InsertBefore) {
|
||||
@ -2342,34 +2343,12 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
|
||||
Op<1>().init(RHS, this);
|
||||
SubclassData = predicate;
|
||||
setName(Name);
|
||||
if (op == Instruction::ICmp) {
|
||||
assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
|
||||
predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
|
||||
"Invalid ICmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to ICmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
|
||||
"Invalid operand types for ICmp instruction");
|
||||
return;
|
||||
}
|
||||
assert(op == Instruction::FCmp && "Invalid CmpInst opcode");
|
||||
assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE &&
|
||||
"Invalid FCmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to FCmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert(Op0Ty->isFloatingPoint() &&
|
||||
"Invalid operand types for FCmp instruction");
|
||||
}
|
||||
|
||||
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd)
|
||||
: Instruction(Type::Int1Ty, op,
|
||||
CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
|
||||
Value *LHS, Value *RHS, const std::string &Name,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(ty, op,
|
||||
OperandTraits<CmpInst>::op_begin(this),
|
||||
OperandTraits<CmpInst>::operands(this),
|
||||
InsertAtEnd) {
|
||||
@ -2377,52 +2356,44 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
|
||||
Op<1>().init(RHS, this);
|
||||
SubclassData = predicate;
|
||||
setName(Name);
|
||||
if (op == Instruction::ICmp) {
|
||||
assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
|
||||
predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
|
||||
"Invalid ICmp predicate value");
|
||||
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to ICmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
|
||||
"Invalid operand types for ICmp instruction");
|
||||
return;
|
||||
}
|
||||
assert(op == Instruction::FCmp && "Invalid CmpInst opcode");
|
||||
assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE &&
|
||||
"Invalid FCmp predicate value");
|
||||
const Type* Op0Ty = getOperand(0)->getType();
|
||||
const Type* Op1Ty = getOperand(1)->getType();
|
||||
assert(Op0Ty == Op1Ty &&
|
||||
"Both operands to FCmp instruction are not of the same type!");
|
||||
// Check that the operands are the right type
|
||||
assert(Op0Ty->isFloatingPoint() &&
|
||||
"Invalid operand types for FCmp instruction");
|
||||
}
|
||||
|
||||
CmpInst *
|
||||
CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2,
|
||||
const std::string &Name, Instruction *InsertBefore) {
|
||||
if (Op == Instruction::ICmp) {
|
||||
return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name,
|
||||
return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertBefore);
|
||||
}
|
||||
return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertBefore);
|
||||
if (Op == Instruction::FCmp) {
|
||||
return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertBefore);
|
||||
}
|
||||
if (Op == Instruction::VICmp) {
|
||||
return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertBefore);
|
||||
}
|
||||
return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertBefore);
|
||||
}
|
||||
|
||||
CmpInst *
|
||||
CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd) {
|
||||
if (Op == Instruction::ICmp) {
|
||||
return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name,
|
||||
return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertAtEnd);
|
||||
}
|
||||
return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertAtEnd);
|
||||
if (Op == Instruction::FCmp) {
|
||||
return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertAtEnd);
|
||||
}
|
||||
if (Op == Instruction::VICmp) {
|
||||
return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertAtEnd);
|
||||
}
|
||||
return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
|
||||
InsertAtEnd);
|
||||
}
|
||||
|
||||
void CmpInst::swapOperands() {
|
||||
@ -2813,6 +2784,13 @@ ICmpInst* ICmpInst::clone() const {
|
||||
return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
|
||||
}
|
||||
|
||||
VFCmpInst* VFCmpInst::clone() const {
|
||||
return new VFCmpInst(getPredicate(), Op<0>(), Op<1>());
|
||||
}
|
||||
VICmpInst* VICmpInst::clone() const {
|
||||
return new VICmpInst(getPredicate(), Op<0>(), Op<1>());
|
||||
}
|
||||
|
||||
MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
|
||||
AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); }
|
||||
FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user