mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-24 06:16:28 +00:00
AMDGPU: Minor assembler refactoring
Fix return before else, check types for selecting fltSemantics, refactor immediate checks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288715 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cfa44507a2
commit
b51e031eff
@ -804,12 +804,44 @@ struct OptionalOperand {
|
|||||||
bool (*ConvertResult)(int64_t&);
|
bool (*ConvertResult)(int64_t&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// May be called with integer type with equivalent bitwidth.
|
||||||
|
static const fltSemantics *getFltSemantics(MVT VT) {
|
||||||
|
switch (VT.getSizeInBits()) {
|
||||||
|
case 32:
|
||||||
|
return &APFloat::IEEEsingle;
|
||||||
|
case 64:
|
||||||
|
return &APFloat::IEEEdouble;
|
||||||
|
case 16:
|
||||||
|
return &APFloat::IEEEhalf;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unsupported fp type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Operand
|
// Operand
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT) {
|
||||||
|
bool Lost;
|
||||||
|
|
||||||
|
// Convert literal to single precision
|
||||||
|
APFloat::opStatus Status = FPLiteral.convert(*getFltSemantics(VT),
|
||||||
|
APFloat::rmNearestTiesToEven,
|
||||||
|
&Lost);
|
||||||
|
// We allow precision lost but not overflow or underflow
|
||||||
|
if (Status != APFloat::opOK &&
|
||||||
|
Lost &&
|
||||||
|
((Status & APFloat::opOverflow) != 0 ||
|
||||||
|
(Status & APFloat::opUnderflow) != 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AMDGPUOperand::isInlinableImm(MVT type) const {
|
bool AMDGPUOperand::isInlinableImm(MVT type) const {
|
||||||
if (!isImmTy(ImmTyNone)) {
|
if (!isImmTy(ImmTyNone)) {
|
||||||
// Only plain immediates are inlinable (e.g. "clamp" attribute is not)
|
// Only plain immediates are inlinable (e.g. "clamp" attribute is not)
|
||||||
@ -824,36 +856,28 @@ bool AMDGPUOperand::isInlinableImm(MVT type) const {
|
|||||||
if (Imm.IsFPImm) { // We got fp literal token
|
if (Imm.IsFPImm) { // We got fp literal token
|
||||||
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
|
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
|
||||||
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
|
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
|
||||||
} else { // Expected 32-bit operand
|
|
||||||
bool lost;
|
|
||||||
APFloat FPLiteral(APFloat::IEEEdouble, Literal);
|
|
||||||
// Convert literal to single precision
|
|
||||||
APFloat::opStatus status = FPLiteral.convert(APFloat::IEEEsingle,
|
|
||||||
APFloat::rmNearestTiesToEven,
|
|
||||||
&lost);
|
|
||||||
// We allow precision lost but not overflow or underflow
|
|
||||||
if (status != APFloat::opOK &&
|
|
||||||
lost &&
|
|
||||||
((status & APFloat::opOverflow) != 0 ||
|
|
||||||
(status & APFloat::opUnderflow) != 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APFloat FPLiteral(APFloat::IEEEdouble, APInt(64, Imm.Val));
|
||||||
|
if (!canLosslesslyConvertToFPType(FPLiteral, type))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check if single precision literal is inlinable
|
// Check if single precision literal is inlinable
|
||||||
return AMDGPU::isInlinableLiteral32(
|
return AMDGPU::isInlinableLiteral32(
|
||||||
static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
|
static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
|
||||||
AsmParser->isVI());
|
AsmParser->isVI());
|
||||||
}
|
}
|
||||||
} else { // We got int literal token
|
|
||||||
|
|
||||||
|
// We got int literal token.
|
||||||
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
|
if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
|
||||||
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
|
return AMDGPU::isInlinableLiteral64(Imm.Val, AsmParser->isVI());
|
||||||
} else { // Expected 32-bit operand
|
}
|
||||||
|
|
||||||
return AMDGPU::isInlinableLiteral32(
|
return AMDGPU::isInlinableLiteral32(
|
||||||
static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
|
static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
|
||||||
AsmParser->isVI());
|
AsmParser->isVI());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMDGPUOperand::isLiteralImm(MVT type) const {
|
bool AMDGPUOperand::isLiteralImm(MVT type) const {
|
||||||
// Check that this imediate can be added as literal
|
// Check that this imediate can be added as literal
|
||||||
@ -861,45 +885,28 @@ bool AMDGPUOperand::isLiteralImm(MVT type) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt Literal(64, Imm.Val);
|
if (!Imm.IsFPImm) {
|
||||||
|
// We got int literal token.
|
||||||
|
|
||||||
if (Imm.IsFPImm) { // We got fp literal token
|
// FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP
|
||||||
|
// types.
|
||||||
|
return isUInt<32>(Imm.Val) || isInt<32>(Imm.Val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got fp literal token
|
||||||
if (type == MVT::f64) { // Expected 64-bit fp operand
|
if (type == MVT::f64) { // Expected 64-bit fp operand
|
||||||
// We would set low 64-bits of literal to zeroes but we accept this literals
|
// We would set low 64-bits of literal to zeroes but we accept this literals
|
||||||
return true;
|
return true;
|
||||||
} else if (type == MVT::i64) { // Expected 64-bit int operand
|
}
|
||||||
|
|
||||||
|
if (type == MVT::i64) { // Expected 64-bit int operand
|
||||||
// We don't allow fp literals in 64-bit integer instructions. It is
|
// We don't allow fp literals in 64-bit integer instructions. It is
|
||||||
// unclear how we should encode them.
|
// unclear how we should encode them.
|
||||||
return false;
|
return false;
|
||||||
} else { // Expected 32-bit operand
|
|
||||||
bool lost;
|
|
||||||
APFloat FPLiteral(APFloat::IEEEdouble, Literal);
|
|
||||||
// Convert literal to single precision
|
|
||||||
APFloat::opStatus status = FPLiteral.convert(APFloat::IEEEsingle,
|
|
||||||
APFloat::rmNearestTiesToEven,
|
|
||||||
&lost);
|
|
||||||
// We allow precision lost but not overflow or underflow
|
|
||||||
if (status != APFloat::opOK &&
|
|
||||||
lost &&
|
|
||||||
((status & APFloat::opOverflow) != 0 ||
|
|
||||||
(status & APFloat::opUnderflow) != 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
APFloat FPLiteral(APFloat::IEEEdouble, APInt(64, Imm.Val));
|
||||||
} else { // We got int literal token
|
return canLosslesslyConvertToFPType(FPLiteral, type);
|
||||||
APInt HiBits = Literal.getHiBits(32);
|
|
||||||
if (HiBits == 0xffffffff &&
|
|
||||||
(*Literal.getLoBits(32).getRawData() & 0x80000000) != 0) {
|
|
||||||
// If high 32 bits aren't zeroes then they all should be ones and 32nd
|
|
||||||
// bit should be set. So that this 64-bit literal is sign-extension of
|
|
||||||
// 32-bit value.
|
|
||||||
return true;
|
|
||||||
} else if (HiBits == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDGPUOperand::isRegClass(unsigned RCID) const {
|
bool AMDGPUOperand::isRegClass(unsigned RCID) const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user