# HG changeset patch # User Erik Eckstein # Date 1387523208 -3600 # Node ID 51d31106cd5e2d012db69eaaa1d8db9d483f2537 # Parent e2a14719e83335baa0713276ac46525e770bb577 fix wrong register definition in AMD64 TableSwitchOp diff -r e2a14719e833 -r 51d31106cd5e graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Dec 19 11:42:16 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Dec 20 08:06:48 2013 +0100 @@ -988,10 +988,7 @@ @Override protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { - // Making a copy of the switch value is necessary because jump table destroys the input - // value - Variable tmp = emitMove(key); - append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind))); + append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(target().wordKind), newVariable(key.getPlatformKind()))); } @Override diff -r e2a14719e833 -r 51d31106cd5e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Thu Dec 19 11:42:16 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Dec 20 08:06:48 2013 +0100 @@ -161,31 +161,38 @@ private final int lowKey; private final LabelRef defaultTarget; private final LabelRef[] targets; - @Alive protected Value index; + @Use protected Value index; + @Temp({REG, HINT}) protected Value idxScratch; @Temp protected Value scratch; - public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) { + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Value index, Variable scratch, Variable idxScratch) { this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; this.index = index; this.scratch = scratch; + this.idxScratch = idxScratch; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - Register value = asIntReg(index); + Register indexReg = asIntReg(index); + Register idxScratchReg = asIntReg(idxScratch); Register scratchReg = asLongReg(scratch); + if (!indexReg.equals(idxScratchReg)) { + masm.movl(idxScratchReg, indexReg); + } + Buffer buf = masm.codeBuffer; // Compare index against jump table bounds int highKey = lowKey + targets.length - 1; if (lowKey != 0) { // subtract the low value from the switch value - masm.subl(value, lowKey); - masm.cmpl(value, highKey - lowKey); + masm.subl(idxScratchReg, lowKey); + masm.cmpl(idxScratchReg, highKey - lowKey); } else { - masm.cmpl(value, highKey); + masm.cmpl(idxScratchReg, highKey); } // Jump to default target if index is not within the jump table @@ -199,8 +206,8 @@ int afterLea = buf.position(); // Load jump table entry into scratch and jump to it - masm.movslq(value, new AMD64Address(scratchReg, value, Scale.Times4, 0)); - masm.addq(scratchReg, value); + masm.movslq(idxScratchReg, new AMD64Address(scratchReg, idxScratchReg, Scale.Times4, 0)); + masm.addq(scratchReg, idxScratchReg); masm.jmp(scratchReg); // Inserting padding so that jump table address is 4-byte aligned