001/* 002 * Copyright (c) 2009, 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.compiler.sparc; 025 026import jdk.internal.jvmci.code.*; 027import jdk.internal.jvmci.common.*; 028import jdk.internal.jvmci.meta.*; 029 030import com.oracle.graal.compiler.gen.*; 031import com.oracle.graal.compiler.match.*; 032import com.oracle.graal.lir.*; 033import com.oracle.graal.lir.StandardOp.JumpOp; 034import com.oracle.graal.lir.gen.*; 035import com.oracle.graal.lir.sparc.*; 036import com.oracle.graal.nodes.*; 037import com.oracle.graal.nodes.calc.*; 038import com.oracle.graal.nodes.memory.*; 039 040/** 041 * This class implements the SPARC specific portion of the LIR generator. 042 */ 043public abstract class SPARCNodeLIRBuilder extends NodeLIRBuilder { 044 045 public SPARCNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen) { 046 super(graph, lirGen); 047 } 048 049 @Override 050 protected boolean peephole(ValueNode valueNode) { 051 // No peephole optimizations for now 052 return false; 053 } 054 055 @Override 056 public void visitBreakpointNode(BreakpointNode node) { 057 JavaType[] sig = new JavaType[node.arguments().size()]; 058 for (int i = 0; i < sig.length; i++) { 059 sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess()); 060 } 061 062 Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(CallingConvention.Type.JavaCall, null, sig, gen.target(), false), 063 node.arguments()); 064 append(new SPARCBreakpointOp(parameters)); 065 } 066 067 @Override 068 protected JumpOp newJumpOp(LabelRef ref) { 069 return new SPARCJumpOp(ref); 070 } 071 072 protected LIRFrameState getState(Access access) { 073 if (access instanceof DeoptimizingNode) { 074 return state((DeoptimizingNode) access); 075 } 076 return null; 077 } 078 079 private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) { 080 assert fromBits <= toBits && toBits <= 64; 081 Kind toKind = null; 082 Kind fromKind = null; 083 if (fromBits == toBits) { 084 return null; 085 } else if (toBits > 32) { 086 toKind = Kind.Long; 087 } else if (toBits > 16) { 088 toKind = Kind.Int; 089 } else { 090 toKind = Kind.Short; 091 } 092 switch (fromBits) { 093 case 8: 094 fromKind = Kind.Byte; 095 break; 096 case 16: 097 fromKind = Kind.Short; 098 break; 099 case 32: 100 fromKind = Kind.Int; 101 break; 102 default: 103 throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); 104 } 105 106 Kind localFromKind = fromKind; 107 Kind localToKind = toKind; 108 return builder -> { 109 Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access)); 110 return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); 111 }; 112 } 113 114 private ComplexMatchResult emitZeroExtendMemory(Access access, int fromBits, int toBits) { 115 assert fromBits <= toBits && toBits <= 64; 116 Kind toKind = null; 117 Kind fromKind = null; 118 if (fromBits == toBits) { 119 return null; 120 } else if (toBits > 32) { 121 toKind = Kind.Long; 122 } else if (toBits > 16) { 123 toKind = Kind.Int; 124 } else { 125 toKind = Kind.Short; 126 } 127 switch (fromBits) { 128 case 8: 129 fromKind = Kind.Byte; 130 break; 131 case 16: 132 fromKind = Kind.Short; 133 break; 134 case 32: 135 fromKind = Kind.Int; 136 break; 137 default: 138 throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); 139 } 140 141 Kind localFromKind = fromKind; 142 Kind localToKind = toKind; 143 return builder -> { 144 // Loads are always zero extending load 145 Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access)); 146 return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); 147 }; 148 } 149 150 @MatchRule("(SignExtend Read=access)") 151 @MatchRule("(SignExtend FloatingRead=access)") 152 public ComplexMatchResult signExtend(SignExtendNode root, Access access) { 153 return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits()); 154 } 155 156 @MatchRule("(ZeroExtend Read=access)") 157 @MatchRule("(ZeroExtend FloatingRead=access)") 158 public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) { 159 return emitZeroExtendMemory(access, root.getInputBits(), root.getResultBits()); 160 } 161 162 @Override 163 public SPARCLIRGenerator getLIRGeneratorTool() { 164 return (SPARCLIRGenerator) super.getLIRGeneratorTool(); 165 } 166 167 @Override 168 protected void emitPrologue(StructuredGraph graph) { 169 getLIRGeneratorTool().emitLoadConstantTableBase(); 170 super.emitPrologue(graph); 171 } 172}