SDValue &Offset, SDValue &Opc);
bool SelectAddrMode3Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode);
bool SelectAddrMode5(SDValue N, SDValue &Base,
SDValue &Offset);
bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align);
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode) {
- Addr = N;
- Mode = CurDAG->getTargetConstant(ARM_AM::getAM4ModeImm(ARM_AM::ia), MVT::i32);
- return true;
-}
-
bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N,
SDValue &Base, SDValue &Offset) {
if (N.getOpcode() != ISD::ADD) {
let MIOperandInfo = (ops GPR, i32imm);
}
-// addrmode4 := reg, <mode|W>
+// ldstm_mode := {ia, ib, da, db}
//
-def addrmode4 : Operand<i32>,
- ComplexPattern<i32, 2, "SelectAddrMode4", []> {
- let PrintMethod = "printAddrMode4Operand";
- let MIOperandInfo = (ops GPR:$addr, i32imm);
+def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
+ let PrintMethod = "printLdStmModeOperand";
}
def ARMMemMode5AsmOperand : AsmOperandClass {
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
- def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ def LDM_RET : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$mode, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
- "ldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []>;
+ "ldm${mode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []>;
// On non-Darwin platforms R9 is callee-saved.
let isCall = 1,
// Store Return State is a system instruction -- for disassembly only
let isCodeGenOnly = 1 in { // FIXME: This should not use submode!
-def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
- NoItinerary, "srs${addr:submode}\tsp!, $mode",
+def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
+ NoItinerary, "srs${amode}\tsp!, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{22-20} = 0b110; // W = 1
}
-def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
- NoItinerary, "srs${addr:submode}\tsp, $mode",
+def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
+ NoItinerary, "srs${amode}\tsp, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{22-20} = 0b100; // W = 0
}
// Return From Exception is a system instruction -- for disassembly only
-def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
- NoItinerary, "rfe${addr:submode}\t$base!",
+def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
+ NoItinerary, "rfe${amode}\t$base!",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{22-20} = 0b011; // W = 1
}
-def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
- NoItinerary, "rfe${addr:submode}\t$base",
+def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
+ NoItinerary, "rfe${amode}\t$base",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{22-20} = 0b001; // W = 0
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
+def LDM : AXI4ld<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IndexModeNone, LdStMulFrm, IIC_iLoad_m,
- "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
+ "ldm${amode}${p}\t$Rn, $dsts", "", []>;
-def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_iLoad_mu,
- "ldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []>;
+ "ldm${amode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []>;
} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
+def STM : AXI4st<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops),
IndexModeNone, LdStMulFrm, IIC_iStore_m,
- "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
+ "stm${amode}${p}\t$Rn, $srcs", "", []>;
-def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def STM_UPD : AXI4st<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_iStore_mu,
- "stm${addr:submode}${p}\t$addr!, $srcs",
- "$addr.addr = $wb", []>;
+ "stm${amode}${p}\t$Rn!, $srcs",
+ "$Rn = $wb", []>;
} // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
//===----------------------------------------------------------------------===//
// Use VLDM to load a Q register as a D register pair.
// This is a pseudo instruction that is expanded to VLDMD after reg alloc.
def VLDMQ
- : PseudoVFPLdStM<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoad_m, "",
- [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]>;
+ : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn, ldstm_mode:$mode),
+ IIC_fpLoad_m, "",
+ [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>;
// Use VSTM to store a Q register as a D register pair.
// This is a pseudo instruction that is expanded to VSTMD after reg alloc.
def VSTMQ
- : PseudoVFPLdStM<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStore_m, "",
- [(store (v2f64 QPR:$src), addrmode4:$addr)]>;
+ : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn, ldstm_mode:$mode),
+ IIC_fpStore_m, "",
+ [(store (v2f64 QPR:$src), GPR:$Rn)]>;
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
isCodeGenOnly = 1 in {
def tLDM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$dsts,
+ variable_ops),
IIC_iLoad_m,
- "ldm${addr:submode}${p}\t$addr, $dsts", []>,
+ "ldm${amode}${p}\t$Rn, $dsts", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
def tLDM_UPD : T1It<(outs tGPR:$wb),
- (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$dsts,
+ variable_ops),
IIC_iLoad_m,
- "ldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []>,
+ "ldm${amode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
} // mayLoad, neverHasSideEffects = 1, hasExtraDefRegAllocReq
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
isCodeGenOnly = 1 in
def tSTM_UPD : T1It<(outs tGPR:$wb),
- (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops),
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$srcs,
+ variable_ops),
IIC_iStore_mu,
- "stm${addr:submode}${p}\t$addr!, $srcs",
- "$addr.addr = $wb", []>,
+ "stm${amode}${p}\t$Rn!, $srcs",
+ "$Rn = $wb", []>,
T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops), IIC_iLoad_m,
- "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts", []> {
+ "ldm${amode}${p}.w\t$Rn, $dsts", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{20} = 1; // Load
}
-def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IIC_iLoad_mu,
- "ldm${addr:submode}${p}${addr:wide}\t$addr!, $dsts",
- "$addr.addr = $wb", []> {
+ "ldm${amode}${p}.w\t$Rn!, $dsts",
+ "$Rn = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops), IIC_iStore_m,
- "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs", []> {
+ "stm${amode}${p}.w\t$Rn, $srcs", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{20} = 0; // Store
}
-def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops),
IIC_iStore_m,
- "stm${addr:submode}${p}${addr:wide}\t$addr!, $srcs",
- "$addr.addr = $wb", []> {
+ "stm${amode}${p}.w\t$Rn!, $srcs",
+ "$Rn = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
- def t2LDM_RET : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
- reglist:$dsts, variable_ops),
+ def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
+ reglist:$dsts, variable_ops),
IIC_iLoad_mBr,
- "ldm${addr:submode}${p}${addr:wide}\t$addr!, $dsts",
- "$addr.addr = $wb", []> {
+ "ldm${amode}${p}.w\t$Rn!, $dsts",
+ "$Rn = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def VLDMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
- variable_ops), IndexModeNone, IIC_fpLoad_m,
- "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
+def VLDMD : AXDI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeNone, IIC_fpLoad_m,
+ "vldm${amode}${p}\t$Rn, $dsts", "", []> {
let Inst{20} = 1;
}
-def VLDMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
- variable_ops), IndexModeNone, IIC_fpLoad_m,
- "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
+def VLDMS : AXSI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeNone, IIC_fpLoad_m,
+ "vldm${amode}${p}\t$Rn, $dsts", "", []> {
let Inst{20} = 1;
}
-def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, IIC_fpLoad_mu,
- "vldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []> {
+ "vldm${amode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []> {
let Inst{20} = 1;
}
-def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, IIC_fpLoad_mu,
- "vldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []> {
+ "vldm${amode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []> {
let Inst{20} = 1;
}
} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
isCodeGenOnly = 1 in {
-def VSTMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
- variable_ops), IndexModeNone, IIC_fpStore_m,
- "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
+def VSTMD : AXDI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeNone, IIC_fpStore_m,
+ "vstm${amode}${p}\t$Rn, $srcs", "", []> {
let Inst{20} = 0;
}
-def VSTMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
- variable_ops), IndexModeNone, IIC_fpStore_m,
- "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
+def VSTMS : AXSI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
+ reglist:$srcs, variable_ops), IndexModeNone,
+ IIC_fpStore_m,
+ "vstm${amode}${p}\t$Rn, $srcs", "", []> {
let Inst{20} = 0;
}
-def VSTMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def VSTMD_UPD : AXDI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, IIC_fpStore_mu,
- "vstm${addr:submode}${p}\t$addr!, $srcs",
- "$addr.addr = $wb", []> {
+ "vstm${amode}${p}\t$Rn!, $srcs",
+ "$Rn = $wb", []> {
let Inst{20} = 0;
}
-def VSTMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+def VSTMS_UPD : AXSI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, IIC_fpStore_mu,
- "vstm${addr:submode}${p}\t$addr!, $srcs",
- "$addr.addr = $wb", []> {
+ "vstm${amode}${p}\t$Rn!, $srcs",
+ "$Rn = $wb", []> {
let Inst{20} = 0;
}
} // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
// MSR/MSRsys: Rm mask=Inst{19-16}
// BXJ: Rm
// MSRi/MSRsysi: so_imm
-// SRSW/SRS: addrmode4:$addr mode_imm
-// RFEW/RFE: addrmode4:$addr Rn
+// SRSW/SRS: ldstm_mode:$amode mode_imm
+// RFEW/RFE: ldstm_mode:$amode Rn
static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
NumOpsAdded = 2;
return true;
}
- // SRSW and SRS requires addrmode4:$addr for ${addr:submode}, followed by the
- // mode immediate (Inst{4-0}).
if (Opcode == ARM::SRSW || Opcode == ARM::SRS ||
Opcode == ARM::RFEW || Opcode == ARM::RFE) {
- // ARMInstPrinter::printAddrMode4Operand() prints special mode string
- // if the base register is SP; so don't set ARM::SP.
- MI.addOperand(MCOperand::CreateReg(0));
ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
<< ImmOffs;
}
-
-void ARMInstPrinter::printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
+void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O,
const char *Modifier) {
- const MCOperand &MO2 = MI->getOperand(OpNum+1);
- ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
- if (Modifier && strcmp(Modifier, "submode") == 0) {
- O << ARM_AM::getAMSubModeStr(Mode);
- } else if (Modifier && strcmp(Modifier, "wide") == 0) {
- ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
- if (Mode == ARM_AM::ia)
- O << ".w";
- } else {
- printOperand(MI, OpNum, O);
- }
+ ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum)
+ .getImm());
+ O << ARM_AM::getAMSubModeStr(Mode);
}
void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O);
- void printAddrMode4Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
+ void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier = 0);
void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier = 0);
MISC("am2offset", "kOperandTypeARMAddrMode2Offset"); // R, I
MISC("addrmode3", "kOperandTypeARMAddrMode3"); // R, R, I
MISC("am3offset", "kOperandTypeARMAddrMode3Offset"); // R, I
- MISC("addrmode4", "kOperandTypeARMAddrMode4"); // R, I
+ MISC("ldstm_mode", "kOperandTypeARMLdStmMode"); // I
MISC("addrmode5", "kOperandTypeARMAddrMode5"); // R, I
MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I
MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I
operandTypes.addEntry("kOperandTypeARMAddrMode2Offset");
operandTypes.addEntry("kOperandTypeARMAddrMode3");
operandTypes.addEntry("kOperandTypeARMAddrMode3Offset");
- operandTypes.addEntry("kOperandTypeARMAddrMode4");
+ operandTypes.addEntry("kOperandTypeARMLdStmMode");
operandTypes.addEntry("kOperandTypeARMAddrMode5");
operandTypes.addEntry("kOperandTypeARMAddrMode6");
operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");