15
15
#include " MCTargetDesc/X86TargetStreamer.h"
16
16
#include " TargetInfo/X86TargetInfo.h"
17
17
#include " X86Operand.h"
18
+ #include " X86RegisterInfo.h"
18
19
#include " llvm-c/Visibility.h"
19
20
#include " llvm/ADT/STLExtras.h"
20
21
#include " llvm/ADT/SmallString.h"
21
22
#include " llvm/ADT/SmallVector.h"
23
+ #include " llvm/ADT/StringRef.h"
22
24
#include " llvm/ADT/StringSwitch.h"
23
25
#include " llvm/ADT/Twine.h"
24
26
#include " llvm/MC/MCContext.h"
29
31
#include " llvm/MC/MCParser/MCAsmParser.h"
30
32
#include " llvm/MC/MCParser/MCParsedAsmOperand.h"
31
33
#include " llvm/MC/MCParser/MCTargetAsmParser.h"
34
+ #include " llvm/MC/MCRegister.h"
32
35
#include " llvm/MC/MCRegisterInfo.h"
33
36
#include " llvm/MC/MCSection.h"
34
37
#include " llvm/MC/MCStreamer.h"
40
43
#include " llvm/Support/SourceMgr.h"
41
44
#include " llvm/Support/raw_ostream.h"
42
45
#include < algorithm>
46
+ #include < cstdint>
43
47
#include < memory>
44
48
45
49
using namespace llvm ;
@@ -1172,7 +1176,7 @@ class X86AsmParser : public MCTargetAsmParser {
1172
1176
1173
1177
X86::CondCode ParseConditionCode (StringRef CCode);
1174
1178
1175
- bool ParseIntelMemoryOperandSize (unsigned &Size);
1179
+ bool ParseIntelMemoryOperandSize (unsigned &Size, StringRef *SizeStr );
1176
1180
bool CreateMemForMSInlineAsm (MCRegister SegReg, const MCExpr *Disp,
1177
1181
MCRegister BaseReg, MCRegister IndexReg,
1178
1182
unsigned Scale, bool NonAbsMem, SMLoc Start,
@@ -2574,7 +2578,8 @@ bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
2574
2578
return false ;
2575
2579
}
2576
2580
2577
- bool X86AsmParser::ParseIntelMemoryOperandSize (unsigned &Size) {
2581
+ bool X86AsmParser::ParseIntelMemoryOperandSize (unsigned &Size,
2582
+ StringRef *SizeStr) {
2578
2583
Size = StringSwitch<unsigned >(getTok ().getString ())
2579
2584
.Cases (" BYTE" , " byte" , 8 )
2580
2585
.Cases (" WORD" , " word" , 16 )
@@ -2592,6 +2597,8 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
2592
2597
.Cases (" ZMMWORD" , " zmmword" , 512 )
2593
2598
.Default (0 );
2594
2599
if (Size) {
2600
+ if (SizeStr)
2601
+ *SizeStr = getTok ().getString ();
2595
2602
const AsmToken &Tok = Lex (); // Eat operand size (e.g., byte, word).
2596
2603
if (!(Tok.getString () == " PTR" || Tok.getString () == " ptr" ))
2597
2604
return Error (Tok.getLoc (), " Expected 'PTR' or 'ptr' token!" );
@@ -2600,14 +2607,28 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
2600
2607
return false ;
2601
2608
}
2602
2609
2610
+ uint16_t RegSizeInBits (const MCRegisterInfo &MRI, MCRegister RegNo) {
2611
+ if (X86MCRegisterClasses[X86::GR8RegClassID].contains (RegNo))
2612
+ return 8 ;
2613
+ if (X86MCRegisterClasses[X86::GR16RegClassID].contains (RegNo))
2614
+ return 16 ;
2615
+ if (X86MCRegisterClasses[X86::GR32RegClassID].contains (RegNo))
2616
+ return 32 ;
2617
+ if (X86MCRegisterClasses[X86::GR64RegClassID].contains (RegNo))
2618
+ return 64 ;
2619
+ // Unknown register size
2620
+ return 0 ;
2621
+ }
2622
+
2603
2623
bool X86AsmParser::parseIntelOperand (OperandVector &Operands, StringRef Name) {
2604
2624
MCAsmParser &Parser = getParser ();
2605
2625
const AsmToken &Tok = Parser.getTok ();
2606
2626
SMLoc Start, End;
2607
2627
2608
2628
// Parse optional Size directive.
2609
2629
unsigned Size;
2610
- if (ParseIntelMemoryOperandSize (Size))
2630
+ StringRef SizeStr;
2631
+ if (ParseIntelMemoryOperandSize (Size, &SizeStr))
2611
2632
return true ;
2612
2633
bool PtrInOperand = bool (Size);
2613
2634
@@ -2624,9 +2645,29 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
2624
2645
return Error (Start, " rip can only be used as a base register" );
2625
2646
// A Register followed by ':' is considered a segment override
2626
2647
if (Tok.isNot (AsmToken::Colon)) {
2627
- if (PtrInOperand)
2628
- return Error (Start, " expected memory operand after 'ptr', "
2629
- " found register operand instead" );
2648
+ if (PtrInOperand) {
2649
+ if (!Parser.isParsingMasm ())
2650
+ return Error (Start, " expected memory operand after 'ptr', "
2651
+ " found register operand instead" );
2652
+
2653
+ // If we are parsing MASM, we are allowed to cast registers to their own
2654
+ // sizes, but not to other types.
2655
+ uint16_t RegSize =
2656
+ RegSizeInBits (*getContext ().getRegisterInfo (), RegNo);
2657
+ if (RegSize == 0 )
2658
+ return Error (
2659
+ Start,
2660
+ " cannot cast register '" +
2661
+ StringRef (getContext ().getRegisterInfo ()->getName (RegNo)) +
2662
+ " '; its size is not easily defined." );
2663
+ if (RegSize != Size)
2664
+ return Error (
2665
+ Start,
2666
+ std::to_string (RegSize) + " -bit register '" +
2667
+ StringRef (getContext ().getRegisterInfo ()->getName (RegNo)) +
2668
+ " ' cannot be used as a " + std::to_string (Size) + " -bit " +
2669
+ SizeStr.upper ());
2670
+ }
2630
2671
Operands.push_back (X86Operand::CreateReg (RegNo, Start, End));
2631
2672
return false ;
2632
2673
}
0 commit comments