ARM LDM/STM system instruction variants.

rdar://10550269

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146519 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach
2011-12-13 21:48:29 +00:00
parent b0659873e6
commit 27debd60a1
3 changed files with 45 additions and 11 deletions

View File

@@ -2804,23 +2804,25 @@ defm STRHT : AI3strT<0b1011, "strht">;
// Load / store multiple Instructions. // Load / store multiple Instructions.
// //
multiclass arm_ldst_mult<string asm, bit L_bit, Format f, multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f,
InstrItinClass itin, InstrItinClass itin_upd> { InstrItinClass itin, InstrItinClass itin_upd> {
// IA is the default, so no need for an explicit suffix on the // IA is the default, so no need for an explicit suffix on the
// mnemonic here. Without it is the cannonical spelling. // mnemonic here. Without it is the cannonical spelling.
def IA : def IA :
AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeNone, f, itin, IndexModeNone, f, itin,
!strconcat(asm, "${p}\t$Rn, $regs"), "", []> { !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> {
let Inst{24-23} = 0b01; // Increment After let Inst{24-23} = 0b01; // Increment After
let Inst{22} = P_bit;
let Inst{21} = 0; // No writeback let Inst{21} = 0; // No writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
} }
def IA_UPD : def IA_UPD :
AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeUpd, f, itin_upd, IndexModeUpd, f, itin_upd,
!strconcat(asm, "${p}\t$Rn!, $regs"), "$Rn = $wb", []> { !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
let Inst{24-23} = 0b01; // Increment After let Inst{24-23} = 0b01; // Increment After
let Inst{22} = P_bit;
let Inst{21} = 1; // Writeback let Inst{21} = 1; // Writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
@@ -2829,16 +2831,18 @@ multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
def DA : def DA :
AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeNone, f, itin, IndexModeNone, f, itin,
!strconcat(asm, "da${p}\t$Rn, $regs"), "", []> { !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> {
let Inst{24-23} = 0b00; // Decrement After let Inst{24-23} = 0b00; // Decrement After
let Inst{22} = P_bit;
let Inst{21} = 0; // No writeback let Inst{21} = 0; // No writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
} }
def DA_UPD : def DA_UPD :
AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeUpd, f, itin_upd, IndexModeUpd, f, itin_upd,
!strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> { !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
let Inst{24-23} = 0b00; // Decrement After let Inst{24-23} = 0b00; // Decrement After
let Inst{22} = P_bit;
let Inst{21} = 1; // Writeback let Inst{21} = 1; // Writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
@@ -2847,16 +2851,18 @@ multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
def DB : def DB :
AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeNone, f, itin, IndexModeNone, f, itin,
!strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> {
let Inst{24-23} = 0b10; // Decrement Before let Inst{24-23} = 0b10; // Decrement Before
let Inst{22} = P_bit;
let Inst{21} = 0; // No writeback let Inst{21} = 0; // No writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
} }
def DB_UPD : def DB_UPD :
AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeUpd, f, itin_upd, IndexModeUpd, f, itin_upd,
!strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
let Inst{24-23} = 0b10; // Decrement Before let Inst{24-23} = 0b10; // Decrement Before
let Inst{22} = P_bit;
let Inst{21} = 1; // Writeback let Inst{21} = 1; // Writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
@@ -2865,16 +2871,18 @@ multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
def IB : def IB :
AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeNone, f, itin, IndexModeNone, f, itin,
!strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> { !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> {
let Inst{24-23} = 0b11; // Increment Before let Inst{24-23} = 0b11; // Increment Before
let Inst{22} = P_bit;
let Inst{21} = 0; // No writeback let Inst{21} = 0; // No writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
} }
def IB_UPD : def IB_UPD :
AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
IndexModeUpd, f, itin_upd, IndexModeUpd, f, itin_upd,
!strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> { !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
let Inst{24-23} = 0b11; // Increment Before let Inst{24-23} = 0b11; // Increment Before
let Inst{22} = P_bit;
let Inst{21} = 1; // Writeback let Inst{21} = 1; // Writeback
let Inst{20} = L_bit; let Inst{20} = L_bit;
@@ -2885,10 +2893,12 @@ multiclass arm_ldst_mult<string asm, bit L_bit, Format f,
let neverHasSideEffects = 1 in { let neverHasSideEffects = 1 in {
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>; defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
IIC_iLoad_mu>;
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>; defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m,
IIC_iStore_mu>;
} // neverHasSideEffects } // neverHasSideEffects
@@ -2902,6 +2912,16 @@ def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
(LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
RegConstraint<"$Rn = $wb">; RegConstraint<"$Rn = $wb">;
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
defm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m,
IIC_iLoad_mu>;
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
defm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m,
IIC_iStore_mu>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Move Instructions. // Move Instructions.
// //

View File

@@ -2666,7 +2666,15 @@ parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return Error(E, "'}' expected"); return Error(E, "'}' expected");
Parser.Lex(); // Eat '}' token. Parser.Lex(); // Eat '}' token.
// Push the register list operand.
Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
// The ARM system instruction variants for LDM/STM have a '^' token here.
if (Parser.getTok().is(AsmToken::Caret)) {
Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
Parser.Lex(); // Eat '^' token.
}
return false; return false;
} }

View File

@@ -764,6 +764,10 @@ Lforward:
ldmda r2!, {r1,r3-r6,sp} ldmda r2!, {r1,r3-r6,sp}
ldmdb r2!, {r1,r3-r6,sp} ldmdb r2!, {r1,r3-r6,sp}
@ system version
ldm r0, {r0, r2, lr}^
ldm sp!, {r0-r3, pc}^
@ CHECK: ldm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe8] @ CHECK: ldm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe8]
@ CHECK: ldm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe8] @ CHECK: ldm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe8]
@ CHECK: ldmib r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe9] @ CHECK: ldmib r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x92,0xe9]
@@ -775,6 +779,8 @@ Lforward:
@ CHECK: ldmib r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xb2,0xe9] @ CHECK: ldmib r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xb2,0xe9]
@ CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe8] @ CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe8]
@ CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe9] @ CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe9]
@ CHECK: ldm r0, {lr, r0, r2} ^ @ encoding: [0x05,0x40,0xd0,0xe8]
@ CHECK: ldm sp!, {pc, r0, r1, r2, r3} ^ @ encoding: [0x0f,0x80,0xfd,0xe8]
@------------------------------------------------------------------------------ @------------------------------------------------------------------------------