1 /* 2 * Copyright (c) 2013, 2015, 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 org.graalvm.compiler.lir.aarch64; 24 25 import java.util.EnumSet; 26 27 import org.graalvm.compiler.asm.aarch64.AArch64Address; 28 import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode; 29 import org.graalvm.compiler.asm.aarch64.AArch64Assembler; 30 import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ExtendType; 31 import org.graalvm.compiler.lir.CompositeValue; 32 import org.graalvm.compiler.lir.InstructionValueConsumer; 33 import org.graalvm.compiler.lir.InstructionValueProcedure; 34 import org.graalvm.compiler.lir.LIRInstruction; 35 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag; 36 37 import jdk.vm.ci.aarch64.AArch64; 38 import jdk.vm.ci.code.Register; 39 import jdk.vm.ci.code.RegisterValue; 40 import jdk.vm.ci.meta.AllocatableValue; 41 import jdk.vm.ci.meta.Value; 42 import jdk.vm.ci.meta.ValueKind; 43 44 public final class AArch64AddressValue extends CompositeValue { 45 private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL); 46 47 @Component({OperandFlag.REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; 48 @Component({OperandFlag.REG, OperandFlag.ILLEGAL}) protected AllocatableValue offset; 49 private final int immediate; 50 51 /** 52 * Whether register offset should be scaled or not. 53 */ 54 private final boolean scaled; 55 private final AddressingMode addressingMode; 56 57 public AArch64AddressValue(ValueKind<?> kind, AllocatableValue base, AllocatableValue offset, int immediate, boolean scaled, AddressingMode addressingMode) { 58 super(kind); 59 this.base = base; 60 this.offset = offset; 61 this.immediate = immediate; 62 this.scaled = scaled; 63 this.addressingMode = addressingMode; 64 } 65 66 private static Register toRegister(AllocatableValue value) { 67 if (value.equals(Value.ILLEGAL)) { 68 return AArch64.zr; 69 } else { 70 return ((RegisterValue) value).getRegister(); 71 } 72 } 73 74 public AllocatableValue getBase() { 75 return base; 76 } 77 78 public AllocatableValue getOffset() { 79 return offset; 80 } 81 82 public int getImmediate() { 83 return immediate; 84 } 85 86 public boolean isScaled() { 87 return scaled; 88 } 89 90 public AddressingMode getAddressingMode() { 91 return addressingMode; 92 } 93 94 public AArch64Address toAddress() { 95 Register baseReg = toRegister(base); 96 Register offsetReg = toRegister(offset); 97 AArch64Assembler.ExtendType extendType = addressingMode == AddressingMode.EXTENDED_REGISTER_OFFSET ? ExtendType.SXTW : null; 98 return AArch64Address.createAddress(addressingMode, baseReg, offsetReg, immediate, scaled, extendType); 99 } 100 101 @Override 102 public CompositeValue forEachComponent(LIRInstruction inst, LIRInstruction.OperandMode mode, InstructionValueProcedure proc) { 103 AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags); 104 AllocatableValue newOffset = (AllocatableValue) proc.doValue(inst, offset, mode, flags); 105 if (!base.identityEquals(newBase) || !offset.identityEquals(newOffset)) { 106 return new AArch64AddressValue(getValueKind(), newBase, newOffset, immediate, scaled, addressingMode); 107 } 108 return this; 109 } 110 111 @Override 112 protected void visitEachComponent(LIRInstruction inst, LIRInstruction.OperandMode mode, InstructionValueConsumer proc) { 113 proc.visitValue(inst, base, mode, flags); 114 proc.visitValue(inst, offset, mode, flags); 115 } 116 }