MC/AsmParser: Support .single and .double for embedding floating point literals.
- I believe more modern 'gas' supports a more enhanced set of arithmetic on them, but for now the only thing we can do is emit them as data. llvm-svn: 114719
This commit is contained in:
parent
3068a93dc1
commit
2af1653032
|
@ -11,6 +11,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
@ -178,6 +179,7 @@ private:
|
|||
// Directive Parsing.
|
||||
bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
|
||||
bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
|
||||
bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
|
||||
bool ParseDirectiveFill(); // ".fill"
|
||||
bool ParseDirectiveSpace(); // ".space"
|
||||
bool ParseDirectiveZero(); // ".zero"
|
||||
|
@ -926,6 +928,10 @@ bool AsmParser::ParseStatement() {
|
|||
return ParseDirectiveValue(4);
|
||||
if (IDVal == ".quad")
|
||||
return ParseDirectiveValue(8);
|
||||
if (IDVal == ".single")
|
||||
return ParseDirectiveRealValue(APFloat::IEEEsingle);
|
||||
if (IDVal == ".double")
|
||||
return ParseDirectiveRealValue(APFloat::IEEEdouble);
|
||||
|
||||
if (IDVal == ".align") {
|
||||
bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
|
||||
|
@ -1409,6 +1415,56 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ParseDirectiveRealValue
|
||||
/// ::= (.single | .double) [ expression (, expression)* ]
|
||||
bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
CheckForValidSection();
|
||||
|
||||
for (;;) {
|
||||
// We don't truly support arithmetic on floating point expressions, so we
|
||||
// have to manually parse unary prefixes.
|
||||
bool IsNeg = false;
|
||||
if (getLexer().is(AsmToken::Minus)) {
|
||||
Lex();
|
||||
IsNeg = true;
|
||||
} else if (getLexer().is(AsmToken::Plus))
|
||||
Lex();
|
||||
|
||||
if (getLexer().isNot(AsmToken::Integer) &&
|
||||
getLexer().isNot(AsmToken::Real))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
// Convert to an APFloat.
|
||||
APFloat Value(Semantics);
|
||||
if (Value.convertFromString(getTok().getString(),
|
||||
APFloat::rmNearestTiesToEven) ==
|
||||
APFloat::opInvalidOp)
|
||||
return TokError("invalid floating point literal");
|
||||
if (IsNeg)
|
||||
Value.changeSign();
|
||||
|
||||
// Consume the numeric token.
|
||||
Lex();
|
||||
|
||||
// Emit the value as an integer.
|
||||
APInt AsInt = Value.bitcastToAPInt();
|
||||
getStreamer().EmitIntValue(AsInt.getLimitedValue(),
|
||||
AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE);
|
||||
|
||||
if (getLexer().is(AsmToken::EndOfStatement))
|
||||
break;
|
||||
|
||||
if (getLexer().isNot(AsmToken::Comma))
|
||||
return TokError("unexpected token in directive");
|
||||
Lex();
|
||||
}
|
||||
}
|
||||
|
||||
Lex();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseDirectiveSpace
|
||||
/// ::= .space expression [ , expression ]
|
||||
bool AsmParser::ParseDirectiveSpace() {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
|
||||
|
||||
# CHECK: .long 1067412619
|
||||
# CHECK: .long 1075000115
|
||||
# CHECK: .long 1077936128
|
||||
# CHECK: .long 1082549862
|
||||
.single 1.2455, +2.3, 3, + 4.2
|
||||
|
||||
# CHECK: .quad 4617315517961601024
|
||||
# CHECK: .quad 4597526701198935065
|
||||
# CHECK: .quad -4600933674317040845
|
||||
.double 5, .232, -11.1
|
Loading…
Reference in New Issue