1 /* 2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2017, Red Hat Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 26 27 package org.graalvm.compiler.core.aarch64; 28 29 import jdk.vm.ci.aarch64.AArch64Kind; 30 31 import org.graalvm.compiler.core.common.type.IntegerStamp; 32 import org.graalvm.compiler.core.common.type.Stamp; 33 import org.graalvm.compiler.graph.NodeClass; 34 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue; 35 import org.graalvm.compiler.nodeinfo.NodeInfo; 36 import org.graalvm.compiler.nodes.FrameState; 37 import org.graalvm.compiler.nodes.NodeView; 38 import org.graalvm.compiler.nodes.StructuredGraph; 39 import org.graalvm.compiler.nodes.ValueNode; 40 import org.graalvm.compiler.nodes.calc.SignExtendNode; 41 import org.graalvm.compiler.nodes.calc.ZeroExtendNode; 42 import org.graalvm.compiler.nodes.extended.GuardingNode; 43 import org.graalvm.compiler.nodes.memory.ReadNode; 44 import org.graalvm.compiler.nodes.memory.address.AddressNode; 45 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 46 import jdk.internal.vm.compiler.word.LocationIdentity; 47 48 /** 49 * AArch64-specific subclass of ReadNode that knows how to merge ZeroExtend and SignExtend into the 50 * read. 51 */ 52 53 @NodeInfo 54 public class AArch64ReadNode extends ReadNode { 55 public static final NodeClass<AArch64ReadNode> TYPE = NodeClass.create(AArch64ReadNode.class); 56 private final IntegerStamp accessStamp; 57 private final boolean isSigned; 58 59 public AArch64ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, 60 FrameState stateBefore, IntegerStamp accessStamp, boolean isSigned) { 61 super(TYPE, address, location, stamp, guard, barrierType, nullCheck, stateBefore); 62 this.accessStamp = accessStamp; 63 this.isSigned = isSigned; 64 } 65 66 @Override 67 public void generate(NodeLIRBuilderTool gen) { 68 AArch64LIRGenerator lirgen = (AArch64LIRGenerator) gen.getLIRGeneratorTool(); 69 AArch64ArithmeticLIRGenerator arithgen = (AArch64ArithmeticLIRGenerator) lirgen.getArithmetic(); 70 AArch64Kind readKind = (AArch64Kind) lirgen.getLIRKind(accessStamp).getPlatformKind(); 71 int resultBits = ((IntegerStamp) stamp(NodeView.DEFAULT)).getBits(); 72 gen.setResult(this, arithgen.emitExtendMemory(isSigned, readKind, resultBits, (AArch64AddressValue) gen.operand(getAddress()), gen.state(this))); 73 } 74 75 /** 76 * replace a ReadNode with an AArch64-specific variant which knows how to merge a downstream 77 * zero or sign extend into the read operation. 78 * 79 * @param readNode 80 */ 81 public static void replace(ReadNode readNode) { 82 assert readNode.getUsageCount() == 1; 83 assert readNode.usages().first() instanceof ZeroExtendNode || readNode.usages().first() instanceof SignExtendNode; 84 85 ValueNode usage = (ValueNode) readNode.usages().first(); 86 boolean isSigned = usage instanceof SignExtendNode; 87 IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp()); 88 89 AddressNode address = readNode.getAddress(); 90 LocationIdentity location = readNode.getLocationIdentity(); 91 Stamp stamp = usage.stamp(NodeView.DEFAULT); 92 GuardingNode guard = readNode.getGuard(); 93 BarrierType barrierType = readNode.getBarrierType(); 94 boolean nullCheck = readNode.getNullCheck(); 95 FrameState stateBefore = readNode.stateBefore(); 96 AArch64ReadNode clone = new AArch64ReadNode(address, location, stamp, guard, barrierType, nullCheck, stateBefore, accessStamp, isSigned); 97 StructuredGraph graph = readNode.graph(); 98 graph.add(clone); 99 // splice out the extend node 100 usage.replaceAtUsagesAndDelete(readNode); 101 // swap the clone for the read 102 graph.replaceFixedWithFixed(readNode, clone); 103 } 104 }