1 /*
   2  * Copyright (c) 2012, 2014, 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 com.oracle.graal.hotspot.hsail.replacements;
  24 
  25 import com.oracle.graal.api.code.*;
  26 import com.oracle.graal.api.meta.*;
  27 import com.oracle.graal.nodes.java.*;
  28 import com.oracle.graal.replacements.Snippet.Fold;
  29 import com.oracle.graal.word.*;
  30 import com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil;
  31 import com.oracle.graal.hotspot.meta.*;
  32 
  33 //JaCoCo Exclude
  34 
  35 /**
  36  * A collection of methods used in HSAIL-specific snippets and substitutions.
  37  */
  38 public class HSAILHotSpotReplacementsUtil extends HotSpotReplacementsUtil {
  39 
  40     private static HotSpotRegistersProvider hsailRegisters;
  41 
  42     public static void initialize(HotSpotRegistersProvider registers) {
  43         hsailRegisters = registers;
  44     }
  45 
  46     public static final LocationIdentity TLAB_INFO_LOCATION = new NamedLocationIdentity("TlabInfo");
  47     public static final LocationIdentity TLABINFO_LASTGOODTOP_LOCATION = new NamedLocationIdentity("TlabInfoLastGoodTop");
  48     public static final LocationIdentity TLABINFO_END_LOCATION = new NamedLocationIdentity("TlabInfoEnd");
  49     public static final LocationIdentity TLABINFO_TOP_LOCATION = new NamedLocationIdentity("TlabInfoTop");
  50     public static final LocationIdentity TLABINFO_START_LOCATION = new NamedLocationIdentity("TlabInfoStart");
  51     public static final LocationIdentity TLABINFO_ALLOCINFO_LOCATION = new NamedLocationIdentity("TlabInfoAllocInfo");
  52     public static final LocationIdentity TLABINFO_ORIGINALTOP_LOCATION = new NamedLocationIdentity("TlabInfoOriginalTop");
  53     public static final LocationIdentity TLABINFO_TLAB_LOCATION = new NamedLocationIdentity("TlabInfoTlab");
  54 
  55     public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLNEXT_LOCATION = new NamedLocationIdentity("AllocInfoTlabInfosPoolNext");
  56     public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLEND_LOCATION = new NamedLocationIdentity("AllocInfoTlabInfosPoolEnd");
  57     public static final LocationIdentity ALLOCINFO_TLABALIGNRESERVEBYTES_LOCATION = new NamedLocationIdentity("AllocInfoTlabAlignreservebytes");
  58 
  59     /**
  60      * Gets the value of the thread register as a Word. There is a level of indirection here. Thread
  61      * register actually points to a holder for tlab info.
  62      */
  63     public static Word getTlabInfoPtr() {
  64         Word threadRegAsWord = registerAsWord(threadRegister(), true, false);
  65         return threadRegAsWord.readWord(0, TLAB_INFO_LOCATION);
  66     }
  67 
  68     public static Word getTlabInfoPtrLoadAcquire() {
  69         Word threadRegAsWord = registerAsWord(threadRegister(), true, false);
  70         return Word.unsigned(HSAILDirectLoadAcquireNode.loadAcquireLong(threadRegAsWord));
  71     }
  72 
  73     public static void writeTlabInfoPtrStoreRelease(Word val) {
  74         // this only gets done in the waiting loop so we will always use Store Release
  75         Word threadRegAsWord = registerAsWord(threadRegister(), true, false);
  76         HSAILDirectStoreReleaseNode.storeReleaseLong(threadRegAsWord, val.rawValue());
  77     }
  78 
  79     @Fold
  80     public static Register threadRegister() {
  81         return hsailRegisters.getThreadRegister();
  82     }
  83 
  84     public static Word atomicGetAndAddTlabInfoTop(Word tlabInfo, int delta) {
  85         return Word.unsigned(AtomicReadAndAddNode.getAndAddLong(null, tlabInfo.rawValue() + config().hsailTlabInfoTopOffset, delta, TLABINFO_TOP_LOCATION));
  86     }
  87 
  88     public static Word readTlabInfoEnd(Word tlabInfo) {
  89         return tlabInfo.readWord(config().hsailTlabInfoEndOffset, TLABINFO_END_LOCATION);
  90     }
  91 
  92     public static Word readTlabInfoStart(Word tlabInfo) {
  93         return tlabInfo.readWord(config().hsailTlabInfoStartOffset, TLABINFO_START_LOCATION);
  94     }
  95 
  96     public static void writeTlabInfoLastGoodTop(Word tlabInfo, Word val) {
  97         tlabInfo.writeWord(config().hsailTlabInfoLastGoodTopOffset, val, TLABINFO_LASTGOODTOP_LOCATION);
  98     }
  99 
 100     public static void writeTlabInfoStart(Word tlabInfo, Word val) {
 101         tlabInfo.writeWord(config().hsailTlabInfoStartOffset, val, TLABINFO_START_LOCATION);
 102     }
 103 
 104     public static void writeTlabInfoTop(Word tlabInfo, Word val) {
 105         tlabInfo.writeWord(config().hsailTlabInfoTopOffset, val, TLABINFO_TOP_LOCATION);
 106     }
 107 
 108     public static void writeTlabInfoEnd(Word tlabInfo, Word val) {
 109         tlabInfo.writeWord(config().hsailTlabInfoEndOffset, val, TLABINFO_END_LOCATION);
 110     }
 111 
 112     public static Word readTlabInfoAllocInfo(Word tlabInfo) {
 113         return tlabInfo.readWord(config().hsailTlabInfoAllocInfoOffset, TLABINFO_ALLOCINFO_LOCATION);
 114     }
 115 
 116     public static void writeTlabInfoAllocInfo(Word tlabInfo, Word val) {
 117         tlabInfo.writeWord(config().hsailTlabInfoAllocInfoOffset, val, TLABINFO_ALLOCINFO_LOCATION);
 118     }
 119 
 120     public static void writeTlabInfoOriginalTop(Word tlabInfo, Word val) {
 121         tlabInfo.writeWord(config().hsailTlabInfoOriginalTopOffset, val, TLABINFO_ORIGINALTOP_LOCATION);
 122     }
 123 
 124     public static void writeTlabInfoTlab(Word tlabInfo, Word val) {
 125         tlabInfo.writeWord(config().hsailTlabInfoTlabOffset, val, TLABINFO_TLAB_LOCATION);
 126     }
 127 
 128     public static Word readTlabInfoTlab(Word tlabInfo) {
 129         return tlabInfo.readWord(config().hsailTlabInfoTlabOffset, TLABINFO_TLAB_LOCATION);
 130     }
 131 
 132     public static Word readAllocInfoTlabInfosPoolEnd(Word allocInfo) {
 133         return allocInfo.readWord(config().hsailAllocInfoTlabInfosPoolEndOffset, ALLOCINFO_TLABINFOSPOOLEND_LOCATION);
 134     }
 135 
 136     public static Word readAllocInfoTlabAlignReserveBytes(Word allocInfo) {
 137         return allocInfo.readWord(config().hsailAllocInfoTlabAlignReserveBytesOffset, ALLOCINFO_TLABALIGNRESERVEBYTES_LOCATION);
 138     }
 139 
 140     public static Word atomicGetAndAddAllocInfoTlabInfosPoolNext(Word allocInfo, int delta) {
 141         return Word.unsigned(AtomicReadAndAddNode.getAndAddLong(null, allocInfo.rawValue() + config().hsailAllocInfoTlabInfosPoolNextOffset, delta, ALLOCINFO_TLABINFOSPOOLNEXT_LOCATION));
 142     }
 143 
 144 }