use super::{KernelBuilder, Operand, Predicate, PtxInstruction, PtxOp, PtxType, VirtualReg};
impl<'a> KernelBuilder<'a> {
pub fn min_u32(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Min, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn sub_u32_reg(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Sub, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn ex2_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Ex2, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn mul_u32(&mut self, a: VirtualReg, b: u32) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::ImmU64(b as u64)),
);
dst
}
pub fn mul_u32_reg(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn add_u32_reg(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Add, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn rsqrt_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Rsqrt, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn sin_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Sin, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn cos_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Cos, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn neg_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Neg, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn div_u32(&mut self, a: VirtualReg, b: u32) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Div, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::ImmU64(b as u64)),
);
dst
}
pub fn rem_u32(&mut self, a: VirtualReg, b: u32) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Rem, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::ImmU64(b as u64)),
);
dst
}
pub fn mov_u64_imm(&mut self, val: u64) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U64);
self.instructions.push(
PtxInstruction::new(PtxOp::Mov, PtxType::U64)
.dst(Operand::Reg(dst))
.src(Operand::ImmU64(val)),
);
dst
}
pub fn mul_u64(&mut self, a: VirtualReg, b: u64) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U64);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::U64)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::ImmU64(b)),
);
dst
}
pub fn mul_u64_reg(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U64);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::U64)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn branch_if_not(&mut self, pred: VirtualReg, label: &str) {
let predicate = Predicate { reg: pred, negated: true };
self.instructions
.push(PtxInstruction::new(PtxOp::Bra, PtxType::B32).predicated(predicate).label(label));
}
pub fn mul_lo_u32(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::U32);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::U32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn mul_lo_s32(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::S32);
self.instructions.push(
PtxInstruction::new(PtxOp::Mul, PtxType::S32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn abs_f32(&mut self, val: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::F32);
self.instructions.push(
PtxInstruction::new(PtxOp::Abs, PtxType::F32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(val)),
);
dst
}
pub fn min_s32(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::S32);
self.instructions.push(
PtxInstruction::new(PtxOp::Min, PtxType::S32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
pub fn max_s32(&mut self, a: VirtualReg, b: VirtualReg) -> VirtualReg {
let dst = self.registers.allocate_virtual(PtxType::S32);
self.instructions.push(
PtxInstruction::new(PtxOp::Max, PtxType::S32)
.dst(Operand::Reg(dst))
.src(Operand::Reg(a))
.src(Operand::Reg(b)),
);
dst
}
}