Mercurial > hg > graal-jvmci-8
comparison graal/Compiler/src/com/sun/c1x/lir/LIRList.java @ 2507:9ec15d6914ca
Pull over of compiler from maxine repository.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 11:43:22 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2506:4a3bf8a5bf41 | 2507:9ec15d6914ca |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.sun.c1x.lir; | |
24 | |
25 import java.util.*; | |
26 | |
27 import com.sun.c1x.*; | |
28 import com.sun.c1x.alloc.*; | |
29 import com.sun.c1x.asm.*; | |
30 import com.sun.c1x.debug.*; | |
31 import com.sun.c1x.gen.*; | |
32 import com.sun.c1x.globalstub.*; | |
33 import com.sun.c1x.ir.*; | |
34 import com.sun.c1x.lir.FrameMap.StackBlock; | |
35 import com.sun.cri.ci.*; | |
36 import com.sun.cri.ci.CiTargetMethod.Mark; | |
37 import com.sun.cri.ri.*; | |
38 import com.sun.cri.xir.CiXirAssembler.XirMark; | |
39 import com.sun.cri.xir.*; | |
40 | |
41 /** | |
42 * This class represents a list of LIR instructions and contains factory methods for creating and appending LIR | |
43 * instructions to this list. | |
44 * | |
45 * @author Marcelo Cintra | |
46 * @author Thomas Wuerthinger | |
47 * @author Ben L. Titzer | |
48 */ | |
49 public final class LIRList { | |
50 | |
51 private List<LIRInstruction> operations; | |
52 private final LIRGenerator generator; | |
53 | |
54 private final LIROpcode runtimeCallOp; | |
55 | |
56 private LIROpcode directCallOp(RiMethod method) { | |
57 return C1XOptions.UseConstDirectCall && method.hasCompiledCode() ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall; | |
58 } | |
59 | |
60 public LIRList(LIRGenerator generator) { | |
61 this.generator = generator; | |
62 this.operations = new ArrayList<LIRInstruction>(8); | |
63 runtimeCallOp = C1XOptions.UseConstDirectCall ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall; | |
64 } | |
65 | |
66 private void append(LIRInstruction op) { | |
67 if (C1XOptions.PrintIRWithLIR && !TTY.isSuppressed()) { | |
68 generator.maybePrintCurrentInstruction(); | |
69 TTY.println(op.toStringWithIdPrefix()); | |
70 TTY.println(); | |
71 } | |
72 operations.add(op); | |
73 assert op.verify(); | |
74 } | |
75 | |
76 public List<LIRInstruction> instructionsList() { | |
77 return operations; | |
78 } | |
79 | |
80 public int length() { | |
81 return operations.size(); | |
82 } | |
83 | |
84 public LIRInstruction at(int i) { | |
85 return operations.get(i); | |
86 } | |
87 | |
88 public void callDirect(RiMethod method, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks, List<CiValue> pointerSlots) { | |
89 append(new LIRCall(directCallOp(method), method, result, arguments, info, marks, false, pointerSlots)); | |
90 } | |
91 | |
92 public void callIndirect(RiMethod method, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks, List<CiValue> pointerSlots) { | |
93 append(new LIRCall(LIROpcode.IndirectCall, method, result, arguments, info, marks, false, pointerSlots)); | |
94 } | |
95 | |
96 public void callNative(String symbol, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks) { | |
97 append(new LIRCall(LIROpcode.NativeCall, symbol, result, arguments, info, marks, false, null)); | |
98 } | |
99 | |
100 public void templateCall(CiValue result, List<CiValue> arguments) { | |
101 append(new LIRCall(LIROpcode.TemplateCall, null, result, arguments, null, null, false, null)); | |
102 } | |
103 | |
104 public void membar(int barriers) { | |
105 append(new LIRMemoryBarrier(barriers)); | |
106 } | |
107 | |
108 public void osrEntry(CiValue osrPointer) { | |
109 append(new LIROp0(LIROpcode.OsrEntry, osrPointer)); | |
110 } | |
111 | |
112 public void branchDestination(Label lbl) { | |
113 append(new LIRLabel(lbl)); | |
114 } | |
115 | |
116 public void negate(CiValue src, CiValue dst, GlobalStub globalStub) { | |
117 LIRNegate op = new LIRNegate(src, dst); | |
118 op.globalStub = globalStub; | |
119 append(op); | |
120 } | |
121 | |
122 public void lea(CiValue src, CiValue dst) { | |
123 append(new LIROp1(LIROpcode.Lea, src, dst)); | |
124 } | |
125 | |
126 public void unalignedMove(CiValue src, CiValue dst) { | |
127 append(new LIROp1(LIROp1.LIRMoveKind.Unaligned, src, dst, dst.kind, null)); | |
128 } | |
129 | |
130 public void move(CiAddress src, CiValue dst, LIRDebugInfo info) { | |
131 append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info)); | |
132 } | |
133 | |
134 public void move(CiValue src, CiAddress dst, LIRDebugInfo info) { | |
135 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info)); | |
136 } | |
137 | |
138 public void move(CiValue src, CiValue dst, CiKind kind) { | |
139 append(new LIROp1(LIROpcode.Move, src, dst, kind, null)); | |
140 } | |
141 | |
142 public void move(CiValue src, CiValue dst) { | |
143 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, null)); | |
144 } | |
145 | |
146 public void volatileMove(CiValue src, CiValue dst, CiKind kind, LIRDebugInfo info) { | |
147 append(new LIROp1(LIROp1.LIRMoveKind.Volatile, src, dst, kind, info)); | |
148 } | |
149 | |
150 public void oop2reg(Object o, CiValue reg) { | |
151 append(new LIROp1(LIROpcode.Move, CiConstant.forObject(o), reg)); | |
152 } | |
153 | |
154 public void returnOp(CiValue result) { | |
155 append(new LIROp1(LIROpcode.Return, result)); | |
156 } | |
157 | |
158 public void monitorAddress(int monitor, CiValue dst) { | |
159 append(new LIRMonitorAddress(dst, monitor)); | |
160 } | |
161 | |
162 public void infopoint(LIROpcode opcode, CiValue dst, LIRDebugInfo info) { | |
163 append(new LIROp0(opcode, dst, info)); | |
164 } | |
165 | |
166 public void alloca(StackBlock stackBlock, CiValue dst) { | |
167 append(new LIRStackAllocate(dst, stackBlock)); | |
168 } | |
169 | |
170 public void convert(int code, CiValue left, CiValue dst, GlobalStub globalStub) { | |
171 LIRConvert op = new LIRConvert(code, left, dst); | |
172 op.globalStub = globalStub; | |
173 append(op); | |
174 } | |
175 | |
176 public void logicalAnd(CiValue left, CiValue right, CiValue dst) { | |
177 append(new LIROp2(LIROpcode.LogicAnd, left, right, dst)); | |
178 } | |
179 | |
180 public void logicalOr(CiValue left, CiValue right, CiValue dst) { | |
181 append(new LIROp2(LIROpcode.LogicOr, left, right, dst)); | |
182 } | |
183 | |
184 public void logicalXor(CiValue left, CiValue right, CiValue dst) { | |
185 append(new LIROp2(LIROpcode.LogicXor, left, right, dst)); | |
186 } | |
187 | |
188 public void nullCheck(CiValue opr, LIRDebugInfo info) { | |
189 append(new LIROp1(LIROpcode.NullCheck, opr, info)); | |
190 } | |
191 | |
192 public void throwException(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) { | |
193 append(new LIROp2(LIROpcode.Throw, exceptionPC, exceptionOop, CiValue.IllegalValue, info, CiKind.Illegal, true)); | |
194 } | |
195 | |
196 public void unwindException(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) { | |
197 append(new LIROp2(LIROpcode.Unwind, exceptionPC, exceptionOop, CiValue.IllegalValue, info)); | |
198 } | |
199 | |
200 public void compareTo(CiValue left, CiValue right, CiValue dst) { | |
201 append(new LIROp2(LIROpcode.CompareTo, left, right, dst)); | |
202 } | |
203 | |
204 public void cmp(Condition condition, CiValue left, CiValue right, LIRDebugInfo info) { | |
205 append(new LIROp2(LIROpcode.Cmp, condition, left, right, info)); | |
206 } | |
207 | |
208 public void cmp(Condition condition, CiValue left, CiValue right) { | |
209 cmp(condition, left, right, null); | |
210 } | |
211 | |
212 public void cmp(Condition condition, CiValue left, int right, LIRDebugInfo info) { | |
213 cmp(condition, left, CiConstant.forInt(right), info); | |
214 } | |
215 | |
216 public void cmp(Condition condition, CiValue left, int right) { | |
217 cmp(condition, left, right, null); | |
218 } | |
219 | |
220 public void cmove(Condition condition, CiValue src1, CiValue src2, CiValue dst) { | |
221 append(new LIROp2(LIROpcode.Cmove, condition, src1, src2, dst)); | |
222 } | |
223 | |
224 public void abs(CiValue from, CiValue to, CiValue tmp) { | |
225 append(new LIROp2(LIROpcode.Abs, from, tmp, to)); | |
226 } | |
227 | |
228 public void sqrt(CiValue from, CiValue to, CiValue tmp) { | |
229 append(new LIROp2(LIROpcode.Sqrt, from, tmp, to)); | |
230 } | |
231 | |
232 public void log(CiValue from, CiValue to, CiValue tmp) { | |
233 append(new LIROp2(LIROpcode.Log, from, tmp, to)); | |
234 } | |
235 | |
236 public void log10(CiValue from, CiValue to, CiValue tmp) { | |
237 append(new LIROp2(LIROpcode.Log10, from, tmp, to)); | |
238 } | |
239 | |
240 public void sin(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { | |
241 append(new LIROp2(LIROpcode.Sin, from, tmp1, to, tmp2)); | |
242 } | |
243 | |
244 public void cos(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { | |
245 append(new LIROp2(LIROpcode.Cos, from, tmp1, to, tmp2)); | |
246 } | |
247 | |
248 public void tan(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { | |
249 append(new LIROp2(LIROpcode.Tan, from, tmp1, to, tmp2)); | |
250 } | |
251 | |
252 public void add(CiValue left, CiValue right, CiValue res) { | |
253 append(new LIROp2(LIROpcode.Add, left, right, res)); | |
254 } | |
255 | |
256 public void sub(CiValue left, CiValue right, CiValue res) { | |
257 append(new LIROp2(LIROpcode.Sub, left, right, res)); | |
258 } | |
259 | |
260 public void mul(CiValue left, CiValue right, CiValue res) { | |
261 append(new LIROp2(LIROpcode.Mul, left, right, res)); | |
262 } | |
263 | |
264 public void div(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) { | |
265 append(new LIROp2(LIROpcode.Div, left, right, res, info)); | |
266 } | |
267 | |
268 public void rem(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) { | |
269 append(new LIROp2(LIROpcode.Rem, left, right, res, info)); | |
270 } | |
271 | |
272 public void jump(BlockBegin block) { | |
273 append(new LIRBranch(Condition.TRUE, CiKind.Illegal, block)); | |
274 } | |
275 | |
276 public void branch(Condition cond, Label lbl) { | |
277 append(new LIRBranch(cond, lbl)); | |
278 } | |
279 | |
280 public void branch(Condition cond, Label lbl, LIRDebugInfo info) { | |
281 append(new LIRBranch(cond, lbl, info)); | |
282 } | |
283 | |
284 public void branch(Condition cond, CiKind kind, BlockBegin block) { | |
285 assert kind != CiKind.Float && kind != CiKind.Double : "no fp comparisons"; | |
286 append(new LIRBranch(cond, kind, block)); | |
287 } | |
288 | |
289 public void branch(Condition cond, CiKind kind, BlockBegin block, BlockBegin unordered) { | |
290 assert kind == CiKind.Float || kind == CiKind.Double : "fp comparisons only"; | |
291 append(new LIRBranch(cond, kind, block, unordered)); | |
292 } | |
293 | |
294 public void tableswitch(CiValue index, int lowKey, BlockBegin defaultTargets, BlockBegin[] targets) { | |
295 append(new LIRTableSwitch(index, lowKey, defaultTargets, targets)); | |
296 } | |
297 | |
298 public void shiftLeft(CiValue value, int count, CiValue dst) { | |
299 shiftLeft(value, CiConstant.forInt(count), dst, CiValue.IllegalValue); | |
300 } | |
301 | |
302 public void shiftRight(CiValue value, int count, CiValue dst) { | |
303 shiftRight(value, CiConstant.forInt(count), dst, CiValue.IllegalValue); | |
304 } | |
305 | |
306 public void lcmp2int(CiValue left, CiValue right, CiValue dst) { | |
307 append(new LIROp2(LIROpcode.Cmpl2i, left, right, dst)); | |
308 } | |
309 | |
310 public void callRuntime(CiRuntimeCall rtCall, CiValue result, List<CiValue> arguments, LIRDebugInfo info) { | |
311 append(new LIRCall(runtimeCallOp, rtCall, result, arguments, info, null, false, null)); | |
312 } | |
313 | |
314 public void pause() { | |
315 append(new LIROp0(LIROpcode.Pause)); | |
316 } | |
317 | |
318 public void breakpoint() { | |
319 append(new LIROp0(LIROpcode.Breakpoint)); | |
320 } | |
321 | |
322 public void prefetch(CiAddress addr, boolean isStore) { | |
323 append(new LIROp1(isStore ? LIROpcode.Prefetchw : LIROpcode.Prefetchr, addr)); | |
324 } | |
325 | |
326 public void idiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
327 append(new LIROp3(LIROpcode.Idiv, left, right, tmp, res, info)); | |
328 } | |
329 | |
330 public void irem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
331 append(new LIROp3(LIROpcode.Irem, left, right, tmp, res, info)); | |
332 } | |
333 | |
334 public void ldiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
335 append(new LIROp3(LIROpcode.Ldiv, left, right, tmp, res, info)); | |
336 } | |
337 | |
338 public void lrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
339 append(new LIROp3(LIROpcode.Lrem, left, right, tmp, res, info)); | |
340 } | |
341 | |
342 public void lsb(CiValue src, CiValue dst) { | |
343 append(new LIRSignificantBit(LIROpcode.Lsb, src, dst)); | |
344 } | |
345 | |
346 public void msb(CiValue src, CiValue dst) { | |
347 append(new LIRSignificantBit(LIROpcode.Msb, src, dst)); | |
348 } | |
349 | |
350 public void wdiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
351 append(new LIROp3(LIROpcode.Wdiv, left, right, tmp, res, info)); | |
352 } | |
353 | |
354 public void wrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
355 append(new LIROp3(LIROpcode.Wrem, left, right, tmp, res, info)); | |
356 } | |
357 | |
358 public void wdivi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
359 append(new LIROp3(LIROpcode.Wdivi, left, right, tmp, res, info)); | |
360 } | |
361 | |
362 public void wremi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { | |
363 append(new LIROp3(LIROpcode.Wremi, left, right, tmp, res, info)); | |
364 } | |
365 | |
366 public void cmpMemInt(Condition condition, CiValue base, int disp, int c, LIRDebugInfo info) { | |
367 append(new LIROp2(LIROpcode.Cmp, condition, new CiAddress(CiKind.Int, base, disp), CiConstant.forInt(c), info)); | |
368 } | |
369 | |
370 public void cmpRegMem(Condition condition, CiValue reg, CiAddress addr, LIRDebugInfo info) { | |
371 append(new LIROp2(LIROpcode.Cmp, condition, reg, addr, info)); | |
372 } | |
373 | |
374 public void shiftLeft(CiValue value, CiValue count, CiValue dst, CiValue tmp) { | |
375 append(new LIROp2(LIROpcode.Shl, value, count, dst, tmp)); | |
376 } | |
377 | |
378 public void shiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) { | |
379 append(new LIROp2(LIROpcode.Shr, value, count, dst, tmp)); | |
380 } | |
381 | |
382 public void unsignedShiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) { | |
383 append(new LIROp2(LIROpcode.Ushr, value, count, dst, tmp)); | |
384 } | |
385 | |
386 public void fcmp2int(CiValue left, CiValue right, CiValue dst, boolean isUnorderedLess) { | |
387 append(new LIROp2(isUnorderedLess ? LIROpcode.Ucmpfd2i : LIROpcode.Cmpfd2i, left, right, dst)); | |
388 } | |
389 | |
390 public void casLong(CiValue addr, CiValue cmpValue, CiValue newValue) { | |
391 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, | |
392 // implying successful swap of newValue into addr | |
393 append(new LIRCompareAndSwap(LIROpcode.CasLong, addr, cmpValue, newValue)); | |
394 } | |
395 | |
396 public void casObj(CiValue addr, CiValue cmpValue, CiValue newValue) { | |
397 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, | |
398 // implying successful swap of newValue into addr | |
399 append(new LIRCompareAndSwap(LIROpcode.CasObj, addr, cmpValue, newValue)); | |
400 } | |
401 | |
402 public void casInt(CiValue addr, CiValue cmpValue, CiValue newValue) { | |
403 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, | |
404 // implying successful swap of newValue into addr | |
405 append(new LIRCompareAndSwap(LIROpcode.CasInt, addr, cmpValue, newValue)); | |
406 } | |
407 | |
408 public void store(CiValue src, CiAddress dst, LIRDebugInfo info) { | |
409 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info)); | |
410 } | |
411 | |
412 public void load(CiAddress src, CiValue dst, LIRDebugInfo info) { | |
413 append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info)); | |
414 } | |
415 | |
416 public static void printBlock(BlockBegin x) { | |
417 // print block id | |
418 BlockEnd end = x.end(); | |
419 TTY.print("B%d ", x.blockID); | |
420 | |
421 // print flags | |
422 if (x.checkBlockFlag(BlockBegin.BlockFlag.StandardEntry)) { | |
423 TTY.print("std "); | |
424 } | |
425 if (x.checkBlockFlag(BlockBegin.BlockFlag.OsrEntry)) { | |
426 TTY.print("osr "); | |
427 } | |
428 if (x.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) { | |
429 TTY.print("ex "); | |
430 } | |
431 if (x.checkBlockFlag(BlockBegin.BlockFlag.SubroutineEntry)) { | |
432 TTY.print("jsr "); | |
433 } | |
434 if (x.checkBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget)) { | |
435 TTY.print("bb "); | |
436 } | |
437 if (x.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { | |
438 TTY.print("lh "); | |
439 } | |
440 if (x.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) { | |
441 TTY.print("le "); | |
442 } | |
443 | |
444 // print block bci range | |
445 TTY.print("[%d, %d] ", x.bci(), (end == null ? -1 : end.bci())); | |
446 | |
447 // print predecessors and successors | |
448 if (x.numberOfPreds() > 0) { | |
449 TTY.print("preds: "); | |
450 for (int i = 0; i < x.numberOfPreds(); i++) { | |
451 TTY.print("B%d ", x.predAt(i).blockID); | |
452 } | |
453 } | |
454 | |
455 if (x.numberOfSux() > 0) { | |
456 TTY.print("sux: "); | |
457 for (int i = 0; i < x.numberOfSux(); i++) { | |
458 TTY.print("B%d ", x.suxAt(i).blockID); | |
459 } | |
460 } | |
461 | |
462 // print exception handlers | |
463 if (x.numberOfExceptionHandlers() > 0) { | |
464 TTY.print("xhandler: "); | |
465 for (int i = 0; i < x.numberOfExceptionHandlers(); i++) { | |
466 TTY.print("B%d ", x.exceptionHandlerAt(i).blockID); | |
467 } | |
468 } | |
469 | |
470 TTY.println(); | |
471 } | |
472 | |
473 public static void printLIR(List<BlockBegin> blocks) { | |
474 if (TTY.isSuppressed()) { | |
475 return; | |
476 } | |
477 TTY.println("LIR:"); | |
478 int i; | |
479 for (i = 0; i < blocks.size(); i++) { | |
480 BlockBegin bb = blocks.get(i); | |
481 printBlock(bb); | |
482 TTY.println("__id_Instruction___________________________________________"); | |
483 bb.lir().printInstructions(); | |
484 } | |
485 } | |
486 | |
487 private void printInstructions() { | |
488 for (int i = 0; i < operations.size(); i++) { | |
489 TTY.println(operations.get(i).toStringWithIdPrefix()); | |
490 TTY.println(); | |
491 } | |
492 TTY.println(); | |
493 } | |
494 | |
495 public void append(LIRInsertionBuffer buffer) { | |
496 assert this == buffer.lirList() : "wrong lir list"; | |
497 int n = operations.size(); | |
498 | |
499 if (buffer.numberOfOps() > 0) { | |
500 // increase size of instructions list | |
501 for (int i = 0; i < buffer.numberOfOps(); i++) { | |
502 operations.add(null); | |
503 } | |
504 // insert ops from buffer into instructions list | |
505 int opIndex = buffer.numberOfOps() - 1; | |
506 int ipIndex = buffer.numberOfInsertionPoints() - 1; | |
507 int fromIndex = n - 1; | |
508 int toIndex = operations.size() - 1; | |
509 for (; ipIndex >= 0; ipIndex--) { | |
510 int index = buffer.indexAt(ipIndex); | |
511 // make room after insertion point | |
512 while (index < fromIndex) { | |
513 operations.set(toIndex--, operations.get(fromIndex--)); | |
514 } | |
515 // insert ops from buffer | |
516 for (int i = buffer.countAt(ipIndex); i > 0; i--) { | |
517 operations.set(toIndex--, buffer.opAt(opIndex--)); | |
518 } | |
519 } | |
520 } | |
521 | |
522 buffer.finish(); | |
523 } | |
524 | |
525 public void insertBefore(int i, LIRInstruction op) { | |
526 operations.add(i, op); | |
527 } | |
528 | |
529 public void xir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, int tempInputCount, int tempCount, CiValue[] inputOperands, int[] operandIndices, int outputOperandIndex, | |
530 LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, List<CiValue> pointerSlots) { | |
531 append(new LIRXirInstruction(snippet, operands, outputOperand, tempInputCount, tempCount, inputOperands, operandIndices, outputOperandIndex, info, infoAfter, method, pointerSlots)); | |
532 } | |
533 } |