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.ptx; 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.ptx.*; 31 import com.oracle.graal.graph.*; 32 import com.oracle.graal.lir.*; 33 import com.oracle.graal.lir.LIRInstruction.Opcode; 34 import com.oracle.graal.lir.StandardOp.MoveOp; 35 import com.oracle.graal.lir.asm.*; 36 37 public class PTXMove { 38 39 @Opcode("MOVE") 40 public static class SpillMoveOp extends PTXLIRInstruction implements MoveOp { 41 42 @Def({REG, STACK}) protected Value result; 43 @Use({REG, STACK, CONST}) protected Value input; 44 45 public SpillMoveOp(Value result, Value input) { 46 this.result = result; 47 this.input = input; 48 } 49 50 @Override 51 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 52 move(tasm, masm, getResult(), getInput()); 53 } 54 55 @Override 56 public Value getInput() { 57 return input; 58 } 59 60 @Override 61 public Value getResult() { 62 return result; 63 } 64 } 65 66 @Opcode("MOVE") 67 public static class MoveToRegOp extends PTXLIRInstruction implements MoveOp { 68 69 @Def({REG, HINT}) protected Value result; 70 @Use({REG, STACK, CONST}) protected Value input; 71 72 public MoveToRegOp(Value result, Value input) { 73 this.result = result; 74 this.input = input; 75 } 76 77 @Override 78 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 79 move(tasm, masm, getResult(), getInput()); 80 } 81 82 @Override 83 public Value getInput() { 84 return input; 85 } 86 87 @Override 88 public Value getResult() { 89 return result; 90 } 91 } 92 93 @Opcode("MOVE") 94 public static class MoveFromRegOp extends PTXLIRInstruction implements MoveOp { 95 96 @Def({REG, STACK}) protected Value result; 97 @Use({REG, CONST, HINT}) protected Value input; 98 99 public MoveFromRegOp(Value result, Value input) { 100 this.result = result; 101 this.input = input; 102 } 103 104 @Override 105 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 106 move(tasm, masm, getResult(), getInput()); 107 } 108 109 @Override 110 public Value getInput() { 111 return input; 112 } 113 114 @Override 115 public Value getResult() { 116 return result; 117 } 118 } 119 120 public static class LoadOp extends PTXLIRInstruction { 121 122 @Def({REG}) protected AllocatableValue result; 123 @Use({COMPOSITE}) protected PTXAddressValue address; 124 @State protected LIRFrameState state; 125 126 public LoadOp(AllocatableValue result, PTXAddressValue address, LIRFrameState state) { 127 this.result = result; 128 this.address = address; 129 this.state = state; 130 } 131 132 @Override 133 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 134 PTXAddress addr = address.toAddress(); 135 switch (address.getKind()) { 136 case Int: 137 masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement()); 138 break; 139 case Object: 140 masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement()); 141 break; 142 default: 143 throw GraalInternalError.shouldNotReachHere(); 144 } 145 } 146 } 147 148 public static class StoreOp extends PTXLIRInstruction { 149 150 @Use({COMPOSITE}) protected PTXAddressValue address; 151 @Use({REG}) protected AllocatableValue input; 152 @State protected LIRFrameState state; 153 154 public StoreOp(PTXAddressValue address, AllocatableValue input, LIRFrameState state) { 155 this.address = address; 156 this.input = input; 157 this.state = state; 158 } 159 160 @Override 161 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 162 assert isRegister(input); 163 PTXAddress addr = address.toAddress(); 164 switch (address.getKind()) { 165 case Int: 166 masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); 167 break; 168 default: 169 throw GraalInternalError.shouldNotReachHere(); 170 } 171 } 172 } 173 174 public static class LeaOp extends PTXLIRInstruction { 175 176 @Def({REG}) protected AllocatableValue result; 177 @Use({COMPOSITE, UNINITIALIZED}) protected PTXAddressValue address; 178 179 public LeaOp(AllocatableValue result, PTXAddressValue address) { 180 this.result = result; 181 this.address = address; 182 } 183 184 @Override 185 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 186 throw new InternalError("NYI"); 187 } 188 } 189 190 public static class StackLeaOp extends PTXLIRInstruction { 191 192 @Def({REG}) protected AllocatableValue result; 193 @Use({STACK, UNINITIALIZED}) protected StackSlot slot; 194 195 public StackLeaOp(AllocatableValue result, StackSlot slot) { 196 this.result = result; 197 this.slot = slot; 198 } 199 200 @Override 201 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 202 throw new InternalError("NYI"); 203 } 204 } 205 206 @Opcode("CAS") 207 public static class CompareAndSwapOp extends PTXLIRInstruction { 208 209 @Def protected AllocatableValue result; 210 @Use({COMPOSITE}) protected PTXAddressValue address; 211 @Use protected AllocatableValue cmpValue; 212 @Use protected AllocatableValue newValue; 213 214 public CompareAndSwapOp(AllocatableValue result, PTXAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { 215 this.result = result; 216 this.address = address; 217 this.cmpValue = cmpValue; 218 this.newValue = newValue; 219 } 220 221 @Override 222 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 223 compareAndSwap(tasm, masm, result, address, cmpValue, newValue); 224 } 225 } 226 227 public static void move(TargetMethodAssembler tasm, PTXAssembler masm, Value result, Value input) { 228 if (isRegister(input)) { 229 if (isRegister(result)) { 230 reg2reg(masm, result, input); 231 } else { 232 throw GraalInternalError.shouldNotReachHere(); 233 } 234 } else if (isConstant(input)) { 235 if (isRegister(result)) { 236 const2reg(tasm, masm, result, (Constant) input); 237 } else { 238 throw GraalInternalError.shouldNotReachHere(); 239 } 240 } else { 241 throw GraalInternalError.shouldNotReachHere(); 242 } 243 } 244 245 private static void reg2reg(PTXAssembler masm, Value result, Value input) { 246 if (asRegister(input).equals(asRegister(result))) { 247 return; 248 } 249 switch (input.getKind()) { 250 case Int: 251 masm.mov_s32(asRegister(result), asRegister(input)); 252 break; 253 case Object: 254 masm.mov_u64(asRegister(result), asRegister(input)); 255 break; 256 default: 257 throw GraalInternalError.shouldNotReachHere("kind=" + result.getKind()); 258 } 259 } 260 261 private static void const2reg(TargetMethodAssembler tasm, PTXAssembler masm, Value result, Constant input) { 262 switch (input.getKind().getStackKind()) { 263 case Int: 264 if (tasm.runtime.needsDataPatch(input)) { 265 tasm.recordDataReferenceInCode(input, 0, true); 266 } 267 masm.mov_s32(asRegister(result), input.asInt()); 268 break; 269 default: 270 throw GraalInternalError.shouldNotReachHere(); 271 } 272 } 273 274 @SuppressWarnings("unused") 275 protected static void compareAndSwap(TargetMethodAssembler tasm, PTXAssembler masm, AllocatableValue result, PTXAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { 276 throw new InternalError("NYI"); 277 } 278 }