1515#include " MCTargetDesc/X86TargetStreamer.h"
1616#include " TargetInfo/X86TargetInfo.h"
1717#include " X86Operand.h"
18+ #include " X86RegisterInfo.h"
1819#include " llvm-c/Visibility.h"
1920#include " llvm/ADT/STLExtras.h"
2021#include " llvm/ADT/SmallString.h"
2122#include " llvm/ADT/SmallVector.h"
23+ #include " llvm/ADT/StringRef.h"
2224#include " llvm/ADT/StringSwitch.h"
2325#include " llvm/ADT/Twine.h"
2426#include " llvm/MC/MCContext.h"
2931#include " llvm/MC/MCParser/MCAsmParser.h"
3032#include " llvm/MC/MCParser/MCParsedAsmOperand.h"
3133#include " llvm/MC/MCParser/MCTargetAsmParser.h"
34+ #include " llvm/MC/MCRegister.h"
3235#include " llvm/MC/MCRegisterInfo.h"
3336#include " llvm/MC/MCSection.h"
3437#include " llvm/MC/MCStreamer.h"
4043#include " llvm/Support/SourceMgr.h"
4144#include " llvm/Support/raw_ostream.h"
4245#include < algorithm>
46+ #include < cstdint>
4347#include < memory>
4448
4549using namespace llvm ;
@@ -1172,7 +1176,7 @@ class X86AsmParser : public MCTargetAsmParser {
11721176
11731177 X86::CondCode ParseConditionCode (StringRef CCode);
11741178
1175- bool ParseIntelMemoryOperandSize (unsigned &Size);
1179+ bool ParseIntelMemoryOperandSize (unsigned &Size, StringRef *SizeStr );
11761180 bool CreateMemForMSInlineAsm (MCRegister SegReg, const MCExpr *Disp,
11771181 MCRegister BaseReg, MCRegister IndexReg,
11781182 unsigned Scale, bool NonAbsMem, SMLoc Start,
@@ -2574,7 +2578,8 @@ bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
25742578 return false ;
25752579}
25762580
2577- bool X86AsmParser::ParseIntelMemoryOperandSize (unsigned &Size) {
2581+ bool X86AsmParser::ParseIntelMemoryOperandSize (unsigned &Size,
2582+ StringRef *SizeStr) {
25782583 Size = StringSwitch<unsigned >(getTok ().getString ())
25792584 .Cases (" BYTE" , " byte" , 8 )
25802585 .Cases (" WORD" , " word" , 16 )
@@ -2592,6 +2597,8 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
25922597 .Cases (" ZMMWORD" , " zmmword" , 512 )
25932598 .Default (0 );
25942599 if (Size) {
2600+ if (SizeStr)
2601+ *SizeStr = getTok ().getString ();
25952602 const AsmToken &Tok = Lex (); // Eat operand size (e.g., byte, word).
25962603 if (!(Tok.getString () == " PTR" || Tok.getString () == " ptr" ))
25972604 return Error (Tok.getLoc (), " Expected 'PTR' or 'ptr' token!" );
@@ -2600,14 +2607,28 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
26002607 return false ;
26012608}
26022609
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+
26032623bool X86AsmParser::parseIntelOperand (OperandVector &Operands, StringRef Name) {
26042624 MCAsmParser &Parser = getParser ();
26052625 const AsmToken &Tok = Parser.getTok ();
26062626 SMLoc Start, End;
26072627
26082628 // Parse optional Size directive.
26092629 unsigned Size;
2610- if (ParseIntelMemoryOperandSize (Size))
2630+ StringRef SizeStr;
2631+ if (ParseIntelMemoryOperandSize (Size, &SizeStr))
26112632 return true ;
26122633 bool PtrInOperand = bool (Size);
26132634
@@ -2624,9 +2645,29 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
26242645 return Error (Start, " rip can only be used as a base register" );
26252646 // A Register followed by ':' is considered a segment override
26262647 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+ }
26302671 Operands.push_back (X86Operand::CreateReg (RegNo, Start, End));
26312672 return false ;
26322673 }
0 commit comments