[llvm] fdd23a3 - [ms] [llvm-ml] Add REAL10 support (x87 extended precision)

Eric Astor via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 13:59:09 PDT 2020


Author: Eric Astor
Date: 2020-09-29T16:58:46-04:00
New Revision: fdd23a35422ca133410c6b066ea191f426267c46

URL: https://github.com/llvm/llvm-project/commit/fdd23a35422ca133410c6b066ea191f426267c46
DIFF: https://github.com/llvm/llvm-project/commit/fdd23a35422ca133410c6b066ea191f426267c46.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCStreamer.h
    llvm/lib/MC/MCParser/MasmParser.cpp
    llvm/lib/MC/MCStreamer.cpp
    llvm/test/tools/llvm-ml/builtin_types.test
    llvm/test/tools/llvm-ml/type_operators.test

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 63a4c1d190ac..8faa3b0c8efb 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -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 @@ class MCStreamer {
   /// 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

diff  --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index d0a52657d662..0d5d6a112902 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -634,6 +634,7 @@ class MasmParser : public MCAsmParser {
     DK_DW,
     DK_REAL4,
     DK_REAL8,
+    DK_REAL10,
     DK_ALIGN,
     DK_ORG,
     DK_ENDR,
@@ -771,7 +772,7 @@ class MasmParser : public MCAsmParser {
   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;

diff  --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 995828b57738..46aa0b89842c 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -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.

diff  --git a/llvm/test/tools/llvm-ml/builtin_types.test b/llvm/test/tools/llvm-ml/builtin_types.test
index f04e318b1b02..89ec1cfd0d71 100644
--- a/llvm/test/tools/llvm-ml/builtin_types.test
+++ b/llvm/test/tools/llvm-ml/builtin_types.test
@@ -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-NEXT: .quad 4608533498688228557
+; CHECK-LABEL: t6_single_hex:
+; CHECK-NEXT: .long 1067869798
 
-t7_single_hex REAL4 3f800000r
-t7_double_hex REAL8 3FF0000000000000R
+t7_double REAL8 1.3
+t7_double_hex REAL8 3FF4CCCCCCCCCCCDR
 
-; CHECK-LABEL: t7_single_hex:
-; CHECK-NEXT: .long 1065353216
+; CHECK-LABEL: t7_double:
+; CHECK-NEXT: .quad 4608533498688228557
 ; CHECK-LABEL: t7_double_hex:
-; CHECK-NEXT: .quad 4607182418800017408
+; CHECK-NEXT: .quad 4608533498688228557
+
+t8_extended REAL10 1.3
+t8_extended_hex REAL10 3FFFA666666666666666r
+
+; CHECK-LABEL: t8_extended:
+; CHECK-NEXT: .ascii "fffffff\246\377?"
+; CHECK-LABEL: t8_extended_hex:
+; CHECK-NEXT: .ascii "fffffff\246\377?"
 
 .code
 

diff  --git a/llvm/test/tools/llvm-ml/type_operators.test b/llvm/test/tools/llvm-ml/type_operators.test
index b8546927e3ef..7de6cdd9448e 100644
--- a/llvm/test/tools/llvm-ml/type_operators.test
+++ b/llvm/test/tools/llvm-ml/type_operators.test
@@ -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 <>, <>
 


        


More information about the llvm-commits mailing list