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}