comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java @ 18839:1b7dbb81df4f

Use ArithmeticOpTable for shift operations.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 12 Jan 2015 13:32:43 +0100
parents ca81508f2a19
children a7ee2e1f0d4e
comparison
equal deleted inserted replaced
18838:ae827362559d 18839:1b7dbb81df4f
1 /* 1 /*
2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
22 */ 22 */
23 package com.oracle.graal.nodes.type; 23 package com.oracle.graal.nodes.type;
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import com.oracle.graal.api.code.*;
28 import com.oracle.graal.api.meta.*; 27 import com.oracle.graal.api.meta.*;
29 import com.oracle.graal.compiler.common.type.*; 28 import com.oracle.graal.compiler.common.type.*;
30 import com.oracle.graal.nodes.*; 29 import com.oracle.graal.nodes.*;
31 30
32 /** 31 /**
43 } 42 }
44 return stamp; 43 return stamp;
45 } else { 44 } else {
46 return StampFactory.forVoid(); 45 return StampFactory.forVoid();
47 } 46 }
48 }
49
50 public static Stamp rightShift(Stamp value, Stamp shift) {
51 if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
52 return rightShift((IntegerStamp) value, (IntegerStamp) shift);
53 }
54 return value.illegal();
55 }
56
57 public static Stamp rightShift(IntegerStamp value, IntegerStamp shift) {
58 int bits = value.getBits();
59 if (shift.lowerBound() == shift.upperBound()) {
60 int extraBits = 64 - bits;
61 long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
62 long shiftCount = shift.lowerBound() & shiftMask;
63 long defaultMask = CodeUtil.mask(bits);
64 // shifting back and forth performs sign extension
65 long downMask = (value.downMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
66 long upMask = (value.upMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
67 return new IntegerStamp(bits, value.lowerBound() >> shiftCount, value.upperBound() >> shiftCount, downMask, upMask);
68 }
69 long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
70 return IntegerStamp.stampForMask(bits, 0, mask);
71 }
72
73 public static Stamp unsignedRightShift(Stamp value, Stamp shift) {
74 if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
75 return unsignedRightShift((IntegerStamp) value, (IntegerStamp) shift);
76 }
77 return value.illegal();
78 }
79
80 public static Stamp unsignedRightShift(IntegerStamp value, IntegerStamp shift) {
81 int bits = value.getBits();
82 if (shift.lowerBound() == shift.upperBound()) {
83 long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
84 long shiftCount = shift.lowerBound() & shiftMask;
85 long downMask = value.downMask() >>> shiftCount;
86 long upMask = value.upMask() >>> shiftCount;
87 if (value.lowerBound() < 0) {
88 return new IntegerStamp(bits, downMask, upMask, downMask, upMask);
89 } else {
90 return new IntegerStamp(bits, value.lowerBound() >>> shiftCount, value.upperBound() >>> shiftCount, downMask, upMask);
91 }
92 }
93 long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
94 return IntegerStamp.stampForMask(bits, 0, mask);
95 }
96
97 public static Stamp leftShift(Stamp value, Stamp shift) {
98 if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
99 return leftShift((IntegerStamp) value, (IntegerStamp) shift);
100 }
101 return value.illegal();
102 }
103
104 public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) {
105 int bits = value.getBits();
106 long defaultMask = CodeUtil.mask(bits);
107 if (value.upMask() == 0) {
108 return value;
109 }
110 int shiftBits = bits > 32 ? 6 : 5;
111 long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
112 if (shift.lowerBound() == shift.upperBound()) {
113 int shiftAmount = (int) (shift.lowerBound() & shiftMask);
114 if (shiftAmount == 0) {
115 return value;
116 }
117 // the mask of bits that will be lost or shifted into the sign bit
118 long removedBits = -1L << (bits - shiftAmount - 1);
119 if ((value.lowerBound() & removedBits) == 0 && (value.upperBound() & removedBits) == 0) {
120 // use a better stamp if neither lower nor upper bound can lose bits
121 return new IntegerStamp(bits, value.lowerBound() << shiftAmount, value.upperBound() << shiftAmount, value.downMask() << shiftAmount, value.upMask() << shiftAmount);
122 }
123 }
124 if ((shift.lowerBound() >>> shiftBits) == (shift.upperBound() >>> shiftBits)) {
125 long downMask = defaultMask;
126 long upMask = 0;
127 for (long i = shift.lowerBound(); i <= shift.upperBound(); i++) {
128 if (shift.contains(i)) {
129 downMask &= value.downMask() << (i & shiftMask);
130 upMask |= value.upMask() << (i & shiftMask);
131 }
132 }
133 Stamp result = IntegerStamp.stampForMask(bits, downMask, upMask & defaultMask);
134 return result;
135 }
136 return value.unrestricted();
137 } 47 }
138 48
139 /** 49 /**
140 * Compute the stamp resulting from the unsigned comparison being true. 50 * Compute the stamp resulting from the unsigned comparison being true.
141 * 51 *