@@ -482,12 +482,25 @@ class MasmParser : public MCAsmParser {
482
482
// / Codeview def_range types parsed by this class.
483
483
StringMap<CVDefRangeType> CVDefRangeTypeMap;
484
484
485
+ bool parseInitValue (unsigned Size);
486
+
485
487
// ".ascii", ".asciz", ".string"
486
488
bool parseDirectiveAscii (StringRef IDVal, bool ZeroTerminated);
487
- bool parseDirectiveValue (StringRef IDVal,
488
- unsigned Size); // "byte", "word", ...
489
- bool parseDirectiveRealValue (StringRef IDVal,
490
- const fltSemantics &); // "real4", ...
489
+
490
+ // "byte", "word", ...
491
+ bool parseScalarInstList (unsigned Size,
492
+ SmallVectorImpl<const MCExpr *> &Values);
493
+ bool parseDirectiveValue (StringRef IDVal, unsigned Size);
494
+ bool parseDirectiveNamedValue (StringRef IDVal, unsigned Size, StringRef Name,
495
+ SMLoc NameLoc);
496
+
497
+ // "real4", "real8"
498
+ bool parseDirectiveRealValue (StringRef IDVal, const fltSemantics &Semantics);
499
+ bool parseRealInstList (const fltSemantics &Semantics,
500
+ SmallVectorImpl<APInt> &Values);
501
+ bool parseDirectiveNamedRealValue (StringRef IDVal,
502
+ const fltSemantics &Semantics,
503
+ StringRef Name, SMLoc NameLoc);
491
504
492
505
// "=", "equ", "textequ"
493
506
bool parseDirectiveEquate (StringRef IDVal, StringRef Name,
@@ -1903,6 +1916,33 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
1903
1916
case DK_TEXTEQU:
1904
1917
Lex ();
1905
1918
return parseDirectiveEquate (nextVal, IDVal, DirKind);
1919
+ case DK_BYTE:
1920
+ case DK_DB:
1921
+ Lex ();
1922
+ return parseDirectiveNamedValue (nextVal, 1 , IDVal, IDLoc);
1923
+ case DK_WORD:
1924
+ case DK_DW:
1925
+ Lex ();
1926
+ return parseDirectiveNamedValue (nextVal, 2 , IDVal, IDLoc);
1927
+ case DK_DWORD:
1928
+ case DK_DD:
1929
+ Lex ();
1930
+ return parseDirectiveNamedValue (nextVal, 4 , IDVal, IDLoc);
1931
+ case DK_FWORD:
1932
+ Lex ();
1933
+ return parseDirectiveNamedValue (nextVal, 6 , IDVal, IDLoc);
1934
+ case DK_QWORD:
1935
+ case DK_DQ:
1936
+ Lex ();
1937
+ return parseDirectiveNamedValue (nextVal, 8 , IDVal, IDLoc);
1938
+ case DK_REAL4:
1939
+ Lex ();
1940
+ return parseDirectiveNamedRealValue (nextVal, APFloat::IEEEsingle (), IDVal,
1941
+ IDLoc);
1942
+ case DK_REAL8:
1943
+ Lex ();
1944
+ return parseDirectiveNamedRealValue (nextVal, APFloat::IEEEdouble (), IDVal,
1945
+ IDLoc);
1906
1946
}
1907
1947
1908
1948
// __asm _emit or __asm __emit
@@ -2739,31 +2779,99 @@ bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
2739
2779
return false ;
2740
2780
}
2741
2781
2782
+ bool MasmParser::parseScalarInstList (unsigned Size,
2783
+ SmallVectorImpl<const MCExpr *> &Values) {
2784
+ do {
2785
+ if (getTok ().is (AsmToken::String)) {
2786
+ StringRef Value = getTok ().getStringContents ();
2787
+ if (Size == 1 ) {
2788
+ // Treat each character as an initializer.
2789
+ for (const char CharVal : Value)
2790
+ Values.push_back (MCConstantExpr::create (CharVal, getContext ()));
2791
+ } else {
2792
+ // Treat the string as an initial value in big-endian representation.
2793
+ if (Value.size () > Size)
2794
+ return Error (getTok ().getLoc (), " out of range literal value" );
2795
+
2796
+ uint64_t IntValue = 0 ;
2797
+ for (const unsigned char CharVal : Value.bytes ())
2798
+ IntValue = (IntValue << 8 ) | CharVal;
2799
+ Values.push_back (MCConstantExpr::create (IntValue, getContext ()));
2800
+ }
2801
+ Lex ();
2802
+ } else {
2803
+ const MCExpr *Value;
2804
+ if (checkForValidSection () || parseExpression (Value))
2805
+ return true ;
2806
+ if (getTok ().is (AsmToken::Identifier) &&
2807
+ getTok ().getString ().equals_lower (" dup" )) {
2808
+ Lex (); // eat 'dup'
2809
+ const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
2810
+ if (!MCE)
2811
+ return Error (Value->getLoc (),
2812
+ " cannot repeat value a non-constant number of times" );
2813
+ const int64_t Repetitions = MCE->getValue ();
2814
+ if (Repetitions < 0 )
2815
+ return Error (Value->getLoc (),
2816
+ " cannot repeat value a negative number of times" );
2817
+
2818
+ SmallVector<const MCExpr *, 1 > DuplicatedValues;
2819
+ if (parseToken (AsmToken::LParen,
2820
+ " parentheses required for 'dup' contents" ) ||
2821
+ parseScalarInstList (Size, DuplicatedValues) ||
2822
+ parseToken (AsmToken::RParen, " unmatched parentheses" ))
2823
+ return true ;
2824
+
2825
+ for (int i = 0 ; i < Repetitions; ++i)
2826
+ Values.append (DuplicatedValues.begin (), DuplicatedValues.end ());
2827
+ } else {
2828
+ Values.push_back (Value);
2829
+ }
2830
+ }
2831
+
2832
+ // Continue if we see a comma. (Also, allow line continuation.)
2833
+ } while (parseOptionalToken (AsmToken::Comma) &&
2834
+ (getTok ().isNot (AsmToken::EndOfStatement) ||
2835
+ !parseToken (AsmToken::EndOfStatement)));
2836
+
2837
+ return false ;
2838
+ }
2839
+
2742
2840
// / parseDirectiveValue
2743
2841
// / ::= (byte | word | ... ) [ expression (, expression)* ]
2744
2842
bool MasmParser::parseDirectiveValue (StringRef IDVal, unsigned Size) {
2745
- auto parseOp = [&]() -> bool {
2746
- const MCExpr *Value;
2747
- SMLoc ExprLoc = getLexer (). getLoc ( );
2748
- if ( checkForValidSection () || parseExpression (Value))
2749
- return true ;
2843
+ SmallVector< const MCExpr *, 1 > Values;
2844
+ if ( parseScalarInstList (Size, Values))
2845
+ return addErrorSuffix ( " in ' " + Twine (IDVal) + " ' directive " );
2846
+
2847
+ for ( const MCExpr *Value : Values) {
2750
2848
// Special case constant expressions to match code generator.
2751
2849
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
2752
2850
assert (Size <= 8 && " Invalid size" );
2753
2851
int64_t IntValue = MCE->getValue ();
2754
2852
if (!isUIntN (8 * Size, IntValue) && !isIntN (8 * Size, IntValue))
2755
- return Error (ExprLoc , " out of range literal value" );
2853
+ return Error (MCE-> getLoc () , " out of range literal value" );
2756
2854
getStreamer ().emitIntValue (IntValue, Size);
2757
- } else
2758
- getStreamer ().emitValue (Value, Size, ExprLoc);
2759
- return false ;
2760
- };
2761
-
2762
- if (parseMany (parseOp))
2763
- return addErrorSuffix (" in '" + Twine (IDVal) + " ' directive" );
2855
+ } else if (const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value);
2856
+ MSE && MSE->getSymbol ().getName () == " ?" ) {
2857
+ // ? initializer; treat as 0.
2858
+ getStreamer ().emitIntValue (0 , Size);
2859
+ } else {
2860
+ getStreamer ().emitValue (Value, Size, Value->getLoc ());
2861
+ }
2862
+ }
2764
2863
return false ;
2765
2864
}
2766
2865
2866
+ // / parseDirectiveNamedValue
2867
+ // / ::= name (byte | word | ... ) [ expression (, expression)* ]
2868
+ bool MasmParser::parseDirectiveNamedValue (StringRef IDVal, unsigned Size,
2869
+ StringRef Name, SMLoc NameLoc) {
2870
+ MCSymbol *Sym = getContext ().getOrCreateSymbol (Name);
2871
+ getStreamer ().emitLabel (Sym);
2872
+ return parseDirectiveValue (IDVal, Size);
2873
+ }
2874
+
2767
2875
static bool parseHexOcta (MasmParser &Asm, uint64_t &hi, uint64_t &lo) {
2768
2876
if (Asm.getTok ().isNot (AsmToken::Integer) &&
2769
2877
Asm.getTok ().isNot (AsmToken::BigNum))
@@ -2824,24 +2932,75 @@ bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
2824
2932
return false ;
2825
2933
}
2826
2934
2935
+ bool MasmParser::parseRealInstList (const fltSemantics &Semantics,
2936
+ SmallVectorImpl<APInt> &ValuesAsInt) {
2937
+ do {
2938
+ const AsmToken NextTok = Lexer.peekTok ();
2939
+ if (NextTok.is (AsmToken::Identifier) &&
2940
+ NextTok.getString ().equals_lower (" dup" )) {
2941
+ const MCExpr *Value;
2942
+ if (parseExpression (Value) || parseToken (AsmToken::Identifier))
2943
+ return true ;
2944
+ const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
2945
+ if (!MCE)
2946
+ return Error (Value->getLoc (),
2947
+ " cannot repeat value a non-constant number of times" );
2948
+ const int64_t Repetitions = MCE->getValue ();
2949
+ if (Repetitions < 0 )
2950
+ return Error (Value->getLoc (),
2951
+ " cannot repeat value a negative number of times" );
2952
+
2953
+ SmallVector<APInt, 1 > DuplicatedValues;
2954
+ if (parseToken (AsmToken::LParen,
2955
+ " parentheses required for 'dup' contents" ) ||
2956
+ parseRealInstList (Semantics, DuplicatedValues) ||
2957
+ parseToken (AsmToken::RParen, " unmatched parentheses" ))
2958
+ return true ;
2959
+
2960
+ for (int i = 0 ; i < Repetitions; ++i)
2961
+ ValuesAsInt.append (DuplicatedValues.begin (), DuplicatedValues.end ());
2962
+ } else {
2963
+ APInt AsInt;
2964
+ if (parseRealValue (Semantics, AsInt))
2965
+ return true ;
2966
+ ValuesAsInt.push_back (AsInt);
2967
+ }
2968
+ // Continue if we see a comma. (Also, allow line continuation.)
2969
+ } while (parseOptionalToken (AsmToken::Comma) &&
2970
+ (getTok ().isNot (AsmToken::EndOfStatement) ||
2971
+ !parseToken (AsmToken::EndOfStatement)));
2972
+
2973
+ return false ;
2974
+ }
2975
+
2827
2976
// / parseDirectiveRealValue
2828
2977
// / ::= (real4 | real8) [ expression (, expression)* ]
2829
2978
bool MasmParser::parseDirectiveRealValue (StringRef IDVal,
2830
2979
const fltSemantics &Semantics) {
2831
- auto parseOp = [&]() -> bool {
2832
- APInt AsInt;
2833
- if (checkForValidSection () || parseRealValue (Semantics, AsInt))
2834
- return true ;
2835
- getStreamer ().emitIntValue (AsInt.getLimitedValue (),
2836
- AsInt.getBitWidth () / 8 );
2837
- return false ;
2838
- };
2980
+ if (checkForValidSection ())
2981
+ return true ;
2839
2982
2840
- if (parseMany (parseOp))
2983
+ SmallVector<APInt, 1 > ValuesAsInt;
2984
+ if (parseRealInstList (Semantics, ValuesAsInt))
2841
2985
return addErrorSuffix (" in '" + Twine (IDVal) + " ' directive" );
2986
+
2987
+ for (const APInt &AsInt : ValuesAsInt) {
2988
+ getStreamer ().emitIntValue (AsInt.getLimitedValue (),
2989
+ AsInt.getBitWidth () / 8 );
2990
+ }
2842
2991
return false ;
2843
2992
}
2844
2993
2994
+ // / parseDirectiveNamedRealValue
2995
+ // / ::= name (real4 | real8) [ expression (, expression)* ]
2996
+ bool MasmParser::parseDirectiveNamedRealValue (StringRef IDVal,
2997
+ const fltSemantics &Semantics,
2998
+ StringRef Name, SMLoc NameLoc) {
2999
+ MCSymbol *Sym = getContext ().getOrCreateSymbol (Name);
3000
+ getStreamer ().emitLabel (Sym);
3001
+ return parseDirectiveRealValue (IDVal, Semantics);
3002
+ }
3003
+
2845
3004
// / parseDirectiveOrg
2846
3005
// / ::= .org expression [ , expression ]
2847
3006
bool MasmParser::parseDirectiveOrg () {
0 commit comments