1 /* 2 * Copyright (c) 2013, 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.lir.hsail; 24 25 import static com.oracle.graal.api.code.ValueUtil.*; 26 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; 27 28 import com.oracle.graal.api.code.*; 29 import com.oracle.graal.api.meta.*; 30 import com.oracle.graal.asm.hsail.*; 31 import com.oracle.graal.debug.*; 32 import com.oracle.graal.graph.*; 33 import com.oracle.graal.lir.*; 34 import com.oracle.graal.lir.StandardOp.MoveOp; 35 import com.oracle.graal.lir.asm.*; 36 37 /** 38 * Implementation of move instructions. 39 */ 40 public class HSAILMove { 41 42 // Stack size in bytes (used to keep track of spilling). 43 static int maxDatatypeSize; 44 // Maximum stack offset used by a store operation. 45 static long maxStackOffset = 0; 46 47 public static long upperBoundStackSize() { 48 return maxStackOffset + maxDatatypeSize; 49 } 50 51 @Opcode("MOVE") 52 public static class SpillMoveOp extends HSAILLIRInstruction implements MoveOp { 53 54 @Def({REG, STACK}) protected AllocatableValue result; 55 @Use({REG, STACK, CONST}) protected Value input; 56 57 public SpillMoveOp(AllocatableValue result, Value input) { 58 this.result = result; 59 this.input = input; 60 } 61 62 @Override 63 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 64 move(tasm, masm, getResult(), getInput()); 65 } 66 67 @Override 68 public Value getInput() { 69 return input; 70 } 71 72 @Override 73 public AllocatableValue getResult() { 74 return result; 75 } 76 } 77 78 @Opcode("MOVE") 79 public static class MoveToRegOp extends HSAILLIRInstruction implements MoveOp { 80 81 @Def({REG, HINT}) protected AllocatableValue result; 82 @Use({REG, STACK, CONST}) protected Value input; 83 84 public MoveToRegOp(AllocatableValue result, Value input) { 85 this.result = result; 86 this.input = input; 87 } 88 89 @Override 90 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 91 move(tasm, masm, getResult(), getInput()); 92 } 93 94 @Override 95 public Value getInput() { 96 return input; 97 } 98 99 @Override 100 public AllocatableValue getResult() { 101 return result; 102 } 103 } 104 105 @Opcode("MOVE") 106 public static class MoveFromRegOp extends HSAILLIRInstruction implements MoveOp { 107 108 @Def({REG, STACK}) protected AllocatableValue result; 109 @Use({REG, CONST, HINT}) protected Value input; 110 111 public MoveFromRegOp(AllocatableValue result, Value input) { 112 this.result = result; 113 this.input = input; 114 } 115 116 @Override 117 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 118 move(tasm, masm, getResult(), getInput()); 119 } 120 121 @Override 122 public Value getInput() { 123 return input; 124 } 125 126 @Override 127 public AllocatableValue getResult() { 128 return result; 129 } 130 } 131 132 public static class LoadOp extends HSAILLIRInstruction { 133 134 @SuppressWarnings("unused") private final Kind kind; 135 @Def({REG}) protected AllocatableValue result; 136 @Use({COMPOSITE}) protected HSAILAddressValue address; 137 @State protected LIRFrameState state; 138 139 public LoadOp(Kind kind, AllocatableValue result, HSAILAddressValue address, LIRFrameState state) { 140 this.kind = kind; 141 this.result = result; 142 this.address = address; 143 this.state = state; 144 } 145 146 @Override 147 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 148 HSAILAddress addr = address.toAddress(); 149 masm.emitLoad(result, addr); 150 } 151 } 152 153 public static class StoreOp extends HSAILLIRInstruction { 154 155 @SuppressWarnings("unused") private final Kind kind; 156 @Use({COMPOSITE}) protected HSAILAddressValue address; 157 @Use({REG}) protected AllocatableValue input; 158 @State protected LIRFrameState state; 159 160 public StoreOp(Kind kind, HSAILAddressValue address, AllocatableValue input, LIRFrameState state) { 161 this.kind = kind; 162 this.address = address; 163 this.input = input; 164 this.state = state; 165 } 166 167 @Override 168 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 169 assert isRegister(input); 170 HSAILAddress addr = address.toAddress(); 171 masm.emitStore(input, addr); 172 } 173 } 174 175 public static class LeaOp extends HSAILLIRInstruction { 176 177 @Def({REG}) protected AllocatableValue result; 178 @Use({COMPOSITE, UNINITIALIZED}) protected HSAILAddressValue address; 179 180 public LeaOp(AllocatableValue result, HSAILAddressValue address) { 181 this.result = result; 182 this.address = address; 183 } 184 185 @Override 186 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 187 throw new InternalError("NYI"); 188 } 189 } 190 191 public static class StackLeaOp extends HSAILLIRInstruction { 192 193 @Def({REG}) protected AllocatableValue result; 194 @Use({STACK, UNINITIALIZED}) protected StackSlot slot; 195 196 public StackLeaOp(AllocatableValue result, StackSlot slot) { 197 this.result = result; 198 this.slot = slot; 199 } 200 201 @Override 202 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 203 throw new InternalError("NYI"); 204 } 205 } 206 207 @Opcode("CAS") 208 public static class CompareAndSwapOp extends HSAILLIRInstruction { 209 210 @Def protected AllocatableValue result; 211 @Use({COMPOSITE}) protected HSAILAddressValue address; 212 @Use protected AllocatableValue cmpValue; 213 @Use protected AllocatableValue newValue; 214 215 public CompareAndSwapOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { 216 this.result = result; 217 this.address = address; 218 this.cmpValue = cmpValue; 219 this.newValue = newValue; 220 } 221 222 @Override 223 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 224 compareAndSwap(tasm, masm, result, address, cmpValue, newValue); 225 } 226 } 227 228 public static class NullCheckOp extends HSAILLIRInstruction { 229 230 @Use protected Value input; 231 @State protected LIRFrameState state; 232 233 public NullCheckOp(Variable input, LIRFrameState state) { 234 this.input = input; 235 this.state = state; 236 } 237 238 @Override 239 public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { 240 Debug.log("NullCheckOp unimplemented"); 241 } 242 } 243 244 @SuppressWarnings("unused") 245 public static void move(TargetMethodAssembler tasm, HSAILAssembler masm, Value result, Value input) { 246 if (isRegister(input)) { 247 if (isRegister(result)) { 248 masm.emitMov(result, input); 249 } else if (isStackSlot(result)) { 250 masm.emitSpillStore(input, result); 251 } else { 252 throw GraalInternalError.shouldNotReachHere(); 253 } 254 } else if (isStackSlot(input)) { 255 if (isRegister(result)) { 256 masm.emitSpillLoad(result, input); 257 } else { 258 throw GraalInternalError.shouldNotReachHere(); 259 } 260 } else if (isConstant(input)) { 261 if (isRegister(result)) { 262 masm.emitMov(result, input); 263 } else { 264 throw GraalInternalError.shouldNotReachHere(); 265 } 266 } else { 267 throw GraalInternalError.shouldNotReachHere(); 268 } 269 } 270 271 @SuppressWarnings("unused") 272 protected static void compareAndSwap(TargetMethodAssembler tasm, HSAILAssembler masm, AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { 273 throw new InternalError("NYI"); 274 } 275 }