graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java

Print this page
rev 8592 : Graal PTX enhancements


  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.asm.*;
  34 
  35 // @formatter:off
  36 public enum PTXArithmetic {
  37     IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
  38     LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
  39     FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR,
  40     DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR,
  41     INEG, LNEG,
  42     I2L, L2I, I2B, I2C, I2S,
  43     F2D, D2F,
  44     I2F, I2D, F2I, D2I,
  45     L2F, L2D, F2L, D2L,
  46     MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
  47 
  48 









































  49     public static class Op1Reg extends PTXLIRInstruction {
  50         @Opcode private final PTXArithmetic opcode;
  51         @Def({REG, HINT}) protected Value result;
  52         @Use({REG}) protected Value x;
  53 
  54         public Op1Reg(PTXArithmetic opcode, Value result, Value x) {
  55             this.opcode = opcode;
  56             this.result = result;
  57             this.x = x;
  58         }
  59 
  60         @Override
  61         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
  62             emit(tasm, masm, opcode, result, x, null);
  63         }
  64     }
  65 
  66     public static class Op1Stack extends PTXLIRInstruction {
  67         @Opcode private final PTXArithmetic opcode;
  68         @Def({REG, HINT}) protected Value result;


 196         public DivOp(PTXArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) {
 197             this.opcode = opcode;
 198             this.result = result;
 199             this.x = x;
 200             this.y = y;
 201             this.state = state;
 202         }
 203 
 204         @Override
 205         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
 206             emit(tasm, masm, opcode, result, y, state);
 207         }
 208 
 209         @Override
 210         protected void verify() {
 211             super.verify();
 212             verifyKind(opcode, result, x, y);
 213         }
 214     }
 215 
 216 
 217     @SuppressWarnings("unused")
 218     protected static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value result) {
 219         switch (opcode) {
 220             default:   throw GraalInternalError.shouldNotReachHere();




 221         }
 222     }
 223 
 224     public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
 225         int exceptionOffset = -1;
 226         if (isRegister(src)) {
 227             Register a = asIntReg(src);
 228             Register d = asIntReg(dst);
 229             switch (opcode) {
 230                 case INEG: masm.neg_s32(d, a); break;













 231                 default:

 232                     throw GraalInternalError.shouldNotReachHere();
 233             }
 234         } else if (isConstant(src)) {
 235             switch (opcode) {
 236                 case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
 237                 case IAND: masm.and_b32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
 238                 default:   throw GraalInternalError.shouldNotReachHere();
 239             }
 240         } else {
 241             switch (opcode) {
 242                 default:   throw GraalInternalError.shouldNotReachHere();
 243             }
 244         }
 245 
 246         if (info != null) {
 247             assert exceptionOffset != -1;
 248             tasm.recordImplicitException(exceptionOffset, info);
 249         }
 250     }
 251 
 252     public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
 253         int exceptionOffset = -1;
 254         if (isConstant(src1)) {
 255             int      a = tasm.asIntConst(src1);
 256             Register b = asIntReg(src2);
 257             Register d = asIntReg(dst);
 258             switch (opcode) {
 259             case ISUB:  masm.sub_s32(d, a, b); break;
 260             case IAND:  masm.and_b32(d, b, a); break;
 261             default:    throw GraalInternalError.shouldNotReachHere();






 262             }
 263         } else if (isConstant(src2)) {
 264             Register a = asIntReg(src1);
 265             int      b = tasm.asIntConst(src2);
 266             Register d = asIntReg(dst);
 267             switch (opcode) {
 268             case IADD:  masm.add_s32(d, a, b); break;
 269             case IAND:  masm.and_b32(d, a, b); break;
 270             case IUSHR: masm.shr_u32(d, a, b); break;
 271             default:    throw GraalInternalError.shouldNotReachHere();














 272             }
 273         } else {
 274             Register a = asIntReg(src1);
 275             Register b = asIntReg(src2);
 276             Register d = asIntReg(dst);
 277             switch (opcode) {
 278             case IADD:  masm.add_s32(d, a, b); break;
 279             case ISUB:  masm.sub_s32(d, a, b); break;
 280             case IMUL:  masm.mul_s32(d, a, b); break;
 281             default:    throw GraalInternalError.shouldNotReachHere();































 282             }
 283         }
 284 
 285         if (info != null) {
 286             assert exceptionOffset != -1;
 287             tasm.recordImplicitException(exceptionOffset, info);
 288         }
 289     }
 290 
 291     private static void verifyKind(PTXArithmetic opcode, Value result, Value x, Value y) {
 292         assert (opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int)
 293             || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long)
 294             || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float)
 295             || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
 296     }
 297 }


  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.Def;
  34 import com.oracle.graal.lir.LIRInstruction.Opcode;
  35 import com.oracle.graal.lir.LIRInstruction.Use;
  36 import com.oracle.graal.lir.asm.*;
  37 
  38 // @formatter:off
  39 public enum PTXArithmetic {
  40     IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
  41     LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
  42     FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR,
  43     DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
  44     INEG, LNEG, FNEG, DNEG,
  45     I2L, L2I, I2B, I2C, I2S,
  46     F2D, D2F,
  47     I2F, I2D, F2I, D2I,
  48     L2F, L2D, F2L, D2L,
  49     MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
  50 
  51 
  52     /**
  53      * Unary operation with separate source and destination operand. 
  54      */
  55     public static class Unary2Op extends PTXLIRInstruction {
  56         @Opcode private final PTXArithmetic opcode;
  57         @Def({REG}) protected AllocatableValue result;
  58         @Use({REG, STACK}) protected AllocatableValue x;
  59 
  60         public Unary2Op(PTXArithmetic opcode, AllocatableValue result, AllocatableValue x) {
  61             this.opcode = opcode;
  62             this.result = result;
  63             this.x = x;
  64         }
  65 
  66                 @Override
  67                 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
  68             PTXMove.move(tasm, masm, result, x);
  69             emit(tasm, masm, opcode, result, x, null);
  70                 }
  71     }
  72 
  73     /**
  74      * Unary operation with single operand for source and destination. 
  75      */
  76     public static class Unary1Op extends PTXLIRInstruction {
  77         @Opcode private final PTXArithmetic opcode;
  78         @Def({REG, HINT}) protected AllocatableValue result;
  79         @Use({REG, STACK}) protected AllocatableValue x;
  80 
  81         public Unary1Op(PTXArithmetic opcode, AllocatableValue result, AllocatableValue x) {
  82             this.opcode = opcode;
  83             this.result = result;
  84             this.x = x;
  85         }
  86 
  87                 @Override
  88                 public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
  89             emit(tasm, masm, opcode, result);
  90                 }
  91     }
  92 
  93     public static class Op1Reg extends PTXLIRInstruction {
  94         @Opcode private final PTXArithmetic opcode;
  95         @Def({REG, HINT}) protected Value result;
  96         @Use({REG}) protected Value x;
  97 
  98         public Op1Reg(PTXArithmetic opcode, Value result, Value x) {
  99             this.opcode = opcode;
 100             this.result = result;
 101             this.x = x;
 102         }
 103 
 104         @Override
 105         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
 106             emit(tasm, masm, opcode, result, x, null);
 107         }
 108     }
 109 
 110     public static class Op1Stack extends PTXLIRInstruction {
 111         @Opcode private final PTXArithmetic opcode;
 112         @Def({REG, HINT}) protected Value result;


 240         public DivOp(PTXArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) {
 241             this.opcode = opcode;
 242             this.result = result;
 243             this.x = x;
 244             this.y = y;
 245             this.state = state;
 246         }
 247 
 248         @Override
 249         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
 250             emit(tasm, masm, opcode, result, y, state);
 251         }
 252 
 253         @Override
 254         protected void verify() {
 255             super.verify();
 256             verifyKind(opcode, result, x, y);
 257         }
 258     }
 259 


 260     protected static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value result) {
 261         switch (opcode) {
 262         case L2I:  masm.cvt_s32_s64(asLongReg(result), asIntReg(result)); break;
 263         case I2C:  masm.cvt_b16_s32(asIntReg(result), asIntReg(result)); break;
 264             default:   
 265                 System.err.println("missing: "  + opcode);
 266                 throw GraalInternalError.shouldNotReachHere();
 267         }
 268     }
 269 
 270     public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
 271         int exceptionOffset = -1;
 272         if (isRegister(src)) {
 273             Register a = asIntReg(src);
 274             Register d = asIntReg(dst);
 275             switch (opcode) {
 276                 case INEG: masm.neg_s32(d, a);     break;
 277                 case FNEG: masm.neg_f32(d, a);     break;
 278                 case DNEG: masm.neg_f64(d, a);     break;
 279                 case I2L:  masm.cvt_s64_s32(d, a); break;
 280                 case I2C:  masm.cvt_b16_s32(d, a); break;
 281                 case I2B:  masm.cvt_s8_s32(d, a);  break;
 282                 case I2F:  masm.cvt_f32_s32(d, a); break;
 283                 case I2D:  masm.cvt_f64_s32(d, a); break;
 284                 case F2I:  masm.cvt_s32_f32(d, a); break;
 285                 case F2L:  masm.cvt_s64_f32(d, a); break;
 286                 case F2D:  masm.cvt_f64_f32(d, a); break;
 287                 case D2I:  masm.cvt_s32_f64(d, a); break;
 288                 case D2L:  masm.cvt_s64_f64(d, a); break;
 289                 case D2F:  masm.cvt_f32_f64(d, a); break;
 290                 default:
 291                         System.err.println("missing: "  + opcode);
 292                     throw GraalInternalError.shouldNotReachHere();
 293             }
 294         } else if (isConstant(src)) {
 295             switch (opcode) {
 296                 case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
 297                 case IAND: masm.and_b32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
 298                 default:   throw GraalInternalError.shouldNotReachHere();
 299             }
 300         } else {
 301             switch (opcode) {
 302                 default:   throw GraalInternalError.shouldNotReachHere();
 303             }
 304         }
 305 
 306         if (info != null) {
 307             assert exceptionOffset != -1;
 308             tasm.recordImplicitException(exceptionOffset, info);
 309         }
 310     }
 311 
 312     public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
 313         int exceptionOffset = -1;
 314         if (isConstant(src1)) {



 315             switch (opcode) {
 316                     case ISUB:  masm.sub_s32(asIntReg(dst),    tasm.asIntConst(src1),    asIntReg(src2));         break;
 317                     case IAND:  masm.and_b32(asIntReg(dst),    asIntReg(src2),           tasm.asIntConst(src1));  break;
 318                     case IDIV:  masm.div_s32(asIntReg(dst),    tasm.asIntConst(src1),    asIntReg(src2));         break;
 319                     case FSUB:  masm.sub_f32(asFloatReg(dst),  tasm.asFloatConst(src1),  asFloatReg(src2));       break;
 320                     case FDIV:  masm.div_f32(asFloatReg(dst),  tasm.asFloatConst(src1),  asFloatReg(src2));       break;
 321                     case DSUB:  masm.sub_f64(asDoubleReg(dst), tasm.asDoubleConst(src1), asDoubleReg(src2));      break;
 322                     case DDIV:  masm.div_f64(asDoubleReg(dst), tasm.asDoubleConst(src1), asDoubleReg(src2));      break;
 323                     default:    
 324                         throw GraalInternalError.shouldNotReachHere();
 325             }
 326         } else if (isConstant(src2)) {



 327             switch (opcode) {
 328                     case IADD:  masm.add_s32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 329                     case ISUB:  masm.sub_s32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 330                     case IMUL:  masm.mul_s32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 331                     case IAND:  masm.and_b32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 332                     case ISHL:  masm.shl_s32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 333                     case ISHR:  masm.shr_s32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 334                     case IUSHR: masm.shr_u32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 335                     case IXOR:  masm.xor_b32(asIntReg(dst),    asIntReg(src1),    tasm.asIntConst(src2));    break;
 336                     case LXOR:  masm.xor_b64(asLongReg(dst),   asLongReg(src1),   tasm.asLongConst(src2));   break;
 337                     case LUSHR: masm.shr_u64(asLongReg(dst),   asLongReg(src1),   tasm.asLongConst(src2));   break;
 338                     case FADD:  masm.add_f32(asFloatReg(dst),  asFloatReg(src1),  tasm.asFloatConst(src2));  break;
 339                     case FMUL:  masm.mul_f32(asFloatReg(dst),  asFloatReg(src1),  tasm.asFloatConst(src2));  break;
 340                     case FDIV:  masm.div_f32(asFloatReg(dst),  asFloatReg(src1),  tasm.asFloatConst(src2));  break;
 341                     case DADD:  masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
 342                     case DMUL:  masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
 343                     case DDIV:  masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
 344                     default:    
 345                         throw GraalInternalError.shouldNotReachHere();
 346             }
 347         } else {



 348             switch (opcode) {
 349                     case IADD:  masm.add_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 350                     case ISUB:  masm.sub_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 351                     case IMUL:  masm.mul_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 352                     case IDIV:  masm.div_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 353                     case IAND:  masm.and_b32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 354                     case IOR:   masm.or_b32 (asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 355                     case IXOR:  masm.xor_b32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 356                     case ISHL:  masm.shl_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 357                     case ISHR:  masm.shr_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 358                     case IUSHR: masm.shr_u32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 359                     case IREM:  masm.rem_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
 360                     case LADD:  masm.add_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 361                     case LSUB:  masm.sub_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 362                     case LMUL:  masm.mul_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 363                     case LDIV:  masm.div_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 364                     case LAND:  masm.and_b64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 365                     case LOR:   masm.or_b64 (asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 366                     case LXOR:  masm.xor_b64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 367                     case LSHL:  masm.shl_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 368                     case LSHR:  masm.shr_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 369                     case LUSHR: masm.shr_u64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 370                     case LREM:  masm.rem_s64(asLongReg(dst),   asLongReg(src1),   asLongReg(src2));   break;
 371                     case FADD:  masm.add_f32(asFloatReg(dst),  asFloatReg(src1),  asFloatReg(src2));  break;
 372                     case FSUB:  masm.sub_f32(asFloatReg(dst),  asFloatReg(src1),  asFloatReg(src2));  break;
 373                     case FMUL:  masm.mul_f32(asFloatReg(dst),  asFloatReg(src1),  asFloatReg(src2));  break;
 374                     case FDIV:  masm.div_f32(asFloatReg(dst),  asFloatReg(src1),  asFloatReg(src2));  break;
 375                     case FREM:  masm.div_f32(asFloatReg(dst),  asFloatReg(src1),  asFloatReg(src2));  break;
 376                     case DADD:  masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
 377                     case DSUB:  masm.sub_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
 378                     case DMUL:  masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
 379                     case DDIV:  masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
 380                     case DREM:  masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
 381                     default:   
 382                         System.err.println("missing: "  + opcode);
 383                         throw GraalInternalError.shouldNotReachHere();
 384             }
 385         }
 386 
 387         if (info != null) {
 388             assert exceptionOffset != -1;
 389             tasm.recordImplicitException(exceptionOffset, info);
 390         }
 391     }
 392 
 393     private static void verifyKind(PTXArithmetic opcode, Value result, Value x, Value y) {
 394         assert (opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int)
 395             || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long)
 396             || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float)
 397             || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
 398     }
 399 }