diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index cf4ef65424a..dfbb05574a7 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1722,23 +1722,44 @@ def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> { } // Store Return State -// FIXME: This should not use submode! -def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), - NoItinerary, "srs${amode}\tsp!, $mode", []> { +class SRSI + : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm, + NoItinerary, asm, "", []> { + bits<5> mode; let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b110; // W = 1 - let Inst{19-8} = 0xd05; - let Inst{7-5} = 0b000; + let Inst{27-25} = 0b100; + let Inst{22} = 1; + let Inst{21} = wb; + let Inst{20} = 0; + let Inst{19-16} = 0b1101; // SP + let Inst{15-5} = 0b00000101000; + let Inst{4-0} = mode; } -def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), - NoItinerary, "srs${amode}\tsp, $mode", []> { - let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b100; // W = 0 - let Inst{19-8} = 0xd05; - let Inst{7-5} = 0b000; +def SRSDA : SRSI<0, "srsda\tsp, $mode"> { + let Inst{24-23} = 0; +} +def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> { + let Inst{24-23} = 0; +} +def SRSDB : SRSI<0, "srsdb\tsp, $mode"> { + let Inst{24-23} = 0b10; +} +def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> { + let Inst{24-23} = 0b10; +} +def SRSIA : SRSI<0, "srsia\tsp, $mode"> { + let Inst{24-23} = 0b01; +} +def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> { + let Inst{24-23} = 0b01; +} +def SRSIB : SRSI<0, "srsib\tsp, $mode"> { + let Inst{24-23} = 0b11; +} +def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> { + let Inst{24-23} = 0b11; } - // Return From Exception class RFEI @@ -4454,3 +4475,10 @@ def : MnemonicAlias<"rfeea", "rfedb">; def : MnemonicAlias<"rfefd", "rfeia">; def : MnemonicAlias<"rfeed", "rfeib">; def : MnemonicAlias<"rfe", "rfeia">; + +// SRS aliases +def : MnemonicAlias<"srsfa", "srsda">; +def : MnemonicAlias<"srsea", "srsdb">; +def : MnemonicAlias<"srsfd", "srsia">; +def : MnemonicAlias<"srsed", "srsib">; +def : MnemonicAlias<"srs", "srsia">; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 40c3097e130..5f12b6150d9 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2489,7 +2489,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || - Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) { + Mnemonic == "vrsqrts" || Mnemonic == "srs" || + (Mnemonic == "movs" && isThumb()))) { Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); CarrySetting = true; } @@ -2540,7 +2541,8 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || Mnemonic == "setend" || ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || - (Mnemonic.startswith("rfe") && !isThumb()) || + ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) + && !isThumb()) || Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { CanAcceptPredicationCode = false; } else { diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 983589f6983..8b22786843f 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -798,7 +798,7 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn, // MSR/MSRsys: Rm mask=Inst{19-16} // BXJ: Rm // MSRi/MSRsysi: so_imm -// SRSW/SRS: ldstm_mode:$amode mode_imm +// SRS: mode_imm // RFE: Rn static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) { @@ -858,15 +858,12 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn, NumOpsAdded = 2; return true; } - if (Opcode == ARM::SRSW || Opcode == ARM::SRS) { - ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn)); - MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode))); - - if (Opcode == ARM::SRSW || Opcode == ARM::SRS) - MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, - decodeRn(insn)))); - NumOpsAdded = 3; + if (Opcode == ARM::SRSDA || Opcode == ARM::SRSDB || + Opcode == ARM::SRSIA || Opcode == ARM::SRSIB || + Opcode == ARM::SRSDA_UPD || Opcode == ARM::SRSDB_UPD || + Opcode == ARM::SRSIA_UPD || Opcode == ARM::SRSIB_UPD) { + MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); + NumOpsAdded = 1; return true; } if (Opcode == ARM::RFEDA || Opcode == ARM::RFEDB || diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 1a271986b34..c99c4353c0e 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -1732,8 +1732,53 @@ Lforward: @------------------------------------------------------------------------------ -@ FIXME: SRS +@ SRS @------------------------------------------------------------------------------ + srsda sp, #5 + srsdb sp, #1 + srsia sp, #0 + srsib sp, #15 + + srsda sp!, #31 + srsdb sp!, #19 + srsia sp!, #2 + srsib sp!, #14 + + srsfa sp, #11 + srsea sp, #10 + srsfd sp, #9 + srsed sp, #5 + + srsfa sp!, #5 + srsea sp!, #5 + srsfd sp!, #5 + srsed sp!, #5 + + srs sp, #5 + srs sp!, #5 + +@ CHECK: srsda sp, #5 @ encoding: [0x05,0x05,0x4d,0xf8] +@ CHECK: srsdb sp, #1 @ encoding: [0x01,0x05,0x4d,0xf9] +@ CHECK: srsia sp, #0 @ encoding: [0x00,0x05,0xcd,0xf8] +@ CHECK: srsib sp, #15 @ encoding: [0x0f,0x05,0xcd,0xf9] + +@ CHECK: srsda sp!, #31 @ encoding: [0x1f,0x05,0x6d,0xf8] +@ CHECK: srsdb sp!, #19 @ encoding: [0x13,0x05,0x6d,0xf9] +@ CHECK: srsia sp!, #2 @ encoding: [0x02,0x05,0xed,0xf8] +@ CHECK: srsib sp!, #14 @ encoding: [0x0e,0x05,0xed,0xf9] + +@ CHECK: srsda sp, #11 @ encoding: [0x0b,0x05,0x4d,0xf8] +@ CHECK: srsdb sp, #10 @ encoding: [0x0a,0x05,0x4d,0xf9] +@ CHECK: srsia sp, #9 @ encoding: [0x09,0x05,0xcd,0xf8] +@ CHECK: srsib sp, #5 @ encoding: [0x05,0x05,0xcd,0xf9] + +@ CHECK: srsda sp!, #5 @ encoding: [0x05,0x05,0x6d,0xf8] +@ CHECK: srsdb sp!, #5 @ encoding: [0x05,0x05,0x6d,0xf9] +@ CHECK: srsia sp!, #5 @ encoding: [0x05,0x05,0xed,0xf8] +@ CHECK: srsib sp!, #5 @ encoding: [0x05,0x05,0xed,0xf9] + +@ CHECK: srsia sp, #5 @ encoding: [0x05,0x05,0xcd,0xf8] +@ CHECK: srsia sp!, #5 @ encoding: [0x05,0x05,0xed,0xf8] @------------------------------------------------------------------------------ diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt index 537ad551a43..b15fa4ff9c2 100644 --- a/test/MC/Disassembler/ARM/arm-tests.txt +++ b/test/MC/Disassembler/ARM/arm-tests.txt @@ -101,6 +101,12 @@ # CHECK: rfedb r0! 0x00 0x0a 0x30 0xf9 +# CHECK: srsdb sp!, #19 +0x13 0x05 0x6d 0xf9 + +# CHECK: srsia sp, #9 +0x09 0x05 0xcd 0xf8 + # CHECK-NOT: rsbeq r0, r2, r0, lsl #0 # CHECK: rsbeq r0, r2, r0 0x00 0x00 0x62 0x00