mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[ms] [llvm-ml] Add REAL10 support (x87 extended precision)
Add MASM support for 80-bit reals in the x87 extended precision format. Reviewed By: thakis Differential Revision: https://reviews.llvm.org/D87402
This commit is contained in:
parent
95792b92ea
commit
91cac48098
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_MC_MCSTREAMER_H
|
||||
#define LLVM_MC_MCSTREAMER_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
@ -673,6 +674,7 @@ public:
|
||||
/// Special case of EmitValue that avoids the client having
|
||||
/// to pass in a MCExpr for constant integers.
|
||||
virtual void emitIntValue(uint64_t Value, unsigned Size);
|
||||
virtual void emitIntValue(APInt Value);
|
||||
|
||||
/// Special case of EmitValue that avoids the client having to pass
|
||||
/// in a MCExpr for constant integers & prints in Hex format for certain
|
||||
|
@ -634,6 +634,7 @@ private:
|
||||
DK_DW,
|
||||
DK_REAL4,
|
||||
DK_REAL8,
|
||||
DK_REAL10,
|
||||
DK_ALIGN,
|
||||
DK_ORG,
|
||||
DK_ENDR,
|
||||
@ -771,7 +772,7 @@ private:
|
||||
bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
|
||||
StringRef Name, SMLoc NameLoc);
|
||||
|
||||
// "real4", "real8"
|
||||
// "real4", "real8", "real10"
|
||||
bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
|
||||
bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
|
||||
bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
|
||||
@ -2147,6 +2148,8 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
|
||||
return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
|
||||
case DK_REAL8:
|
||||
return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
|
||||
case DK_REAL10:
|
||||
return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
|
||||
case DK_STRUCT:
|
||||
case DK_UNION:
|
||||
return parseDirectiveNestedStruct(IDVal, DirKind);
|
||||
@ -2382,6 +2385,10 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
|
||||
Lex();
|
||||
return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
|
||||
IDVal, IDLoc);
|
||||
case DK_REAL10:
|
||||
Lex();
|
||||
return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
|
||||
10, IDVal, IDLoc);
|
||||
case DK_STRUCT:
|
||||
case DK_UNION:
|
||||
Lex();
|
||||
@ -3456,14 +3463,14 @@ bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
|
||||
} else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
|
||||
// MASM hexadecimal floating-point literal; no APFloat conversion needed.
|
||||
// To match ML64.exe, ignore the initial sign.
|
||||
unsigned Size = Value.getSizeInBits(Semantics);
|
||||
if (Size != (IDVal.size() << 2))
|
||||
unsigned SizeInBits = Value.getSizeInBits(Semantics);
|
||||
if (SizeInBits != (IDVal.size() << 2))
|
||||
return TokError("invalid floating point literal");
|
||||
|
||||
// Consume the numeric token.
|
||||
Lex();
|
||||
|
||||
Res = APInt(Size, IDVal, 16);
|
||||
Res = APInt(SizeInBits, IDVal, 16);
|
||||
if (SignLoc.isValid())
|
||||
return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
|
||||
return false;
|
||||
@ -3540,8 +3547,7 @@ bool MasmParser::emitRealValues(const fltSemantics &Semantics,
|
||||
return true;
|
||||
|
||||
for (const APInt &AsInt : ValuesAsInt) {
|
||||
getStreamer().emitIntValue(AsInt.getLimitedValue(),
|
||||
AsInt.getBitWidth() / 8);
|
||||
getStreamer().emitIntValue(AsInt);
|
||||
}
|
||||
if (Count)
|
||||
*Count = ValuesAsInt.size();
|
||||
@ -3571,7 +3577,7 @@ bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
|
||||
}
|
||||
|
||||
/// parseDirectiveRealValue
|
||||
/// ::= (real4 | real8) [ expression (, expression)* ]
|
||||
/// ::= (real4 | real8 | real10) [ expression (, expression)* ]
|
||||
bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
|
||||
const fltSemantics &Semantics,
|
||||
size_t Size) {
|
||||
@ -3586,7 +3592,7 @@ bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
|
||||
}
|
||||
|
||||
/// parseDirectiveNamedRealValue
|
||||
/// ::= name (real4 | real8) [ expression (, expression)* ]
|
||||
/// ::= name (real4 | real8 | real10) [ expression (, expression)* ]
|
||||
bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
|
||||
const fltSemantics &Semantics,
|
||||
unsigned Size, StringRef Name,
|
||||
@ -3680,8 +3686,20 @@ bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
|
||||
bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
|
||||
const RealFieldInfo &Contents,
|
||||
FieldInitializer &Initializer) {
|
||||
const fltSemantics &Semantics =
|
||||
(Field.Type == 4) ? APFloat::IEEEsingle() : APFloat::IEEEdouble();
|
||||
const fltSemantics *Semantics;
|
||||
switch (Field.Type) {
|
||||
case 4:
|
||||
Semantics = &APFloat::IEEEsingle();
|
||||
break;
|
||||
case 8:
|
||||
Semantics = &APFloat::IEEEdouble();
|
||||
break;
|
||||
case 10:
|
||||
Semantics = &APFloat::x87DoubleExtended();
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unknown real field type");
|
||||
}
|
||||
|
||||
SMLoc Loc = getTok().getLoc();
|
||||
|
||||
@ -3689,20 +3707,20 @@ bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
|
||||
if (parseOptionalToken(AsmToken::LCurly)) {
|
||||
if (Field.LengthOf == 1)
|
||||
return Error(Loc, "Cannot initialize scalar field with array value");
|
||||
if (parseRealInstList(Semantics, AsIntValues, AsmToken::RCurly) ||
|
||||
if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
|
||||
parseToken(AsmToken::RCurly))
|
||||
return true;
|
||||
} else if (parseOptionalAngleBracketOpen()) {
|
||||
if (Field.LengthOf == 1)
|
||||
return Error(Loc, "Cannot initialize scalar field with array value");
|
||||
if (parseRealInstList(Semantics, AsIntValues, AsmToken::Greater) ||
|
||||
if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
|
||||
parseAngleBracketClose())
|
||||
return true;
|
||||
} else if (Field.LengthOf > 1) {
|
||||
return Error(Loc, "Cannot initialize array field with scalar value");
|
||||
} else {
|
||||
AsIntValues.emplace_back();
|
||||
if (parseRealValue(Semantics, AsIntValues.back()))
|
||||
if (parseRealValue(*Semantics, AsIntValues.back()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -6278,6 +6296,7 @@ void MasmParser::initializeDirectiveKindMap() {
|
||||
DirectiveKindMap["sqword"] = DK_SQWORD;
|
||||
DirectiveKindMap["real4"] = DK_REAL4;
|
||||
DirectiveKindMap["real8"] = DK_REAL8;
|
||||
DirectiveKindMap["real10"] = DK_REAL10;
|
||||
DirectiveKindMap["align"] = DK_ALIGN;
|
||||
// DirectiveKindMap[".org"] = DK_ORG;
|
||||
DirectiveKindMap["extern"] = DK_EXTERN;
|
||||
@ -6732,6 +6751,7 @@ bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
|
||||
.CasesLower("qword", "dq", "sqword", 8)
|
||||
.CaseLower("real4", 4)
|
||||
.CaseLower("real8", 8)
|
||||
.CaseLower("real10", 10)
|
||||
.Default(0);
|
||||
if (Size) {
|
||||
Info.Name = Name;
|
||||
|
@ -138,6 +138,21 @@ void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
|
||||
unsigned Index = IsLittleEndian ? 0 : 8 - Size;
|
||||
emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
|
||||
}
|
||||
void MCStreamer::emitIntValue(APInt Value) {
|
||||
if (Value.getNumWords() == 1) {
|
||||
emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
|
||||
const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
|
||||
const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
|
||||
const unsigned Size = Value.getBitWidth() / 8;
|
||||
SmallString<10> Tmp;
|
||||
Tmp.resize(Size);
|
||||
StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
|
||||
emitBytes(Tmp.str());
|
||||
}
|
||||
|
||||
/// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
|
||||
/// client having to pass in a MCExpr for constant integers.
|
||||
|
@ -65,20 +65,28 @@ t5_signed SQWORD -4611686018427387904
|
||||
; CHECK-NEXT: .quad -4611686018427387904
|
||||
|
||||
t6_single REAL4 1.3
|
||||
t6_double REAL8 1.3
|
||||
t6_single_hex REAL4 3fa66666r
|
||||
|
||||
; CHECK-LABEL: t6_single:
|
||||
; CHECK-NEXT: .long 1067869798
|
||||
; CHECK-LABEL: t6_double:
|
||||
; CHECK-LABEL: t6_single_hex:
|
||||
; CHECK-NEXT: .long 1067869798
|
||||
|
||||
t7_double REAL8 1.3
|
||||
t7_double_hex REAL8 3FF4CCCCCCCCCCCDR
|
||||
|
||||
; CHECK-LABEL: t7_double:
|
||||
; CHECK-NEXT: .quad 4608533498688228557
|
||||
; CHECK-LABEL: t7_double_hex:
|
||||
; CHECK-NEXT: .quad 4608533498688228557
|
||||
|
||||
t7_single_hex REAL4 3f800000r
|
||||
t7_double_hex REAL8 3FF0000000000000R
|
||||
t8_extended REAL10 1.3
|
||||
t8_extended_hex REAL10 3FFFA666666666666666r
|
||||
|
||||
; CHECK-LABEL: t7_single_hex:
|
||||
; CHECK-NEXT: .long 1065353216
|
||||
; CHECK-LABEL: t7_double_hex:
|
||||
; CHECK-NEXT: .quad 4607182418800017408
|
||||
; CHECK-LABEL: t8_extended:
|
||||
; CHECK-NEXT: .ascii "fffffff\246\377?"
|
||||
; CHECK-LABEL: t8_extended_hex:
|
||||
; CHECK-NEXT: .ascii "fffffff\246\377?"
|
||||
|
||||
.code
|
||||
|
||||
|
@ -196,6 +196,7 @@ mov eax, type(t6_signed)
|
||||
|
||||
t7_single REAL4 2 DUP (?)
|
||||
t7_double REAL8 ?
|
||||
t7_extended REAL10 3 DUP (?)
|
||||
|
||||
t7:
|
||||
; CHECK-LABEL: t7:
|
||||
@ -214,6 +215,13 @@ mov eax, type(t7_double)
|
||||
; CHECK: mov eax, 1
|
||||
; CHECK: mov eax, 8
|
||||
|
||||
mov eax, sizeof(t7_extended)
|
||||
mov eax, lengthof(t7_extended)
|
||||
mov eax, type(t7_extended)
|
||||
; CHECK: mov eax, 30
|
||||
; CHECK: mov eax, 3
|
||||
; CHECK: mov eax, 10
|
||||
|
||||
|
||||
t8_var FOO <>, <>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user