comparison graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java @ 4314:9ce8594bedaf

Allow CiAddress as Input and Alive operands of LIR instructions.
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Thu, 19 Jan 2012 14:14:36 -0800
parents 430b5db3e6f8
children 438ab53efdd0
comparison
equal deleted inserted replaced
4313:79af35bd9fd7 4314:9ce8594bedaf
24 24
25 import static com.oracle.max.cri.ci.CiValueUtil.*; 25 import static com.oracle.max.cri.ci.CiValueUtil.*;
26 26
27 /** 27 /**
28 * Represents an address in target machine memory, specified via some combination of a base register, an index register, 28 * Represents an address in target machine memory, specified via some combination of a base register, an index register,
29 * a displacement and a scale. Note that the base and index registers may be {@link CiVariable variable}, that is as yet 29 * a displacement and a scale. Note that the base and index registers may be a variable that will get a register assigned
30 * unassigned to target machine registers. 30 * later by the register allocator.
31 */ 31 */
32 public final class CiAddress extends CiValue { 32 public final class CiAddress extends CiValue {
33 private static final long serialVersionUID = -1003772042519945089L; 33 private static final long serialVersionUID = -1003772042519945089L;
34 34
35 /** 35 /**
36 * A sentinel value used as a place holder in an instruction stream for an address that will be patched. 36 * A sentinel value used as a place holder in an instruction stream for an address that will be patched.
37 */ 37 */
38 public static final CiAddress Placeholder = new CiAddress(CiKind.Illegal, CiValue.IllegalValue); 38 public static final CiAddress Placeholder = new CiAddress(CiKind.Illegal, CiValue.IllegalValue);
39 39
40 /** 40 /**
41 * Base register that defines the start of the address computation; always present. 41 * Base register that defines the start of the address computation.
42 */
43 public final CiValue base;
44 /**
45 * Optional index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}.
46 * If not present, is denoted by {@link CiValue#IllegalValue}. 42 * If not present, is denoted by {@link CiValue#IllegalValue}.
47 */ 43 */
48 public final CiValue index; 44 public CiValue base;
45
46 /**
47 * Index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}.
48 * If not present, is denoted by {@link CiValue#IllegalValue}.
49 */
50 public CiValue index;
51
49 /** 52 /**
50 * Scaling factor for indexing, dependent on target operand size. 53 * Scaling factor for indexing, dependent on target operand size.
51 */ 54 */
52 public final Scale scale; 55 public final Scale scale;
56
53 /** 57 /**
54 * Optional additive displacement. 58 * Optional additive displacement.
55 */ 59 */
56 public final int displacement; 60 public final int displacement;
57 61
73 public CiAddress(CiKind kind, CiValue base, int displacement) { 77 public CiAddress(CiKind kind, CiValue base, int displacement) {
74 this(kind, base, IllegalValue, Scale.Times1, displacement); 78 this(kind, base, IllegalValue, Scale.Times1, displacement);
75 } 79 }
76 80
77 /** 81 /**
78 * Creates a {@code CiAddress} with given base and offset registers, no scaling and no displacement.
79 * @param kind the kind of the value being addressed
80 * @param base the base register
81 * @param offset the offset register
82 */
83 public CiAddress(CiKind kind, CiValue base, CiValue offset) {
84 this(kind, base, offset, Scale.Times1, 0);
85 }
86
87 /**
88 * Creates a {@code CiAddress} with given base and index registers, scaling and displacement. 82 * Creates a {@code CiAddress} with given base and index registers, scaling and displacement.
89 * This is the most general constructor.. 83 * This is the most general constructor..
90 * @param kind the kind of the value being addressed 84 * @param kind the kind of the value being addressed
91 * @param base the base register 85 * @param base the base register
92 * @param index the index register 86 * @param index the index register
93 * @param scale the scaling factor 87 * @param scale the scaling factor
94 * @param displacement the displacement 88 * @param displacement the displacement
95 */ 89 */
96 public CiAddress(CiKind kind, CiValue base, CiValue index, Scale scale, int displacement) { 90 public CiAddress(CiKind kind, CiValue base, CiValue index, Scale scale, int displacement) {
97 super(kind); 91 super(kind);
92 this.base = base;
93 this.index = index;
94 this.scale = scale;
95 this.displacement = displacement;
98 96
99 this.base = base; 97 assert !isConstant(base) && !isStackSlot(base);
100 if (isConstant(index)) { 98 assert !isConstant(index) && !isStackSlot(index);
101 long longIndex = ((CiConstant) index).asLong();
102 long longDisp = displacement + longIndex * scale.value;
103 if ((int) longIndex != longIndex || (int) longDisp != longDisp) {
104 throw new Error("integer overflow when computing constant displacement");
105 }
106 this.displacement = (int) longDisp;
107 this.index = IllegalValue;
108 this.scale = Scale.Times1;
109 } else {
110 this.index = index;
111 this.scale = scale;
112 this.displacement = displacement;
113 }
114 } 99 }
115 100
116 /** 101 /**
117 * A scaling factor used in complex addressing modes such as those supported by x86 platforms. 102 * A scaling factor used in complex addressing modes such as those supported by x86 platforms.
118 */ 103 */
120 Times1(1, 0), 105 Times1(1, 0),
121 Times2(2, 1), 106 Times2(2, 1),
122 Times4(4, 2), 107 Times4(4, 2),
123 Times8(8, 3); 108 Times8(8, 3);
124 109
125 Scale(int value, int log2) { 110 private Scale(int value, int log2) {
126 this.value = value; 111 this.value = value;
127 this.log2 = log2; 112 this.log2 = log2;
128 } 113 }
129 114
130 /** 115 /**
136 * The {@linkplain #value value} of this scale log 2. 121 * The {@linkplain #value value} of this scale log 2.
137 */ 122 */
138 public final int log2; 123 public final int log2;
139 124
140 public static Scale fromInt(int scale) { 125 public static Scale fromInt(int scale) {
141 // Checkstyle: stop
142 switch (scale) { 126 switch (scale) {
143 case 1: return Times1; 127 case 1: return Times1;
144 case 2: return Times2; 128 case 2: return Times2;
145 case 4: return Times4; 129 case 4: return Times4;
146 case 8: return Times8; 130 case 8: return Times8;
147 default: throw new IllegalArgumentException(String.valueOf(scale)); 131 default: throw new IllegalArgumentException(String.valueOf(scale));
148 }
149 // Checkstyle: resume
150 }
151
152 public static Scale fromShift(int shift) {
153 return fromInt(1 << shift);
154 }
155 }
156
157 /**
158 * Encodes the possible addressing modes as a simple value.
159 */
160 public enum Format {
161 BASE,
162 BASE_DISP,
163 BASE_INDEX,
164 BASE_INDEX_DISP,
165 PLACEHOLDER;
166 }
167
168 /**
169 * Returns the {@link Format encoded addressing mode} that this {@code CiAddress} represents.
170 * @return the encoded addressing mode
171 */
172 public Format format() {
173 if (this == Placeholder) {
174 return Format.PLACEHOLDER;
175 }
176 assert isLegal(base);
177 if (isLegal(index)) {
178 if (displacement != 0) {
179 return Format.BASE_INDEX_DISP;
180 } else {
181 return Format.BASE_INDEX;
182 }
183 } else {
184 if (displacement != 0) {
185 return Format.BASE_DISP;
186 } else {
187 return Format.BASE;
188 } 132 }
189 } 133 }
190 } 134 }
191 135
192 private static String signed(int i) {
193 if (i >= 0) {
194 return "+" + i;
195 }
196 return String.valueOf(i);
197 }
198
199 @Override 136 @Override
200 public String toString() { 137 public String toString() {
201 // Checkstyle: stop 138 if (this == Placeholder) {
202 switch (format()) { 139 return "[<placeholder>]";
203 case BASE : return "[" + base + kindSuffix() + "]";
204 case BASE_DISP : return "[" + base + signed(displacement) + kindSuffix() + "]";
205 case BASE_INDEX : return "[" + base + "+" + index + kindSuffix() + "]";
206 case BASE_INDEX_DISP : return "[" + base + "+(" + index + "*" + scale.value + ")" + signed(displacement) + kindSuffix() + "]";
207 case PLACEHOLDER : return "[<placeholder>]";
208 default : throw new IllegalArgumentException("unknown format: " + format());
209 } 140 }
210 // Checkstyle: resume 141
142 StringBuilder s = new StringBuilder();
143 s.append(kind.javaName).append("[");
144 String sep = "";
145 if (isLegal(base)) {
146 s.append(base);
147 sep = " + ";
148 }
149 if (isLegal(index)) {
150 s.append(sep).append(index).append(" * ").append(scale.value);
151 sep = " + ";
152 }
153 if (displacement < 0) {
154 s.append(" - ").append(-displacement);
155 } else if (displacement > 0) {
156 s.append(sep).append(displacement);
157 }
158 s.append("]");
159 return s.toString();
211 } 160 }
212 161
213 @Override 162 @Override
214 public boolean equals(Object obj) { 163 public boolean equals(Object obj) {
215 if (obj instanceof CiAddress) { 164 if (obj instanceof CiAddress) {
219 return false; 168 return false;
220 } 169 }
221 170
222 @Override 171 @Override
223 public int hashCode() { 172 public int hashCode() {
224 return (base.hashCode() << 4) | kind.ordinal(); 173 return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ (scale.value << 8) ^ (kind.ordinal() << 12);
225 } 174 }
226 } 175 }