1 /* 2 * Copyright (c) 2011, 2012, 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.asm.*; 33 import com.oracle.graal.nodes.calc.*; 34 35 public enum PTXCompare { 36 ICMP, LCMP, ACMP, FCMP, DCMP; 37 38 public static class CompareOp extends PTXLIRInstruction { 39 40 @Opcode private final PTXCompare opcode; 41 @Use({REG, STACK, CONST}) protected Value x; 42 @Use({REG, STACK, CONST}) protected Value y; 43 private final Condition condition; 44 45 public CompareOp(PTXCompare opcode, Condition condition, Value x, Value y) { 46 this.opcode = opcode; 47 this.condition = condition; 48 this.x = x; 49 this.y = y; 50 } 51 52 @Override 53 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { 54 emit(tasm, masm, opcode, condition, x, y); 55 } 56 57 @Override 58 protected void verify() { 59 super.verify(); 60 assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || 61 (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) || 62 (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); 63 } 64 } 65 66 public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXCompare opcode, Condition condition, Value x, Value y) { 67 if (isConstant(x)) { 68 int a = tasm.asIntConst(x); 69 Register b = asIntReg(y); 70 switch (opcode) { 71 case ICMP: 72 emitCompareConstReg(masm, condition, a, b); 73 break; 74 default: 75 throw GraalInternalError.shouldNotReachHere(); 76 } 77 } else if (isConstant(y)) { 78 Register a = asIntReg(x); 79 int b = tasm.asIntConst(y); 80 switch (opcode) { 81 case ICMP: 82 emitCompareRegConst(masm, condition, a, b); 83 break; 84 case ACMP: 85 if (((Constant) y).isNull()) { 86 switch (condition) { 87 case EQ: 88 masm.setp_eq_s32(a, b); 89 break; 90 case NE: 91 masm.setp_ne_s32(a, b); 92 break; 93 default: 94 throw GraalInternalError.shouldNotReachHere(); 95 } 96 } else { 97 throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); 98 } 99 break; 100 default: 101 throw GraalInternalError.shouldNotReachHere(); 102 } 103 } else { 104 Register a = asIntReg(x); 105 Register b = asIntReg(y); 106 switch (opcode) { 107 case ICMP: 108 emitCompareRegReg(masm, condition, a, b); 109 break; 110 default: 111 throw GraalInternalError.shouldNotReachHere(); 112 } 113 } 114 } 115 116 private static void emitCompareConstReg(PTXAssembler masm, Condition condition, int a, Register b) { 117 switch (condition) { 118 case EQ: 119 masm.setp_eq_s32(a, b); 120 break; 121 case NE: 122 masm.setp_ne_s32(a, b); 123 break; 124 case LT: 125 masm.setp_lt_s32(a, b); 126 break; 127 case LE: 128 masm.setp_le_s32(a, b); 129 break; 130 case GT: 131 masm.setp_gt_s32(a, b); 132 break; 133 case GE: 134 masm.setp_ge_s32(a, b); 135 break; 136 case AT: 137 masm.setp_gt_u32(a, b); 138 break; 139 case AE: 140 masm.setp_ge_u32(a, b); 141 break; 142 case BT: 143 masm.setp_lt_u32(a, b); 144 break; 145 case BE: 146 masm.setp_le_u32(a, b); 147 break; 148 default: 149 throw GraalInternalError.shouldNotReachHere(); 150 } 151 } 152 153 private static void emitCompareRegConst(PTXAssembler masm, Condition condition, Register a, int b) { 154 switch (condition) { 155 case EQ: 156 masm.setp_eq_s32(a, b); 157 break; 158 case NE: 159 masm.setp_ne_s32(a, b); 160 break; 161 case LT: 162 masm.setp_lt_s32(a, b); 163 break; 164 case LE: 165 masm.setp_le_s32(a, b); 166 break; 167 case GT: 168 masm.setp_gt_s32(a, b); 169 break; 170 case GE: 171 masm.setp_ge_s32(a, b); 172 break; 173 case AT: 174 masm.setp_gt_u32(a, b); 175 break; 176 case AE: 177 masm.setp_ge_u32(a, b); 178 break; 179 case BT: 180 masm.setp_lt_u32(a, b); 181 break; 182 case BE: 183 masm.setp_le_u32(a, b); 184 break; 185 default: 186 throw GraalInternalError.shouldNotReachHere(); 187 } 188 } 189 190 private static void emitCompareRegReg(PTXAssembler masm, Condition condition, Register a, Register b) { 191 switch (condition) { 192 case EQ: 193 masm.setp_eq_s32(a, b); 194 break; 195 case NE: 196 masm.setp_ne_s32(a, b); 197 break; 198 case LT: 199 masm.setp_lt_s32(a, b); 200 break; 201 case LE: 202 masm.setp_le_s32(a, b); 203 break; 204 case GT: 205 masm.setp_gt_s32(a, b); 206 break; 207 case GE: 208 masm.setp_ge_s32(a, b); 209 break; 210 case AT: 211 masm.setp_gt_u32(a, b); 212 break; 213 case AE: 214 masm.setp_ge_u32(a, b); 215 break; 216 case BT: 217 masm.setp_lt_u32(a, b); 218 break; 219 case BE: 220 masm.setp_le_u32(a, b); 221 break; 222 default: 223 throw GraalInternalError.shouldNotReachHere(); 224 } 225 } 226 }