mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 16:17:17 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114719 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
@@ -178,6 +179,7 @@ private:
|
|||||||
// Directive Parsing.
|
// Directive Parsing.
|
||||||
bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
|
bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
|
||||||
bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
|
bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
|
||||||
|
bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
|
||||||
bool ParseDirectiveFill(); // ".fill"
|
bool ParseDirectiveFill(); // ".fill"
|
||||||
bool ParseDirectiveSpace(); // ".space"
|
bool ParseDirectiveSpace(); // ".space"
|
||||||
bool ParseDirectiveZero(); // ".zero"
|
bool ParseDirectiveZero(); // ".zero"
|
||||||
@@ -926,6 +928,10 @@ bool AsmParser::ParseStatement() {
|
|||||||
return ParseDirectiveValue(4);
|
return ParseDirectiveValue(4);
|
||||||
if (IDVal == ".quad")
|
if (IDVal == ".quad")
|
||||||
return ParseDirectiveValue(8);
|
return ParseDirectiveValue(8);
|
||||||
|
if (IDVal == ".single")
|
||||||
|
return ParseDirectiveRealValue(APFloat::IEEEsingle);
|
||||||
|
if (IDVal == ".double")
|
||||||
|
return ParseDirectiveRealValue(APFloat::IEEEdouble);
|
||||||
|
|
||||||
if (IDVal == ".align") {
|
if (IDVal == ".align") {
|
||||||
bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
|
bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
|
||||||
@@ -1409,6 +1415,56 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
|
|||||||
return false;
|
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
|
/// ParseDirectiveSpace
|
||||||
/// ::= .space expression [ , expression ]
|
/// ::= .space expression [ , expression ]
|
||||||
bool AsmParser::ParseDirectiveSpace() {
|
bool AsmParser::ParseDirectiveSpace() {
|
||||||
|
12
test/MC/AsmParser/floating-literals.s
Normal file
12
test/MC/AsmParser/floating-literals.s
Normal file
@@ -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
|
Reference in New Issue
Block a user