# HG changeset patch # User Roland Schatz # Date 1362665779 -3600 # Node ID d2733c9b3d0e591818d6b16edb1ebe485c50e2e4 # Parent a85ef330ffe7b20aa671932f6f0006364bc5eca6 Convert AMD64Address to CompositeValue. diff -r a85ef330ffe7 -r d2733c9b3d0e graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java --- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Thu Mar 07 15:16:19 2013 +0100 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Thu Mar 07 15:16:19 2013 +0100 @@ -29,7 +29,7 @@ import java.nio.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.Register.*; +import com.oracle.graal.api.code.Register.RegisterFlag; /** * Represents the AMD64 architecture. diff -r a85ef330ffe7 -r d2733c9b3d0e 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 Mar 07 15:16:19 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Mar 07 15:16:19 2013 +0100 @@ -30,6 +30,7 @@ import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.*; import com.oracle.graal.amd64.*; +import com.oracle.graal.amd64.AMD64Address.Scale; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; @@ -158,56 +159,64 @@ append(createMove(dst, src)); } - private AMD64Address prepareAddress(Kind kind, Value base, int displacement, Value index, int scale) { - Value baseRegister = base; + private AMD64AddressValue prepareAddress(Kind kind, Value base, int displacement, Value index, int scale) { + AllocatableValue baseRegister; int finalDisp = displacement; if (isConstant(base)) { if (asConstant(base).isNull()) { - baseRegister = Value.ILLEGAL; + baseRegister = AllocatableValue.UNUSED; } else if (asConstant(base).getKind() != Kind.Object) { long newDisplacement = displacement + asConstant(base).asLong(); if (NumUtil.isInt(newDisplacement)) { assert !runtime.needsDataPatch(asConstant(base)); finalDisp = (int) newDisplacement; - baseRegister = Value.ILLEGAL; + baseRegister = AllocatableValue.UNUSED; } else { - Value newBase = newVariable(Kind.Long); + Variable newBase = newVariable(Kind.Long); emitMove(newBase, base); baseRegister = newBase; } + } else { + baseRegister = load(base); } + } else if (base == Value.ILLEGAL) { + baseRegister = AllocatableValue.UNUSED; + } else { + baseRegister = asAllocatable(base); } - Value indexRegister = index; - AMD64Address.Scale scaleEnum; - if (index != Value.ILLEGAL && scale > 0) { - scaleEnum = AMD64Address.Scale.fromInt(scale); + AllocatableValue indexRegister; + Scale scaleEnum; + if (index != Value.ILLEGAL && scale != 0) { + scaleEnum = Scale.fromInt(scale); if (isConstant(index)) { long newDisplacement = finalDisp + asConstant(index).asLong() * scale; // only use the constant index if the resulting displacement fits into a 32 bit // offset if (NumUtil.isInt(newDisplacement)) { finalDisp = (int) newDisplacement; - indexRegister = Value.ILLEGAL; + indexRegister = AllocatableValue.UNUSED; } else { // create a temporary variable for the index, the pointer load cannot handle a // constant index - Value newIndex = newVariable(Kind.Long); + Variable newIndex = newVariable(Kind.Long); emitMove(newIndex, index); indexRegister = newIndex; } + } else { + indexRegister = asAllocatable(index); } } else { - indexRegister = Value.ILLEGAL; - scaleEnum = AMD64Address.Scale.Times1; + indexRegister = AllocatableValue.UNUSED; + scaleEnum = Scale.Times1; } - return new AMD64Address(kind, baseRegister, indexRegister, scaleEnum, finalDisp); + return new AMD64AddressValue(kind, baseRegister, indexRegister, scaleEnum, finalDisp); } @Override public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap) { - AMD64Address loadAddress = prepareAddress(kind, base, displacement, index, scale); + AMD64AddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); Variable result = newVariable(loadAddress.getKind()); append(new LoadOp(result, loadAddress, canTrap ? state() : null)); return result; @@ -215,7 +224,7 @@ @Override public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) { - AMD64Address storeAddress = prepareAddress(kind, base, displacement, index, scale); + AMD64AddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); LIRFrameState state = canTrap ? state() : null; if (isConstant(inputVal)) { @@ -233,7 +242,7 @@ @Override public Variable emitLea(Value base, int displacement, Value index, int scale) { Variable result = newVariable(target().wordKind); - AMD64Address address = prepareAddress(result.getKind(), base, displacement, index, scale); + AMD64AddressValue address = prepareAddress(result.getKind(), base, displacement, index, scale); append(new LeaOp(result, address)); return result; } @@ -922,15 +931,15 @@ Value expected = loadNonConst(operand(node.expected())); Variable newValue = load(operand(node.newValue())); - AMD64Address address; + AMD64AddressValue address; int displacement = node.displacement(); Value index = operand(node.offset()); if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) { assert !runtime.needsDataPatch(asConstant(index)); displacement += (int) asConstant(index).asLong(); - address = new AMD64Address(kind, load(operand(node.object())), displacement); + address = new AMD64AddressValue(kind, load(operand(node.object())), displacement); } else { - address = new AMD64Address(kind, load(operand(node.object())), load(index), AMD64Address.Scale.Times1, displacement); + address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement); } RegisterValue rax = AMD64.rax.asValue(kind); diff -r a85ef330ffe7 -r d2733c9b3d0e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Mar 07 15:16:19 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Mar 07 15:16:19 2013 +0100 @@ -31,8 +31,9 @@ import sun.misc.*; import com.oracle.graal.amd64.*; +import com.oracle.graal.amd64.AMD64Address.Scale; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.*; +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; @@ -128,14 +129,14 @@ Variable newVal = load(operand(x.newValue())); int disp = 0; - AMD64Address address; + AMD64AddressValue address; Value index = operand(x.offset()); if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { assert !runtime.needsDataPatch(asConstant(index)); disp += (int) ValueUtil.asConstant(index).asLong(); - address = new AMD64Address(kind, load(operand(x.object())), disp); + address = new AMD64AddressValue(kind, load(operand(x.object())), disp); } else { - address = new AMD64Address(kind, load(operand(x.object())), load(index), AMD64Address.Scale.Times1, disp); + address = new AMD64AddressValue(kind, load(operand(x.object())), load(index), Scale.Times1, disp); } RegisterValue rax = AMD64.rax.asValue(kind); diff -r a85ef330ffe7 -r d2733c9b3d0e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Thu Mar 07 15:16:19 2013 +0100 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.amd64.AMD64Address.Scale; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.*; + +public class AMD64AddressValue extends CompositeValue { + + private static final long serialVersionUID = -4444600052487578694L; + + @Component({REG, UNUSED}) protected AllocatableValue base; + @Component({REG, UNUSED}) protected AllocatableValue index; + protected final Scale scale; + protected final int displacement; + + public AMD64AddressValue(Kind kind, AllocatableValue base, int displacement) { + this(kind, base, AllocatableValue.UNUSED, Scale.Times1, displacement); + } + + public AMD64AddressValue(Kind kind, AllocatableValue base, AllocatableValue index, Scale scale, int displacement) { + super(kind); + this.base = base; + this.index = index; + this.scale = scale; + this.displacement = displacement; + } + + public AMD64Address toAddress() { + Value baseVal = base == AllocatableValue.UNUSED ? Value.ILLEGAL : base; + Value indexVal = index == AllocatableValue.UNUSED ? Value.ILLEGAL : index; + return new AMD64Address(getKind(), baseVal, indexVal, scale, displacement); + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(getKind().getJavaName()).append("["); + String sep = ""; + if (isLegal(base)) { + s.append(base); + sep = " + "; + } + if (isLegal(index)) { + s.append(sep).append(index).append(" * ").append(scale.value); + sep = " + "; + } + if (displacement < 0) { + s.append(" - ").append(-displacement); + } else if (displacement > 0) { + s.append(sep).append(displacement); + } + s.append("]"); + return s.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AMD64AddressValue) { + AMD64AddressValue addr = (AMD64AddressValue) obj; + return getKind() == addr.getKind() && displacement == addr.displacement && base.equals(addr.base) && scale == addr.scale && index.equals(addr.index); + } + return false; + } + + @Override + public int hashCode() { + return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ (scale.value << 8) ^ (getKind().ordinal() << 12); + } +} diff -r a85ef330ffe7 -r d2733c9b3d0e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Mar 07 15:16:19 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Mar 07 15:16:19 2013 +0100 @@ -97,10 +97,10 @@ public abstract static class MemOp extends AMD64LIRInstruction { - @Use({ADDR}) protected AMD64Address address; + @Use({COMPOSITE}) protected AMD64AddressValue address; @State protected LIRFrameState state; - public MemOp(AMD64Address address, LIRFrameState state) { + public MemOp(AMD64AddressValue address, LIRFrameState state) { this.address = address; this.state = state; } @@ -120,7 +120,7 @@ @Def({REG}) protected AllocatableValue result; - public LoadOp(AllocatableValue result, AMD64Address address, LIRFrameState state) { + public LoadOp(AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { super(address, state); this.result = result; } @@ -130,28 +130,28 @@ switch (address.getKind()) { case Boolean: case Byte: - masm.movsxb(asRegister(result), address); + masm.movsxb(asRegister(result), address.toAddress()); break; case Char: - masm.movzxl(asRegister(result), address); + masm.movzxl(asRegister(result), address.toAddress()); break; case Short: - masm.movswl(asRegister(result), address); + masm.movswl(asRegister(result), address.toAddress()); break; case Int: - masm.movslq(asRegister(result), address); + masm.movslq(asRegister(result), address.toAddress()); break; case Long: - masm.movq(asRegister(result), address); + masm.movq(asRegister(result), address.toAddress()); break; case Float: - masm.movflt(asFloatReg(result), address); + masm.movflt(asFloatReg(result), address.toAddress()); break; case Double: - masm.movdbl(asDoubleReg(result), address); + masm.movdbl(asDoubleReg(result), address.toAddress()); break; case Object: - masm.movq(asRegister(result), address); + masm.movq(asRegister(result), address.toAddress()); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -163,7 +163,7 @@ @Use({REG}) protected AllocatableValue input; - public StoreOp(AMD64Address address, AllocatableValue input, LIRFrameState state) { + public StoreOp(AMD64AddressValue address, AllocatableValue input, LIRFrameState state) { super(address, state); this.input = input; } @@ -174,26 +174,26 @@ switch (address.getKind()) { case Boolean: case Byte: - masm.movb(address, asRegister(input)); + masm.movb(address.toAddress(), asRegister(input)); break; case Char: case Short: - masm.movw(address, asRegister(input)); + masm.movw(address.toAddress(), asRegister(input)); break; case Int: - masm.movl(address, asRegister(input)); + masm.movl(address.toAddress(), asRegister(input)); break; case Long: - masm.movq(address, asRegister(input)); + masm.movq(address.toAddress(), asRegister(input)); break; case Float: - masm.movflt(address, asFloatReg(input)); + masm.movflt(address.toAddress(), asFloatReg(input)); break; case Double: - masm.movsd(address, asDoubleReg(input)); + masm.movsd(address.toAddress(), asDoubleReg(input)); break; case Object: - masm.movq(address, asRegister(input)); + masm.movq(address.toAddress(), asRegister(input)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -205,7 +205,7 @@ protected final Constant input; - public StoreConstantOp(AMD64Address address, Constant input, LIRFrameState state) { + public StoreConstantOp(AMD64AddressValue address, Constant input, LIRFrameState state) { super(address, state); this.input = input; } @@ -215,30 +215,30 @@ switch (address.getKind()) { case Boolean: case Byte: - masm.movb(address, input.asInt() & 0xFF); + masm.movb(address.toAddress(), input.asInt() & 0xFF); break; case Char: case Short: - masm.movw(address, input.asInt() & 0xFFFF); + masm.movw(address.toAddress(), input.asInt() & 0xFFFF); break; case Int: - masm.movl(address, input.asInt()); + masm.movl(address.toAddress(), input.asInt()); break; case Long: if (NumUtil.isInt(input.asLong())) { - masm.movslq(address, (int) input.asLong()); + masm.movslq(address.toAddress(), (int) input.asLong()); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } break; case Float: - masm.movl(address, floatToRawIntBits(input.asFloat())); + masm.movl(address.toAddress(), floatToRawIntBits(input.asFloat())); break; case Double: throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); case Object: if (input.isNull()) { - masm.movptr(address, 0); + masm.movptr(address.toAddress(), 0); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } @@ -252,16 +252,16 @@ public static class LeaOp extends AMD64LIRInstruction { @Def({REG}) protected AllocatableValue result; - @Use({ADDR, UNINITIALIZED}) protected AMD64Address address; + @Use({COMPOSITE, UNINITIALIZED}) protected AMD64AddressValue address; - public LeaOp(AllocatableValue result, AMD64Address address) { + public LeaOp(AllocatableValue result, AMD64AddressValue address) { this.result = result; this.address = address; } @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - masm.leaq(asLongReg(result), address); + masm.leaq(asLongReg(result), address.toAddress()); } } @@ -316,11 +316,11 @@ public static class CompareAndSwapOp extends AMD64LIRInstruction { @Def protected AllocatableValue result; - @Use({ADDR}) protected AMD64Address address; + @Use({COMPOSITE}) protected AMD64AddressValue address; @Use protected AllocatableValue cmpValue; @Use protected AllocatableValue newValue; - public CompareAndSwapOp(AllocatableValue result, AMD64Address address, AllocatableValue cmpValue, AllocatableValue newValue) { + public CompareAndSwapOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { this.result = result; this.address = address; this.cmpValue = cmpValue; @@ -523,7 +523,7 @@ } } - protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64Address address, AllocatableValue cmpValue, AllocatableValue newValue) { + protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax; if (tasm.target.isMP) { @@ -531,11 +531,11 @@ } switch (cmpValue.getKind()) { case Int: - masm.cmpxchgl(asRegister(newValue), address); + masm.cmpxchgl(asRegister(newValue), address.toAddress()); break; case Long: case Object: - masm.cmpxchgq(asRegister(newValue), address); + masm.cmpxchgq(asRegister(newValue), address.toAddress()); break; default: throw GraalInternalError.shouldNotReachHere();