graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java
Print this page
rev 8661 : Graal PTX enhancements
rev 8663 : [mq]: ptx_lookup_switch
*** 28,53 ****
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.meta.*;
import com.oracle.graal.asm.ptx.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.lir.*;
import com.oracle.graal.lir.asm.*;
// @formatter:off
public enum PTXArithmetic {
IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
! FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR,
! DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR,
! INEG, LNEG,
I2L, L2I, I2B, I2C, I2S,
F2D, D2F,
I2F, I2D, F2I, D2I,
L2F, L2D, F2L, D2L,
MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
public static class Op1Reg extends PTXLIRInstruction {
@Opcode private final PTXArithmetic opcode;
@Def({REG, HINT}) protected Value result;
@Use({REG}) protected Value x;
--- 28,97 ----
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.meta.*;
import com.oracle.graal.asm.ptx.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.lir.*;
+ import com.oracle.graal.lir.LIRInstruction.Def;
+ import com.oracle.graal.lir.LIRInstruction.Opcode;
+ import com.oracle.graal.lir.LIRInstruction.Use;
import com.oracle.graal.lir.asm.*;
// @formatter:off
public enum PTXArithmetic {
IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
! FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR,
! DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
! INEG, LNEG, FNEG, DNEG,
I2L, L2I, I2B, I2C, I2S,
F2D, D2F,
I2F, I2D, F2I, D2I,
L2F, L2D, F2L, D2L,
MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
+ /**
+ * Unary operation with separate source and destination operand.
+ */
+ public static class Unary2Op extends PTXLIRInstruction {
+ @Opcode private final PTXArithmetic opcode;
+ @Def({REG}) protected AllocatableValue result;
+ @Use({REG, STACK}) protected AllocatableValue x;
+
+ public Unary2Op(PTXArithmetic opcode, AllocatableValue result, AllocatableValue x) {
+ this.opcode = opcode;
+ this.result = result;
+ this.x = x;
+ }
+
+ @Override
+ public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
+ PTXMove.move(tasm, masm, result, x);
+ emit(tasm, masm, opcode, result, x, null);
+ }
+ }
+
+ /**
+ * Unary operation with single operand for source and destination.
+ */
+ public static class Unary1Op extends PTXLIRInstruction {
+ @Opcode private final PTXArithmetic opcode;
+ @Def({REG, HINT}) protected AllocatableValue result;
+ @Use({REG, STACK}) protected AllocatableValue x;
+
+ public Unary1Op(PTXArithmetic opcode, AllocatableValue result, AllocatableValue x) {
+ this.opcode = opcode;
+ this.result = result;
+ this.x = x;
+ }
+
+ @Override
+ public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
+ emit(tasm, masm, opcode, result);
+ }
+ }
+
public static class Op1Reg extends PTXLIRInstruction {
@Opcode private final PTXArithmetic opcode;
@Def({REG, HINT}) protected Value result;
@Use({REG}) protected Value x;
*** 211,237 ****
super.verify();
verifyKind(opcode, result, x, y);
}
}
-
- @SuppressWarnings("unused")
protected static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value result) {
switch (opcode) {
! default: throw GraalInternalError.shouldNotReachHere();
}
}
public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
int exceptionOffset = -1;
if (isRegister(src)) {
Register a = asIntReg(src);
Register d = asIntReg(dst);
switch (opcode) {
case INEG: masm.neg_s32(d, a); break;
default:
! throw GraalInternalError.shouldNotReachHere();
}
} else if (isConstant(src)) {
switch (opcode) {
case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
case IAND: masm.and_b32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
--- 255,295 ----
super.verify();
verifyKind(opcode, result, x, y);
}
}
protected static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value result) {
switch (opcode) {
! case L2I: masm.cvt_s32_s64(asLongReg(result), asIntReg(result)); break;
! case I2C: masm.cvt_b16_s32(asIntReg(result), asIntReg(result)); break;
! default:
! throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
}
}
public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
int exceptionOffset = -1;
if (isRegister(src)) {
Register a = asIntReg(src);
Register d = asIntReg(dst);
switch (opcode) {
case INEG: masm.neg_s32(d, a); break;
+ case FNEG: masm.neg_f32(d, a); break;
+ case DNEG: masm.neg_f64(d, a); break;
+ case I2L: masm.cvt_s64_s32(d, a); break;
+ case I2C: masm.cvt_b16_s32(d, a); break;
+ case I2B: masm.cvt_s8_s32(d, a); break;
+ case I2F: masm.cvt_f32_s32(d, a); break;
+ case I2D: masm.cvt_f64_s32(d, a); break;
+ case F2I: masm.cvt_s32_f32(d, a); break;
+ case F2L: masm.cvt_s64_f32(d, a); break;
+ case F2D: masm.cvt_f64_f32(d, a); break;
+ case D2I: masm.cvt_s32_f64(d, a); break;
+ case D2L: masm.cvt_s64_f64(d, a); break;
+ case D2F: masm.cvt_f32_f64(d, a); break;
default:
! throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
}
} else if (isConstant(src)) {
switch (opcode) {
case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
case IAND: masm.and_b32(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
*** 250,286 ****
}
public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
int exceptionOffset = -1;
if (isConstant(src1)) {
- int a = tasm.asIntConst(src1);
- Register b = asIntReg(src2);
- Register d = asIntReg(dst);
switch (opcode) {
! case ISUB: masm.sub_s32(d, a, b); break;
! case IAND: masm.and_b32(d, b, a); break;
! default: throw GraalInternalError.shouldNotReachHere();
}
} else if (isConstant(src2)) {
- Register a = asIntReg(src1);
- int b = tasm.asIntConst(src2);
- Register d = asIntReg(dst);
switch (opcode) {
! case IADD: masm.add_s32(d, a, b); break;
! case IAND: masm.and_b32(d, a, b); break;
! case IUSHR: masm.shr_u32(d, a, b); break;
! default: throw GraalInternalError.shouldNotReachHere();
}
} else {
- Register a = asIntReg(src1);
- Register b = asIntReg(src2);
- Register d = asIntReg(dst);
switch (opcode) {
! case IADD: masm.add_s32(d, a, b); break;
! case ISUB: masm.sub_s32(d, a, b); break;
! case IMUL: masm.mul_s32(d, a, b); break;
! default: throw GraalInternalError.shouldNotReachHere();
}
}
if (info != null) {
assert exceptionOffset != -1;
--- 308,385 ----
}
public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, PTXArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
int exceptionOffset = -1;
if (isConstant(src1)) {
switch (opcode) {
! case ISUB: masm.sub_s32(asIntReg(dst), tasm.asIntConst(src1), asIntReg(src2)); break;
! case IAND: masm.and_b32(asIntReg(dst), asIntReg(src2), tasm.asIntConst(src1)); break;
! case IDIV: masm.div_s32(asIntReg(dst), tasm.asIntConst(src1), asIntReg(src2)); break;
! case FSUB: masm.sub_f32(asFloatReg(dst), tasm.asFloatConst(src1), asFloatReg(src2)); break;
! case FDIV: masm.div_f32(asFloatReg(dst), tasm.asFloatConst(src1), asFloatReg(src2)); break;
! case DSUB: masm.sub_f64(asDoubleReg(dst), tasm.asDoubleConst(src1), asDoubleReg(src2)); break;
! case DDIV: masm.div_f64(asDoubleReg(dst), tasm.asDoubleConst(src1), asDoubleReg(src2)); break;
! default:
! throw GraalInternalError.shouldNotReachHere();
}
} else if (isConstant(src2)) {
switch (opcode) {
! case IADD: masm.add_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case IMUL: masm.mul_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case IAND: masm.and_b32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case ISHL: masm.shl_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case ISHR: masm.shr_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case IUSHR: masm.shr_u32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case IXOR: masm.xor_b32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break;
! case LXOR: masm.xor_b64(asLongReg(dst), asLongReg(src1), tasm.asLongConst(src2)); break;
! case LUSHR: masm.shr_u64(asLongReg(dst), asLongReg(src1), tasm.asLongConst(src2)); break;
! case FADD: masm.add_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break;
! case FMUL: masm.mul_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break;
! case FDIV: masm.div_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break;
! case DADD: masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
! case DMUL: masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
! case DDIV: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break;
! default:
! throw GraalInternalError.shouldNotReachHere();
}
} else {
switch (opcode) {
! case IADD: masm.add_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IMUL: masm.mul_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IDIV: masm.div_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IAND: masm.and_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IOR: masm.or_b32 (asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IXOR: masm.xor_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case ISHL: masm.shl_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case ISHR: masm.shr_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IUSHR: masm.shr_u32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case IREM: masm.rem_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break;
! case LADD: masm.add_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LSUB: masm.sub_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LMUL: masm.mul_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LDIV: masm.div_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LAND: masm.and_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LOR: masm.or_b64 (asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LXOR: masm.xor_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LSHL: masm.shl_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LSHR: masm.shr_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LUSHR: masm.shr_u64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case LREM: masm.rem_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break;
! case FADD: masm.add_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break;
! case FSUB: masm.sub_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break;
! case FMUL: masm.mul_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break;
! case FDIV: masm.div_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break;
! case FREM: masm.div_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break;
! case DADD: masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
! case DSUB: masm.sub_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
! case DMUL: masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
! case DDIV: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
! case DREM: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break;
! default:
! throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
}
}
if (info != null) {
assert exceptionOffset != -1;