001/* 002 * Copyright (c) 2013, 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 */ 023package com.oracle.graal.hotspot.sparc; 024 025import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; 026import static jdk.internal.jvmci.code.ValueUtil.*; 027import jdk.internal.jvmci.code.*; 028import jdk.internal.jvmci.hotspot.HotSpotVMConfig.CompressEncoding; 029import jdk.internal.jvmci.meta.*; 030 031import com.oracle.graal.asm.*; 032import com.oracle.graal.asm.sparc.SPARCAssembler.Annul; 033import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict; 034import com.oracle.graal.asm.sparc.SPARCAssembler.CC; 035import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; 036import com.oracle.graal.asm.sparc.SPARCAssembler.RCondition; 037import com.oracle.graal.asm.sparc.*; 038import com.oracle.graal.lir.*; 039import com.oracle.graal.lir.asm.*; 040import com.oracle.graal.lir.sparc.*; 041 042public class SPARCHotSpotMove { 043 public static final class CompressPointer extends SPARCLIRInstruction { 044 public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class); 045 public static final SizeEstimate SIZE = SizeEstimate.create(5); 046 047 private final CompressEncoding encoding; 048 private final boolean nonNull; 049 050 @Def({REG}) protected AllocatableValue result; 051 @Use({REG}) protected AllocatableValue input; 052 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; 053 054 public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { 055 super(TYPE, SIZE); 056 this.result = result; 057 this.input = input; 058 this.baseRegister = baseRegister; 059 this.encoding = encoding; 060 this.nonNull = nonNull; 061 } 062 063 @Override 064 public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { 065 Register inputRegister = asRegister(input); 066 Register resReg = asRegister(result); 067 if (encoding.base != 0) { 068 Register baseReg = asRegister(baseRegister); 069 if (!nonNull) { 070 masm.cmp(inputRegister, baseReg); 071 masm.movcc(ConditionFlag.Equal, CC.Xcc, baseReg, resReg); 072 masm.sub(resReg, baseReg, resReg); 073 } else { 074 masm.sub(inputRegister, baseReg, resReg); 075 } 076 if (encoding.shift != 0) { 077 masm.srlx(resReg, encoding.shift, resReg); 078 } 079 } else { 080 masm.srlx(inputRegister, encoding.shift, resReg); 081 } 082 } 083 } 084 085 public static final class UncompressPointer extends SPARCLIRInstruction { 086 public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class); 087 public static final SizeEstimate SIZE = SizeEstimate.create(4); 088 089 private final CompressEncoding encoding; 090 private final boolean nonNull; 091 092 @Def({REG}) protected AllocatableValue result; 093 @Use({REG}) protected AllocatableValue input; 094 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; 095 096 public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { 097 super(TYPE, SIZE); 098 this.result = result; 099 this.input = input; 100 this.baseRegister = baseRegister; 101 this.encoding = encoding; 102 this.nonNull = nonNull; 103 } 104 105 @Override 106 public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { 107 Register inputRegister = asRegister(input); 108 Register resReg = asRegister(result); 109 Register secondaryInput; 110 if (encoding.shift != 0) { 111 masm.sll(inputRegister, encoding.shift, resReg); 112 secondaryInput = resReg; 113 } else { 114 secondaryInput = inputRegister; 115 } 116 117 if (encoding.base != 0) { 118 if (nonNull) { 119 masm.add(secondaryInput, asRegister(baseRegister), resReg); 120 } else { 121 Label done = new Label(); 122 masm.bpr(RCondition.Rc_nz, Annul.ANNUL, done, BranchPredict.PREDICT_TAKEN, secondaryInput); 123 masm.add(asRegister(baseRegister), secondaryInput, resReg); 124 masm.bind(done); 125 } 126 } 127 } 128 } 129 130}