}
void printAddrMode1(const MachineInstr *MI, int opNum);
+ void printAddrMode5(const MachineInstr *MI, int opNum);
void printMemRegImm(const MachineInstr *MI, int opNum,
const char *Modifier = NULL) {
}
}
+void ARMAsmPrinter::printAddrMode5(const MachineInstr *MI, int opNum) {
+ const MachineOperand &Arg = MI->getOperand(opNum);
+ const MachineOperand &Offset = MI->getOperand(opNum + 1);
+ assert(Offset.isImmediate());
+
+ if (Arg.isConstantPoolIndex()) {
+ assert(Offset.getImmedValue() == 0);
+ printOperand(MI, opNum);
+ } else {
+ assert(Arg.isRegister());
+ O << '[';
+ printOperand(MI, opNum);
+ O << ", ";
+ printOperand(MI, opNum + 1);
+ O << ']';
+ }
+}
+
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand (opNum);
const MRegisterInfo &RI = *TM.getRegisterInfo();
bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
bool SelectAddrMode1(SDOperand N, SDOperand &Arg, SDOperand &Shift,
SDOperand &ShiftType);
+ bool SelectAddrMode5(SDOperand N, SDOperand &Arg, SDOperand &Offset);
// Include the pieces autogenerated from the target description.
#include "ARMGenDAGISel.inc"
return true;
}
+bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand N, SDOperand &Arg,
+ SDOperand &Offset) {
+ //TODO: detect offset
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+ Arg = N;
+ return true;
+}
+
//register plus/minus 12 bit offset
bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
SDOperand &Base) {
let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
}
+def op_addr_mode5 : Operand<iPTR> {
+ let PrintMethod = "printAddrMode5";
+ let NumMIOperands = 2;
+ let MIOperandInfo = (ops ptr_rc, i32imm);
+}
+
def memri : Operand<iPTR> {
let PrintMethod = "printMemRegImm";
let NumMIOperands = 2;
def addr_mode1 : ComplexPattern<iPTR, 3, "SelectAddrMode1", [imm, sra, shl, srl],
[]>;
+//Addressing Mode 5: VFP load/store
+def addr_mode5 : ComplexPattern<iPTR, 2, "SelectAddrMode5", [], []>;
+
//register plus/minus 12 bit offset
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex], []>;
//register plus scaled register
def FDIVD : DFPBinOp<"fdivd", fdiv>;
// Floating Point Load
-def FLDS : InstARM<(ops FPRegs:$dst, IntRegs:$addr),
- "flds $dst, [$addr]",
- [(set FPRegs:$dst, (load IntRegs:$addr))]>;
+def FLDS : InstARM<(ops FPRegs:$dst, op_addr_mode5:$addr),
+ "flds $dst, $addr",
+ [(set FPRegs:$dst, (load addr_mode5:$addr))]>;
-def FLDD : InstARM<(ops DFPRegs:$dst, IntRegs:$addr),
- "fldd $dst, [$addr]",
- [(set DFPRegs:$dst, (load IntRegs:$addr))]>;
+def FLDD : InstARM<(ops DFPRegs:$dst, op_addr_mode5:$addr),
+ "fldd $dst, $addr",
+ [(set DFPRegs:$dst, (load addr_mode5:$addr))]>;
// Floating Point Store
-def FSTS : InstARM<(ops FPRegs:$src, IntRegs:$addr),
+def FSTS : InstARM<(ops FPRegs:$src, op_addr_mode5:$addr),
"fsts $src, [$addr]",
- [(store FPRegs:$src, IntRegs:$addr)]>;
+ [(store FPRegs:$src, addr_mode5:$addr)]>;
-def FSTD : InstARM<(ops DFPRegs:$src, IntRegs:$addr),
+def FSTD : InstARM<(ops DFPRegs:$src, op_addr_mode5:$addr),
"fstd $src, [$addr]",
- [(store DFPRegs:$src, IntRegs:$addr)]>;
+ [(store DFPRegs:$src, addr_mode5:$addr)]>;
def : Pat<(ARMcall tglobaladdr:$dst),
(bl tglobaladdr:$dst)>;