1 /*
   2  * Copyright (c) 2009, 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 
  24 package org.graalvm.compiler.core.sparc;
  25 
  26 import static jdk.vm.ci.sparc.SPARCKind.BYTE;
  27 import static jdk.vm.ci.sparc.SPARCKind.HWORD;
  28 import static jdk.vm.ci.sparc.SPARCKind.WORD;
  29 import static jdk.vm.ci.sparc.SPARCKind.XWORD;
  30 
  31 import org.graalvm.compiler.core.common.LIRKind;
  32 import org.graalvm.compiler.core.gen.NodeMatchRules;
  33 import org.graalvm.compiler.core.match.ComplexMatchResult;
  34 import org.graalvm.compiler.core.match.MatchRule;
  35 import org.graalvm.compiler.debug.GraalError;
  36 import org.graalvm.compiler.lir.LIRFrameState;
  37 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  38 import org.graalvm.compiler.nodes.DeoptimizingNode;
  39 import org.graalvm.compiler.nodes.calc.SignExtendNode;
  40 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
  41 import org.graalvm.compiler.nodes.memory.Access;
  42 
  43 import jdk.vm.ci.sparc.SPARCKind;
  44 
  45 /**
  46  * This class implements the SPARC specific portion of the LIR generator.
  47  */
  48 public class SPARCNodeMatchRules extends NodeMatchRules {
  49 
  50     public SPARCNodeMatchRules(LIRGeneratorTool gen) {
  51         super(gen);
  52     }
  53 
  54     protected LIRFrameState getState(Access access) {
  55         if (access instanceof DeoptimizingNode) {
  56             return state((DeoptimizingNode) access);
  57         }
  58         return null;
  59     }
  60 
  61     private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) {
  62         assert fromBits <= toBits && toBits <= 64;
  63         SPARCKind toKind = null;
  64         SPARCKind fromKind = null;
  65         if (fromBits == toBits) {
  66             return null;
  67         }
  68         toKind = toBits > 32 ? XWORD : WORD;
  69         switch (fromBits) {
  70             case 8:
  71                 fromKind = BYTE;
  72                 break;
  73             case 16:
  74                 fromKind = HWORD;
  75                 break;
  76             case 32:
  77                 fromKind = WORD;
  78                 break;
  79             default:
  80                 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
  81         }
  82         SPARCKind localFromKind = fromKind;
  83         SPARCKind localToKind = toKind;
  84         return builder -> {
  85             return getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), LIRKind.value(localToKind), operand(access.getAddress()), getState(access));
  86         };
  87     }
  88 
  89     private ComplexMatchResult emitZeroExtendMemory(Access access, int fromBits, int toBits) {
  90         assert fromBits <= toBits && toBits <= 64;
  91         SPARCKind toKind = null;
  92         SPARCKind fromKind = null;
  93         if (fromBits == toBits) {
  94             return null;
  95         }
  96         toKind = toBits > 32 ? XWORD : WORD;
  97         switch (fromBits) {
  98             case 8:
  99                 fromKind = BYTE;
 100                 break;
 101             case 16:
 102                 fromKind = HWORD;
 103                 break;
 104             case 32:
 105                 fromKind = WORD;
 106                 break;
 107             default:
 108                 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
 109         }
 110         SPARCKind localFromKind = fromKind;
 111         SPARCKind localToKind = toKind;
 112         return builder -> {
 113             // Loads are always zero extending load
 114             return getLIRGeneratorTool().emitZeroExtendLoad(LIRKind.value(localFromKind), LIRKind.value(localToKind), operand(access.getAddress()), getState(access));
 115         };
 116     }
 117 
 118     @MatchRule("(SignExtend Read=access)")
 119     @MatchRule("(SignExtend FloatingRead=access)")
 120     public ComplexMatchResult signExtend(SignExtendNode root, Access access) {
 121         return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits());
 122     }
 123 
 124     @MatchRule("(ZeroExtend Read=access)")
 125     @MatchRule("(ZeroExtend FloatingRead=access)")
 126     public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) {
 127         return emitZeroExtendMemory(access, root.getInputBits(), root.getResultBits());
 128     }
 129 
 130     @Override
 131     public SPARCLIRGenerator getLIRGeneratorTool() {
 132         return (SPARCLIRGenerator) super.getLIRGeneratorTool();
 133     }
 134 
 135     protected SPARCArithmeticLIRGenerator getArithmeticLIRGenerator() {
 136         return (SPARCArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic();
 137     }
 138 }