@@ -1210,8 +1210,6 @@ bool X86AsmParser::MatchRegisterByName(unsigned &RegNo, StringRef RegName,
1210
1210
// FIXME: This should be done using Requires<Not64BitMode> and
1211
1211
// Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1212
1212
// checked.
1213
- // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1214
- // REX prefix.
1215
1213
if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1216
1214
X86MCRegisterClasses[X86::GR64RegClassID].contains (RegNo) ||
1217
1215
X86II::isX86_64NonExtLowByteReg (RegNo) ||
@@ -3619,6 +3617,33 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
3619
3617
}
3620
3618
}
3621
3619
3620
+ const MCInstrDesc &MCID = MII.get (Inst.getOpcode ());
3621
+ // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
3622
+ // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
3623
+ if ((MCID.TSFlags & X86II::EncodingMask) == 0 ) {
3624
+ MCPhysReg HReg = X86::NoRegister;
3625
+ bool UsesRex = MCID.TSFlags & X86II::REX_W;
3626
+ unsigned NumOps = Inst.getNumOperands ();
3627
+ for (unsigned i = 0 ; i != NumOps; ++i) {
3628
+ const MCOperand &MO = Inst.getOperand (i);
3629
+ if (!MO.isReg ())
3630
+ continue ;
3631
+ unsigned Reg = MO.getReg ();
3632
+ if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
3633
+ HReg = Reg;
3634
+ if (X86II::isX86_64NonExtLowByteReg (Reg) ||
3635
+ X86II::isX86_64ExtendedReg (Reg))
3636
+ UsesRex = true ;
3637
+ }
3638
+
3639
+ if (UsesRex && HReg != X86::NoRegister) {
3640
+ StringRef RegName = X86IntelInstPrinter::getRegisterName (HReg);
3641
+ return Error (Ops[0 ]->getStartLoc (),
3642
+ " can't encode '" + RegName + " ' in an instruction requiring "
3643
+ " REX prefix." );
3644
+ }
3645
+ }
3646
+
3622
3647
return false ;
3623
3648
}
3624
3649
@@ -3989,6 +4014,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
3989
4014
unsigned NumSuccessfulMatches =
3990
4015
std::count (std::begin (Match), std::end (Match), Match_Success);
3991
4016
if (NumSuccessfulMatches == 1 ) {
4017
+ if (!MatchingInlineAsm && validateInstruction (Inst, Operands))
4018
+ return true ;
3992
4019
// Some instructions need post-processing to, for example, tweak which
3993
4020
// encoding is selected. Loop on it while changes happen so the
3994
4021
// individual transformations can chain off each other.
0 commit comments