mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
Add basic generic CodeGen support for half.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146927 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9b0878512f
commit
e3376ecd50
@ -45,49 +45,50 @@ namespace llvm {
|
||||
FIRST_INTEGER_VALUETYPE = i1,
|
||||
LAST_INTEGER_VALUETYPE = i128,
|
||||
|
||||
f32 = 7, // This is a 32 bit floating point value
|
||||
f64 = 8, // This is a 64 bit floating point value
|
||||
f80 = 9, // This is a 80 bit floating point value
|
||||
f128 = 10, // This is a 128 bit floating point value
|
||||
ppcf128 = 11, // This is a PPC 128-bit floating point value
|
||||
f16 = 7, // This is a 16 bit floating point value
|
||||
f32 = 8, // This is a 32 bit floating point value
|
||||
f64 = 9, // This is a 64 bit floating point value
|
||||
f80 = 10, // This is a 80 bit floating point value
|
||||
f128 = 11, // This is a 128 bit floating point value
|
||||
ppcf128 = 12, // This is a PPC 128-bit floating point value
|
||||
|
||||
v2i8 = 12, // 2 x i8
|
||||
v4i8 = 13, // 4 x i8
|
||||
v8i8 = 14, // 8 x i8
|
||||
v16i8 = 15, // 16 x i8
|
||||
v32i8 = 16, // 32 x i8
|
||||
v2i16 = 17, // 2 x i16
|
||||
v4i16 = 18, // 4 x i16
|
||||
v8i16 = 19, // 8 x i16
|
||||
v16i16 = 20, // 16 x i16
|
||||
v2i32 = 21, // 2 x i32
|
||||
v4i32 = 22, // 4 x i32
|
||||
v8i32 = 23, // 8 x i32
|
||||
v1i64 = 24, // 1 x i64
|
||||
v2i64 = 25, // 2 x i64
|
||||
v4i64 = 26, // 4 x i64
|
||||
v8i64 = 27, // 8 x i64
|
||||
v2i8 = 13, // 2 x i8
|
||||
v4i8 = 14, // 4 x i8
|
||||
v8i8 = 15, // 8 x i8
|
||||
v16i8 = 16, // 16 x i8
|
||||
v32i8 = 17, // 32 x i8
|
||||
v2i16 = 18, // 2 x i16
|
||||
v4i16 = 19, // 4 x i16
|
||||
v8i16 = 20, // 8 x i16
|
||||
v16i16 = 21, // 16 x i16
|
||||
v2i32 = 22, // 2 x i32
|
||||
v4i32 = 23, // 4 x i32
|
||||
v8i32 = 24, // 8 x i32
|
||||
v1i64 = 25, // 1 x i64
|
||||
v2i64 = 26, // 2 x i64
|
||||
v4i64 = 27, // 4 x i64
|
||||
v8i64 = 28, // 8 x i64
|
||||
|
||||
v2f32 = 28, // 2 x f32
|
||||
v4f32 = 29, // 4 x f32
|
||||
v8f32 = 30, // 8 x f32
|
||||
v2f64 = 31, // 2 x f64
|
||||
v4f64 = 32, // 4 x f64
|
||||
v2f32 = 29, // 2 x f32
|
||||
v4f32 = 30, // 4 x f32
|
||||
v8f32 = 31, // 8 x f32
|
||||
v2f64 = 32, // 2 x f64
|
||||
v4f64 = 33, // 4 x f64
|
||||
|
||||
FIRST_VECTOR_VALUETYPE = v2i8,
|
||||
LAST_VECTOR_VALUETYPE = v4f64,
|
||||
|
||||
x86mmx = 33, // This is an X86 MMX value
|
||||
x86mmx = 34, // This is an X86 MMX value
|
||||
|
||||
Glue = 34, // This glues nodes together during pre-RA sched
|
||||
Glue = 35, // This glues nodes together during pre-RA sched
|
||||
|
||||
isVoid = 35, // This has no value
|
||||
isVoid = 36, // This has no value
|
||||
|
||||
Untyped = 36, // This value takes a register, but has
|
||||
Untyped = 37, // This value takes a register, but has
|
||||
// unspecified type. The register class
|
||||
// will be determined by the opcode.
|
||||
|
||||
LAST_VALUETYPE = 37, // This always remains at the end of the list.
|
||||
LAST_VALUETYPE = 38, // This always remains at the end of the list.
|
||||
|
||||
// This is the current maximum for LAST_VALUETYPE.
|
||||
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
|
||||
@ -143,7 +144,7 @@ namespace llvm {
|
||||
|
||||
/// isFloatingPoint - Return true if this is a FP, or a vector FP type.
|
||||
bool isFloatingPoint() const {
|
||||
return ((SimpleTy >= MVT::f32 && SimpleTy <= MVT::ppcf128) ||
|
||||
return ((SimpleTy >= MVT::f16 && SimpleTy <= MVT::ppcf128) ||
|
||||
(SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64));
|
||||
}
|
||||
|
||||
@ -252,6 +253,7 @@ namespace llvm {
|
||||
case i1 : return 1;
|
||||
case i8 : return 8;
|
||||
case i16 :
|
||||
case f16:
|
||||
case v2i8: return 16;
|
||||
case f32 :
|
||||
case i32 :
|
||||
@ -301,6 +303,8 @@ namespace llvm {
|
||||
switch (BitWidth) {
|
||||
default:
|
||||
assert(false && "Bad bit width!");
|
||||
case 16:
|
||||
return MVT::f16;
|
||||
case 32:
|
||||
return MVT::f32;
|
||||
case 64:
|
||||
|
@ -26,39 +26,40 @@ def i16 : ValueType<16 , 3>; // 16-bit integer value
|
||||
def i32 : ValueType<32 , 4>; // 32-bit integer value
|
||||
def i64 : ValueType<64 , 5>; // 64-bit integer value
|
||||
def i128 : ValueType<128, 6>; // 128-bit integer value
|
||||
def f32 : ValueType<32 , 7>; // 32-bit floating point value
|
||||
def f64 : ValueType<64 , 8>; // 64-bit floating point value
|
||||
def f80 : ValueType<80 , 9>; // 80-bit floating point value
|
||||
def f128 : ValueType<128, 10>; // 128-bit floating point value
|
||||
def ppcf128: ValueType<128, 11>; // PPC 128-bit floating point value
|
||||
def f16 : ValueType<16 , 7>; // 32-bit floating point value
|
||||
def f32 : ValueType<32 , 8>; // 32-bit floating point value
|
||||
def f64 : ValueType<64 , 9>; // 64-bit floating point value
|
||||
def f80 : ValueType<80 , 10>; // 80-bit floating point value
|
||||
def f128 : ValueType<128, 11>; // 128-bit floating point value
|
||||
def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value
|
||||
|
||||
def v2i8 : ValueType<16 , 12>; // 2 x i8 vector value
|
||||
def v4i8 : ValueType<32 , 13>; // 4 x i8 vector value
|
||||
def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value
|
||||
def v16i8 : ValueType<128, 15>; // 16 x i8 vector value
|
||||
def v32i8 : ValueType<256, 16>; // 32 x i8 vector value
|
||||
def v2i16 : ValueType<32 , 17>; // 2 x i16 vector value
|
||||
def v4i16 : ValueType<64 , 18>; // 4 x i16 vector value
|
||||
def v8i16 : ValueType<128, 19>; // 8 x i16 vector value
|
||||
def v16i16 : ValueType<256, 20>; // 16 x i16 vector value
|
||||
def v2i32 : ValueType<64 , 21>; // 2 x i32 vector value
|
||||
def v4i32 : ValueType<128, 22>; // 4 x i32 vector value
|
||||
def v8i32 : ValueType<256, 23>; // 8 x i32 vector value
|
||||
def v1i64 : ValueType<64 , 24>; // 1 x i64 vector value
|
||||
def v2i64 : ValueType<128, 25>; // 2 x i64 vector value
|
||||
def v4i64 : ValueType<256, 26>; // 4 x i64 vector value
|
||||
def v8i64 : ValueType<512, 27>; // 8 x i64 vector value
|
||||
def v2i8 : ValueType<16 , 13>; // 2 x i8 vector value
|
||||
def v4i8 : ValueType<32 , 14>; // 4 x i8 vector value
|
||||
def v8i8 : ValueType<64 , 15>; // 8 x i8 vector value
|
||||
def v16i8 : ValueType<128, 16>; // 16 x i8 vector value
|
||||
def v32i8 : ValueType<256, 17>; // 32 x i8 vector value
|
||||
def v2i16 : ValueType<32 , 18>; // 2 x i16 vector value
|
||||
def v4i16 : ValueType<64 , 19>; // 4 x i16 vector value
|
||||
def v8i16 : ValueType<128, 20>; // 8 x i16 vector value
|
||||
def v16i16 : ValueType<256, 21>; // 16 x i16 vector value
|
||||
def v2i32 : ValueType<64 , 22>; // 2 x i32 vector value
|
||||
def v4i32 : ValueType<128, 23>; // 4 x i32 vector value
|
||||
def v8i32 : ValueType<256, 24>; // 8 x i32 vector value
|
||||
def v1i64 : ValueType<64 , 25>; // 1 x i64 vector value
|
||||
def v2i64 : ValueType<128, 26>; // 2 x i64 vector value
|
||||
def v4i64 : ValueType<256, 27>; // 4 x i64 vector value
|
||||
def v8i64 : ValueType<512, 28>; // 8 x i64 vector value
|
||||
|
||||
def v2f32 : ValueType<64 , 28>; // 2 x f32 vector value
|
||||
def v4f32 : ValueType<128, 29>; // 4 x f32 vector value
|
||||
def v8f32 : ValueType<256, 30>; // 8 x f32 vector value
|
||||
def v2f64 : ValueType<128, 31>; // 2 x f64 vector value
|
||||
def v4f64 : ValueType<256, 32>; // 4 x f64 vector value
|
||||
def v2f32 : ValueType<64 , 29>; // 2 x f32 vector value
|
||||
def v4f32 : ValueType<128, 30>; // 4 x f32 vector value
|
||||
def v8f32 : ValueType<256, 31>; // 8 x f32 vector value
|
||||
def v2f64 : ValueType<128, 32>; // 2 x f64 vector value
|
||||
def v4f64 : ValueType<256, 33>; // 4 x f64 vector value
|
||||
|
||||
def x86mmx : ValueType<64 , 33>; // X86 MMX value
|
||||
def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue
|
||||
def isVoid : ValueType<0 , 35>; // Produces no value
|
||||
def untyped: ValueType<8 , 36>; // Produces an untyped value
|
||||
def x86mmx : ValueType<64 , 34>; // X86 MMX value
|
||||
def FlagVT : ValueType<0 , 35>; // Pre-RA sched glue
|
||||
def isVoid : ValueType<0 , 36>; // Produces no value
|
||||
def untyped: ValueType<8 , 37>; // Produces an untyped value
|
||||
|
||||
def MetadataVT: ValueType<0, 250>; // Metadata
|
||||
|
||||
|
@ -1694,16 +1694,14 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
|
||||
|
||||
static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
|
||||
AsmPrinter &AP) {
|
||||
// FP Constants are printed as integer constants to avoid losing
|
||||
// precision.
|
||||
if (CFP->getType()->isDoubleTy()) {
|
||||
if (CFP->getType()->isHalfTy()) {
|
||||
if (AP.isVerbose()) {
|
||||
double Val = CFP->getValueAPF().convertToDouble();
|
||||
AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
|
||||
SmallString<10> Str;
|
||||
CFP->getValueAPF().toString(Str);
|
||||
AP.OutStreamer.GetCommentOS() << "half " << Str << '\n';
|
||||
}
|
||||
|
||||
uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
|
||||
AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
|
||||
AP.OutStreamer.EmitIntValue(Val, 2, AddrSpace);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1717,6 +1715,19 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
|
||||
return;
|
||||
}
|
||||
|
||||
// FP Constants are printed as integer constants to avoid losing
|
||||
// precision.
|
||||
if (CFP->getType()->isDoubleTy()) {
|
||||
if (AP.isVerbose()) {
|
||||
double Val = CFP->getValueAPF().convertToDouble();
|
||||
AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
|
||||
}
|
||||
|
||||
uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
|
||||
AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CFP->getType()->isX86_FP80Ty()) {
|
||||
// all long double variants are printed as hex
|
||||
// API needed to prevent premature destruction
|
||||
|
@ -572,21 +572,22 @@ TargetLowering::TargetLowering(const TargetMachine &tm,
|
||||
// ConstantFP nodes default to expand. Targets can either change this to
|
||||
// Legal, in which case all fp constants are legal, or use isFPImmLegal()
|
||||
// to optimize expansions for certain constants.
|
||||
setOperationAction(ISD::ConstantFP, MVT::f16, Expand);
|
||||
setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
|
||||
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
|
||||
setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
|
||||
|
||||
// These library functions default to expand.
|
||||
setOperationAction(ISD::FLOG , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FLOG2, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FLOG10, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FEXP , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FEXP2, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FFLOOR, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FNEARBYINT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCEIL, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FRINT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FTRUNC, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FLOG , MVT::f16, Expand);
|
||||
setOperationAction(ISD::FLOG2, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FLOG10, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FEXP , MVT::f16, Expand);
|
||||
setOperationAction(ISD::FEXP2, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FFLOOR, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FNEARBYINT, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FCEIL, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FRINT, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FTRUNC, MVT::f16, Expand);
|
||||
setOperationAction(ISD::FLOG , MVT::f32, Expand);
|
||||
setOperationAction(ISD::FLOG2, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FLOG10, MVT::f32, Expand);
|
||||
@ -597,6 +598,16 @@ TargetLowering::TargetLowering(const TargetMachine &tm,
|
||||
setOperationAction(ISD::FCEIL, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FRINT, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FTRUNC, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FLOG , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FLOG2, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FLOG10, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FEXP , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FEXP2, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FFLOOR, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FNEARBYINT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCEIL, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FRINT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FTRUNC, MVT::f64, Expand);
|
||||
|
||||
// Default ISD::TRAP to expand (which turns it into abort).
|
||||
setOperationAction(ISD::TRAP, MVT::Other, Expand);
|
||||
|
@ -147,6 +147,7 @@ void TargetData::init() {
|
||||
setAlignment(INTEGER_ALIGN, 2, 2, 16); // i16
|
||||
setAlignment(INTEGER_ALIGN, 4, 4, 32); // i32
|
||||
setAlignment(INTEGER_ALIGN, 4, 8, 64); // i64
|
||||
setAlignment(FLOAT_ALIGN, 2, 2, 16); // half
|
||||
setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
|
||||
setAlignment(FLOAT_ALIGN, 8, 8, 64); // double
|
||||
setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ...
|
||||
@ -477,6 +478,8 @@ uint64_t TargetData::getTypeSizeInBits(Type *Ty) const {
|
||||
return cast<IntegerType>(Ty)->getBitWidth();
|
||||
case Type::VoidTyID:
|
||||
return 8;
|
||||
case Type::HalfTyID:
|
||||
return 16;
|
||||
case Type::FloatTyID:
|
||||
return 32;
|
||||
case Type::DoubleTyID:
|
||||
@ -534,6 +537,7 @@ unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const {
|
||||
case Type::VoidTyID:
|
||||
AlignType = INTEGER_ALIGN;
|
||||
break;
|
||||
case Type::HalfTyID:
|
||||
case Type::FloatTyID:
|
||||
case Type::DoubleTyID:
|
||||
// PPC_FP128TyID and FP128TyID have different data contents, but the
|
||||
|
@ -108,6 +108,7 @@ std::string EVT::getEVTString() const {
|
||||
case MVT::i32: return "i32";
|
||||
case MVT::i64: return "i64";
|
||||
case MVT::i128: return "i128";
|
||||
case MVT::f16: return "f16";
|
||||
case MVT::f32: return "f32";
|
||||
case MVT::f64: return "f64";
|
||||
case MVT::f80: return "f80";
|
||||
@ -158,6 +159,7 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
|
||||
case MVT::i32: return Type::getInt32Ty(Context);
|
||||
case MVT::i64: return Type::getInt64Ty(Context);
|
||||
case MVT::i128: return IntegerType::get(Context, 128);
|
||||
case MVT::f16: return Type::getHalfTy(Context);
|
||||
case MVT::f32: return Type::getFloatTy(Context);
|
||||
case MVT::f64: return Type::getDoubleTy(Context);
|
||||
case MVT::f80: return Type::getX86_FP80Ty(Context);
|
||||
@ -202,6 +204,7 @@ EVT EVT::getEVT(Type *Ty, bool HandleUnknown){
|
||||
return MVT::isVoid;
|
||||
case Type::IntegerTyID:
|
||||
return getIntegerVT(Ty->getContext(), cast<IntegerType>(Ty)->getBitWidth());
|
||||
case Type::HalfTyID: return MVT(MVT::f16);
|
||||
case Type::FloatTyID: return MVT(MVT::f32);
|
||||
case Type::DoubleTyID: return MVT(MVT::f64);
|
||||
case Type::X86_FP80TyID: return MVT(MVT::f80);
|
||||
|
@ -58,6 +58,7 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
|
||||
case MVT::iAny: return "MVT::iAny";
|
||||
case MVT::fAny: return "MVT::fAny";
|
||||
case MVT::vAny: return "MVT::vAny";
|
||||
case MVT::f16: return "MVT::f16";
|
||||
case MVT::f32: return "MVT::f32";
|
||||
case MVT::f64: return "MVT::f64";
|
||||
case MVT::f80: return "MVT::f80";
|
||||
|
@ -181,6 +181,8 @@ static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
|
||||
} else if (VT == MVT::Other) {
|
||||
// MVT::OtherVT is used to mean the empty struct type here.
|
||||
OS << "StructType::get(Context)";
|
||||
} else if (VT == MVT::f16) {
|
||||
OS << "Type::getHalfTy(Context)";
|
||||
} else if (VT == MVT::f32) {
|
||||
OS << "Type::getFloatTy(Context)";
|
||||
} else if (VT == MVT::f64) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user