mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
ARM assembly parsing for MOV (register).
Correct the handling of the 's' suffix when parsing ARM mode. It's only a truly separate opcode in Thumb. Add test cases to make sure we handle the s and condition suffices correctly, including diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135513 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -79,6 +79,8 @@ class ARMAsmParser : public TargetAsmParser {
|
|||||||
bool MatchAndEmitInstruction(SMLoc IDLoc,
|
bool MatchAndEmitInstruction(SMLoc IDLoc,
|
||||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
MCStreamer &Out);
|
MCStreamer &Out);
|
||||||
|
StringRef SplitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
|
||||||
|
bool &CarrySetting, unsigned &ProcessorIMod);
|
||||||
void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
|
void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
|
||||||
bool &CanAcceptPredicationCode);
|
bool &CanAcceptPredicationCode);
|
||||||
|
|
||||||
@@ -1952,10 +1954,10 @@ ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
|
|||||||
/// setting letters to form a canonical mnemonic and flags.
|
/// setting letters to form a canonical mnemonic and flags.
|
||||||
//
|
//
|
||||||
// FIXME: Would be nice to autogen this.
|
// FIXME: Would be nice to autogen this.
|
||||||
static StringRef SplitMnemonic(StringRef Mnemonic,
|
StringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic,
|
||||||
unsigned &PredicationCode,
|
unsigned &PredicationCode,
|
||||||
bool &CarrySetting,
|
bool &CarrySetting,
|
||||||
unsigned &ProcessorIMod) {
|
unsigned &ProcessorIMod) {
|
||||||
PredicationCode = ARMCC::AL;
|
PredicationCode = ARMCC::AL;
|
||||||
CarrySetting = false;
|
CarrySetting = false;
|
||||||
ProcessorIMod = 0;
|
ProcessorIMod = 0;
|
||||||
@@ -1963,19 +1965,19 @@ static StringRef SplitMnemonic(StringRef Mnemonic,
|
|||||||
// Ignore some mnemonics we know aren't predicated forms.
|
// Ignore some mnemonics we know aren't predicated forms.
|
||||||
//
|
//
|
||||||
// FIXME: Would be nice to autogen this.
|
// FIXME: Would be nice to autogen this.
|
||||||
if (Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "movs" ||
|
if ((Mnemonic == "movs" && isThumb()) ||
|
||||||
Mnemonic == "svc" || Mnemonic == "mls" || Mnemonic == "smmls" ||
|
Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" ||
|
||||||
Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vnmls" ||
|
Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
|
||||||
Mnemonic == "vacge" || Mnemonic == "vcge" || Mnemonic == "vclt" ||
|
Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" ||
|
||||||
Mnemonic == "vacgt" || Mnemonic == "vcgt" || Mnemonic == "vcle" ||
|
Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" ||
|
||||||
Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
|
Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" ||
|
||||||
Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
|
Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" ||
|
||||||
Mnemonic == "vqdmlal")
|
Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
|
||||||
return Mnemonic;
|
return Mnemonic;
|
||||||
|
|
||||||
// First, split out any predication code. Ignore mnemonics we know aren't
|
// First, split out any predication code. Ignore mnemonics we know aren't
|
||||||
// predicated but do have a carry-set and so weren't caught above.
|
// predicated but do have a carry-set and so weren't caught above.
|
||||||
if (Mnemonic != "adcs" && Mnemonic != "bics") {
|
if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs") {
|
||||||
unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
|
unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
|
||||||
.Case("eq", ARMCC::EQ)
|
.Case("eq", ARMCC::EQ)
|
||||||
.Case("ne", ARMCC::NE)
|
.Case("ne", ARMCC::NE)
|
||||||
@@ -2005,10 +2007,10 @@ static StringRef SplitMnemonic(StringRef Mnemonic,
|
|||||||
// the instructions we know end in 's'.
|
// the instructions we know end in 's'.
|
||||||
if (Mnemonic.endswith("s") &&
|
if (Mnemonic.endswith("s") &&
|
||||||
!(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
|
!(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
|
||||||
Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
|
Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
|
||||||
Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
|
Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
|
||||||
Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
|
Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
|
||||||
Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
|
Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) {
|
||||||
Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
|
Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
|
||||||
CarrySetting = true;
|
CarrySetting = true;
|
||||||
}
|
}
|
||||||
@@ -2056,8 +2058,8 @@ GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
|
|||||||
Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
|
Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
|
||||||
Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
|
Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
|
||||||
Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
|
Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
|
||||||
Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
|
Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
|
||||||
Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
|
Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
|
||||||
CanAcceptPredicationCode = false;
|
CanAcceptPredicationCode = false;
|
||||||
} else {
|
} else {
|
||||||
CanAcceptPredicationCode = true;
|
CanAcceptPredicationCode = true;
|
||||||
|
@@ -678,12 +678,31 @@ _func:
|
|||||||
mov r5, #0xff0000
|
mov r5, #0xff0000
|
||||||
mov r6, #0xffff
|
mov r6, #0xffff
|
||||||
movw r9, #0xffff
|
movw r9, #0xffff
|
||||||
|
movs r3, #7
|
||||||
|
moveq r4, #0xff0
|
||||||
|
movseq r5, #0xff0000
|
||||||
|
|
||||||
@ CHECK: mov r3, #7 @ encoding: [0x07,0x30,0xa0,0xe3]
|
@ CHECK: mov r3, #7 @ encoding: [0x07,0x30,0xa0,0xe3]
|
||||||
@ CHECK: mov r4, #4080 @ encoding: [0xff,0x4e,0xa0,0xe3]
|
@ CHECK: mov r4, #4080 @ encoding: [0xff,0x4e,0xa0,0xe3]
|
||||||
@ CHECK: mov r5, #16711680 @ encoding: [0xff,0x58,0xa0,0xe3]
|
@ CHECK: mov r5, #16711680 @ encoding: [0xff,0x58,0xa0,0xe3]
|
||||||
@ CHECK: movw r6, #65535 @ encoding: [0xff,0x6f,0x0f,0xe3]
|
@ CHECK: movw r6, #65535 @ encoding: [0xff,0x6f,0x0f,0xe3]
|
||||||
@ CHECK: movw r9, #65535 @ encoding: [0xff,0x9f,0x0f,0xe3]
|
@ CHECK: movw r9, #65535 @ encoding: [0xff,0x9f,0x0f,0xe3]
|
||||||
|
@ CHECK: movs r3, #7 @ encoding: [0x07,0x30,0xb0,0xe3]
|
||||||
|
@ CHECK: moveq r4, #4080 @ encoding: [0xff,0x4e,0xa0,0x03]
|
||||||
|
@ CHECK: movseq r5, #16711680 @ encoding: [0xff,0x58,0xb0,0x03]
|
||||||
|
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
@ MOV (register)
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
mov r2, r3
|
||||||
|
movs r2, r3
|
||||||
|
moveq r2, r3
|
||||||
|
movseq r2, r3
|
||||||
|
|
||||||
|
@ CHECK: mov r2, r3 @ encoding: [0x03,0x20,0xa0,0xe1]
|
||||||
|
@ CHECK: movs r2, r3 @ encoding: [0x03,0x20,0xb0,0xe1]
|
||||||
|
@ CHECK: moveq r2, r3 @ encoding: [0x03,0x20,0xa0,0x01]
|
||||||
|
@ CHECK: movseq r2, r3 @ encoding: [0x03,0x20,0xb0,0x01]
|
||||||
|
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
@ STM*
|
@ STM*
|
||||||
|
@@ -93,3 +93,9 @@
|
|||||||
@ Out of range immediate for MOV
|
@ Out of range immediate for MOV
|
||||||
movw r9, 0x10000
|
movw r9, 0x10000
|
||||||
@ CHECK-ERRORS: error: invalid operand for instruction
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
||||||
|
|
||||||
|
@ Invalid 's' bit usage for MOVW
|
||||||
|
movs r6, #0xffff
|
||||||
|
movwseq r9, #0xffff
|
||||||
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
||||||
|
@ CHECK-ERRORS: error: instruction 'movw' can not set flags, but 's' suffix specified
|
||||||
|
Reference in New Issue
Block a user