200 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
201 virtual const Type *sub( const Type *, const Type * ) const;
202 };
203
204 //------------------------------CmpNNode--------------------------------------
205 // Compare 2 narrow oop values, returning condition codes (-1, 0 or 1).
206 class CmpNNode : public CmpNode {
207 public:
208 CmpNNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
209 virtual int Opcode() const;
210 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
211 virtual const Type *sub( const Type *, const Type * ) const;
212 };
213
214 //------------------------------CmpLNode---------------------------------------
215 // Compare 2 long values, returning condition codes (-1, 0 or 1).
216 class CmpLNode : public CmpNode {
217 public:
218 CmpLNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
219 virtual int Opcode() const;
220 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
221 virtual const Type *sub( const Type *, const Type * ) const;
222 };
223
224 //------------------------------CmpULNode---------------------------------------
225 // Compare 2 unsigned long values, returning condition codes (-1, 0 or 1).
226 class CmpULNode : public CmpNode {
227 public:
228 CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { }
229 virtual int Opcode() const;
230 virtual const Type* sub(const Type*, const Type*) const;
231 };
232
233 //------------------------------CmpL3Node--------------------------------------
234 // Compare 2 long values, returning integer value (-1, 0 or 1).
235 class CmpL3Node : public CmpLNode {
236 public:
237 CmpL3Node( Node *in1, Node *in2 ) : CmpLNode(in1,in2) {
238 // Since it is not consumed by Bools, it is not really a Cmp.
239 init_class_id(Class_Sub);
240 }
292 virtual int Opcode() const;
293 virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return nullptr; }
294 const Type* Value(PhaseGVN* phase) const;
295 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
296 };
297
298 //------------------------------CmpD3Node--------------------------------------
299 // Compare 2 double values, returning integer value (-1, 0 or 1).
300 // This implements the Java bytecode dcmpl, so unordered returns -1.
301 // Operands may not commute.
302 class CmpD3Node : public CmpDNode {
303 public:
304 CmpD3Node( Node *in1, Node *in2 ) : CmpDNode(in1,in2) {
305 // Since it is not consumed by Bools, it is not really a Cmp.
306 init_class_id(Class_Sub);
307 }
308 virtual int Opcode() const;
309 virtual uint ideal_reg() const { return Op_RegI; }
310 };
311
312
313 //------------------------------BoolTest---------------------------------------
314 // Convert condition codes to a boolean test value (0 or -1).
315 // We pick the values as 3 bits; the low order 2 bits we compare against the
316 // condition codes, the high bit flips the sense of the result.
317 // For vector compares, additionally, the 4th bit indicates if the compare is unsigned
318 struct BoolTest {
319 enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, never = 8, illegal = 9,
320 // The following values are used with vector compares
321 // A BoolTest value should not be constructed for such values
322 unsigned_compare = 16,
323 ule = unsigned_compare | le, uge = unsigned_compare | ge, ult = unsigned_compare | lt, ugt = unsigned_compare | gt };
324 mask _test;
325 BoolTest( mask btm ) : _test(btm) { assert((btm & unsigned_compare) == 0, "unsupported");}
326 const Type *cc2logical( const Type *CC ) const;
327 // Commute the test. I use a small table lookup. The table is created as
328 // a simple char array where each element is the ASCII version of a 'mask'
329 // enum from above.
330 mask commute( ) const { return mask("032147658"[_test]-'0'); }
331 mask negate( ) const { return negate_mask(_test); }
|
200 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
201 virtual const Type *sub( const Type *, const Type * ) const;
202 };
203
204 //------------------------------CmpNNode--------------------------------------
205 // Compare 2 narrow oop values, returning condition codes (-1, 0 or 1).
206 class CmpNNode : public CmpNode {
207 public:
208 CmpNNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
209 virtual int Opcode() const;
210 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
211 virtual const Type *sub( const Type *, const Type * ) const;
212 };
213
214 //------------------------------CmpLNode---------------------------------------
215 // Compare 2 long values, returning condition codes (-1, 0 or 1).
216 class CmpLNode : public CmpNode {
217 public:
218 CmpLNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
219 virtual int Opcode() const;
220 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
221 virtual const Type *sub( const Type *, const Type * ) const;
222 };
223
224 //------------------------------CmpULNode---------------------------------------
225 // Compare 2 unsigned long values, returning condition codes (-1, 0 or 1).
226 class CmpULNode : public CmpNode {
227 public:
228 CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { }
229 virtual int Opcode() const;
230 virtual const Type* sub(const Type*, const Type*) const;
231 };
232
233 //------------------------------CmpL3Node--------------------------------------
234 // Compare 2 long values, returning integer value (-1, 0 or 1).
235 class CmpL3Node : public CmpLNode {
236 public:
237 CmpL3Node( Node *in1, Node *in2 ) : CmpLNode(in1,in2) {
238 // Since it is not consumed by Bools, it is not really a Cmp.
239 init_class_id(Class_Sub);
240 }
292 virtual int Opcode() const;
293 virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return nullptr; }
294 const Type* Value(PhaseGVN* phase) const;
295 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
296 };
297
298 //------------------------------CmpD3Node--------------------------------------
299 // Compare 2 double values, returning integer value (-1, 0 or 1).
300 // This implements the Java bytecode dcmpl, so unordered returns -1.
301 // Operands may not commute.
302 class CmpD3Node : public CmpDNode {
303 public:
304 CmpD3Node( Node *in1, Node *in2 ) : CmpDNode(in1,in2) {
305 // Since it is not consumed by Bools, it is not really a Cmp.
306 init_class_id(Class_Sub);
307 }
308 virtual int Opcode() const;
309 virtual uint ideal_reg() const { return Op_RegI; }
310 };
311
312 //--------------------------FlatArrayCheckNode---------------------------------
313 // Returns true if one of the input array objects or array klass ptrs (there
314 // can be multiple) is flat.
315 class FlatArrayCheckNode : public CmpNode {
316 public:
317 enum {
318 Control,
319 Memory,
320 ArrayOrKlass
321 };
322 FlatArrayCheckNode(Compile* C, Node* mem, Node* array_or_klass) : CmpNode(mem, array_or_klass) {
323 init_class_id(Class_FlatArrayCheck);
324 init_flags(Flag_is_macro);
325 C->add_macro_node(this);
326 }
327 virtual int Opcode() const;
328 virtual const Type* sub(const Type*, const Type*) const { ShouldNotReachHere(); return nullptr; }
329 const Type* Value(PhaseGVN* phase) const;
330 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
331 };
332
333 //------------------------------BoolTest---------------------------------------
334 // Convert condition codes to a boolean test value (0 or -1).
335 // We pick the values as 3 bits; the low order 2 bits we compare against the
336 // condition codes, the high bit flips the sense of the result.
337 // For vector compares, additionally, the 4th bit indicates if the compare is unsigned
338 struct BoolTest {
339 enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, never = 8, illegal = 9,
340 // The following values are used with vector compares
341 // A BoolTest value should not be constructed for such values
342 unsigned_compare = 16,
343 ule = unsigned_compare | le, uge = unsigned_compare | ge, ult = unsigned_compare | lt, ugt = unsigned_compare | gt };
344 mask _test;
345 BoolTest( mask btm ) : _test(btm) { assert((btm & unsigned_compare) == 0, "unsupported");}
346 const Type *cc2logical( const Type *CC ) const;
347 // Commute the test. I use a small table lookup. The table is created as
348 // a simple char array where each element is the ASCII version of a 'mask'
349 // enum from above.
350 mask commute( ) const { return mask("032147658"[_test]-'0'); }
351 mask negate( ) const { return negate_mask(_test); }
|