001/* 002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023 024package com.oracle.graal.hotspot.amd64; 025 026import jdk.internal.jvmci.code.*; 027import jdk.internal.jvmci.hotspot.HotSpotVMConfig.*; 028import jdk.internal.jvmci.meta.*; 029 030import com.oracle.graal.asm.*; 031import com.oracle.graal.asm.amd64.AMD64Address.Scale; 032import com.oracle.graal.compiler.amd64.*; 033import com.oracle.graal.compiler.common.type.*; 034import com.oracle.graal.graph.*; 035import com.oracle.graal.hotspot.nodes.*; 036import com.oracle.graal.hotspot.nodes.CompressionNode.CompressionOp; 037import com.oracle.graal.nodeinfo.*; 038import com.oracle.graal.nodes.*; 039import com.oracle.graal.nodes.calc.*; 040import com.oracle.graal.nodes.spi.*; 041 042public class AMD64HotSpotAddressLowering extends AMD64AddressLowering { 043 044 private final long heapBase; 045 private final Register heapBaseRegister; 046 047 @NodeInfo 048 public static class HeapBaseNode extends FloatingNode implements LIRLowerable { 049 050 public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class); 051 052 private final Register heapBaseRegister; 053 054 public HeapBaseNode(Register heapBaseRegister) { 055 super(TYPE, StampFactory.pointer()); 056 this.heapBaseRegister = heapBaseRegister; 057 } 058 059 public void generate(NodeLIRBuilderTool generator) { 060 LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp()); 061 generator.setResult(this, heapBaseRegister.asValue(kind)); 062 } 063 } 064 065 public AMD64HotSpotAddressLowering(CodeCacheProvider codeCache, long heapBase, Register heapBaseRegister) { 066 super(codeCache); 067 this.heapBase = heapBase; 068 if (heapBase == 0) { 069 this.heapBaseRegister = null; 070 } else { 071 this.heapBaseRegister = heapBaseRegister; 072 } 073 } 074 075 @Override 076 protected boolean improve(AMD64AddressNode addr) { 077 if (addr.getScale() == Scale.Times1) { 078 if (addr.getBase() == null && addr.getIndex() instanceof CompressionNode) { 079 if (improveUncompression(addr, (CompressionNode) addr.getIndex())) { 080 return true; 081 } 082 } 083 084 if (addr.getIndex() == null && addr.getBase() instanceof CompressionNode) { 085 if (improveUncompression(addr, (CompressionNode) addr.getBase())) { 086 return true; 087 } 088 } 089 } 090 091 return super.improve(addr); 092 } 093 094 private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression) { 095 if (compression.getOp() == CompressionOp.Uncompress) { 096 CompressEncoding encoding = compression.getEncoding(); 097 Scale scale = Scale.fromShift(encoding.shift); 098 if (scale == null) { 099 return false; 100 } 101 102 if (heapBaseRegister != null && encoding.base == heapBase) { 103 ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister)); 104 addr.setBase(base); 105 } else if (encoding.base != 0) { 106 long disp = addr.getDisplacement() + encoding.base; 107 if (NumUtil.isInt(disp)) { 108 addr.setDisplacement((int) disp); 109 addr.setBase(null); 110 } else { 111 return false; 112 } 113 } else { 114 addr.setBase(null); 115 } 116 117 addr.setScale(scale); 118 addr.setIndex(compression.getValue()); 119 return true; 120 } else { 121 return false; 122 } 123 } 124}