53 */
54 public class StandardOp {
55
56 /**
57 * A block delimiter. Every well formed block must contain exactly one such operation and it
58 * must be the last operation in the block.
59 */
60 public interface BlockEndOp {
61 }
62
63 public interface NullCheck {
64 Value getCheckedValue();
65
66 LIRFrameState getState();
67 }
68
69 public interface ImplicitNullCheck {
70 boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit);
71 }
72
73 /**
74 * LIR operation that defines the position of a label.
75 */
76 public static final class LabelOp extends LIRInstruction {
77 public static final LIRInstructionClass<LabelOp> TYPE = LIRInstructionClass.create(LabelOp.class);
78 public static final EnumSet<OperandFlag> incomingFlags = EnumSet.of(REG, STACK);
79
80 /**
81 * In the LIR, every register and variable must be defined before it is used. For method
82 * parameters that are passed in fixed registers, exception objects passed to the exception
83 * handler in a fixed register, or any other use of a fixed register not defined in this
84 * method, an artificial definition is necessary. To avoid spill moves to be inserted
85 * between the label at the beginning of a block an an actual definition in the second
86 * instruction of a block, the registers are defined here in the label.
87 */
88 @Def({REG, STACK}) private Value[] incomingValues;
89 private final Label label;
90 private final boolean align;
91 private int numbPhis;
92
93 public LabelOp(Label label, boolean align) {
94 super(TYPE);
95 this.label = label;
96 this.align = align;
138 }
139 int t = incomingValues.length + values.length;
140 Value[] newArray = new Value[t];
141 System.arraycopy(incomingValues, 0, newArray, 0, incomingValues.length);
142 System.arraycopy(values, 0, newArray, incomingValues.length, values.length);
143 incomingValues = newArray;
144 }
145
146 private boolean checkRange(int idx) {
147 return idx < incomingValues.length;
148 }
149
150 @Override
151 public void emitCode(CompilationResultBuilder crb) {
152 if (align) {
153 crb.asm.align(crb.target.wordSize * 2);
154 }
155 crb.asm.bind(label);
156 }
157
158 public Label getLabel() {
159 return label;
160 }
161
162 /**
163 * @return true if this label acts as a PhiIn.
164 */
165 public boolean isPhiIn() {
166 return getPhiSize() > 0;
167 }
168
169 public void forEachIncomingValue(InstructionValueProcedure proc) {
170 for (int i = 0; i < incomingValues.length; i++) {
171 incomingValues[i] = proc.doValue(this, incomingValues[i], OperandMode.DEF, incomingFlags);
172 }
173 }
174 }
175
176 /**
177 * LIR operation that is an unconditional jump to a {@link #destination()}.
|
53 */
54 public class StandardOp {
55
56 /**
57 * A block delimiter. Every well formed block must contain exactly one such operation and it
58 * must be the last operation in the block.
59 */
60 public interface BlockEndOp {
61 }
62
63 public interface NullCheck {
64 Value getCheckedValue();
65
66 LIRFrameState getState();
67 }
68
69 public interface ImplicitNullCheck {
70 boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit);
71 }
72
73 public interface LabelHoldingOp {
74 Label getLabel();
75 }
76
77 /**
78 * LIR operation that defines the position of a label.
79 */
80 public static final class LabelOp extends LIRInstruction implements LabelHoldingOp {
81 public static final LIRInstructionClass<LabelOp> TYPE = LIRInstructionClass.create(LabelOp.class);
82 public static final EnumSet<OperandFlag> incomingFlags = EnumSet.of(REG, STACK);
83
84 /**
85 * In the LIR, every register and variable must be defined before it is used. For method
86 * parameters that are passed in fixed registers, exception objects passed to the exception
87 * handler in a fixed register, or any other use of a fixed register not defined in this
88 * method, an artificial definition is necessary. To avoid spill moves to be inserted
89 * between the label at the beginning of a block an an actual definition in the second
90 * instruction of a block, the registers are defined here in the label.
91 */
92 @Def({REG, STACK}) private Value[] incomingValues;
93 private final Label label;
94 private final boolean align;
95 private int numbPhis;
96
97 public LabelOp(Label label, boolean align) {
98 super(TYPE);
99 this.label = label;
100 this.align = align;
142 }
143 int t = incomingValues.length + values.length;
144 Value[] newArray = new Value[t];
145 System.arraycopy(incomingValues, 0, newArray, 0, incomingValues.length);
146 System.arraycopy(values, 0, newArray, incomingValues.length, values.length);
147 incomingValues = newArray;
148 }
149
150 private boolean checkRange(int idx) {
151 return idx < incomingValues.length;
152 }
153
154 @Override
155 public void emitCode(CompilationResultBuilder crb) {
156 if (align) {
157 crb.asm.align(crb.target.wordSize * 2);
158 }
159 crb.asm.bind(label);
160 }
161
162 @Override
163 public Label getLabel() {
164 return label;
165 }
166
167 /**
168 * @return true if this label acts as a PhiIn.
169 */
170 public boolean isPhiIn() {
171 return getPhiSize() > 0;
172 }
173
174 public void forEachIncomingValue(InstructionValueProcedure proc) {
175 for (int i = 0; i < incomingValues.length; i++) {
176 incomingValues[i] = proc.doValue(this, incomingValues[i], OperandMode.DEF, incomingFlags);
177 }
178 }
179 }
180
181 /**
182 * LIR operation that is an unconditional jump to a {@link #destination()}.
|