[llvm-branch-commits] [llvm-branch] r98549 - in /llvm/branches/Apple/Hermes: ./ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/
Bob Wilson
bob.wilson at apple.com
Mon Mar 15 09:37:10 PDT 2010
Author: bwilson
Date: Mon Mar 15 11:37:10 2010
New Revision: 98549
URL: http://llvm.org/viewvc/llvm-project?rev=98549&view=rev
Log:
--- Merging r98395 into '.':
U lib/Target/ARM/ARMInstrNEON.td
--- Merging r98398 into '.':
U lib/Target/ARM/ARMLoadStoreOptimizer.cpp
--- Merging r98402 into '.':
G lib/Target/ARM/ARMLoadStoreOptimizer.cpp
--- Merging r98409 into '.':
U lib/Target/ARM/Thumb1RegisterInfo.cpp
U lib/Target/ARM/ARMInstrInfo.td
U lib/Target/ARM/ARMInstrVFP.td
U lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
U lib/Target/ARM/Thumb2SizeReduction.cpp
G lib/Target/ARM/ARMLoadStoreOptimizer.cpp
U lib/Target/ARM/ARMInstrThumb2.td
U lib/Target/ARM/ARMInstrFormats.td
U lib/Target/ARM/ARMInstrThumb.td
U lib/Target/ARM/Thumb1InstrInfo.cpp
U lib/Target/ARM/ARMConstantIslandPass.cpp
--- Merging r98427 into '.':
G lib/Target/ARM/ARMInstrInfo.td
G lib/Target/ARM/ARMInstrVFP.td
U lib/Target/ARM/ARMCodeEmitter.cpp
G lib/Target/ARM/ARMInstrFormats.td
U lib/Target/ARM/ARMBaseInstrInfo.h
Modified:
llvm/branches/Apple/Hermes/ (props changed)
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMBaseInstrInfo.h
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMConstantIslandPass.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrFormats.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrInfo.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrNEON.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb2.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrVFP.td
llvm/branches/Apple/Hermes/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1InstrInfo.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1RegisterInfo.cpp
llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb2SizeReduction.cpp
Propchange: llvm/branches/Apple/Hermes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 15 11:37:10 2010
@@ -1 +1 @@
-/llvm/trunk:96521,96525,96572,96621,96775,96825,96827,96990,97025,97065,97071,97538,97707,97757,97782,97797,98210,98270,98416
+/llvm/trunk:96521,96525,96572,96621,96775,96825,96827,96990,97025,97065,97071,97538,97707,97757,97782,97797,98210,98270,98395,98398,98402,98409,98416,98427
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMBaseInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMBaseInstrInfo.h?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMBaseInstrInfo.h (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMBaseInstrInfo.h Mon Mar 15 11:37:10 2010
@@ -58,12 +58,13 @@
Size4Bytes = 3,
Size2Bytes = 4,
- // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
- // and store ops
+ // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
+ // and store ops only. Generic "updating" flag is used for ld/st multiple.
IndexModeShift = 7,
IndexModeMask = 3 << IndexModeShift,
IndexModePre = 1,
IndexModePost = 2,
+ IndexModeUpd = 3,
//===------------------------------------------------------------------===//
// Instruction encoding formats.
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMCodeEmitter.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMCodeEmitter.cpp Mon Mar 15 11:37:10 2010
@@ -925,19 +925,26 @@
return Binary;
}
-void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
- const MachineInstr &MI) {
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ bool IsUpdating = (TID.TSFlags & ARMII::IndexModeMask) != 0;
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+ // Skip operand 0 of an instruction with base register update.
+ unsigned OpIdx = 0;
+ if (IsUpdating)
+ ++OpIdx;
+
// Set base address operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+ Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// Set addressing mode by modifying bits U(23) and P(24)
- const MachineOperand &MO = MI.getOperand(1);
+ const MachineOperand &MO = MI.getOperand(OpIdx++);
Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm()));
// Set bit W(21)
@@ -945,7 +952,7 @@
Binary |= 0x1 << ARMII::W_BitShift;
// Set registers
- for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpIdx+2, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
@@ -1322,17 +1329,25 @@
void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ bool IsUpdating = (TID.TSFlags & ARMII::IndexModeMask) != 0;
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+ // Skip operand 0 of an instruction with base register update.
+ unsigned OpIdx = 0;
+ if (IsUpdating)
+ ++OpIdx;
+
// Set base address operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+ Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// Set addressing mode by modifying bits U(23) and P(24)
- const MachineOperand &MO = MI.getOperand(1);
+ const MachineOperand &MO = MI.getOperand(OpIdx++);
Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm()));
// Set bit W(21)
@@ -1340,11 +1355,11 @@
Binary |= 0x1 << ARMII::W_BitShift;
// First register is encoded in Dd.
- Binary |= encodeVFPRd(MI, 5);
+ Binary |= encodeVFPRd(MI, OpIdx+2);
// Number of registers are encoded in offset field.
unsigned NumRegs = 1;
- for (unsigned i = 6, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpIdx+3, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMConstantIslandPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Mar 15 11:37:10 2010
@@ -1473,11 +1473,10 @@
bool MadeChange = false;
for (unsigned i = 0, e = PushPopMIs.size(); i != e; ++i) {
MachineInstr *MI = PushPopMIs[i];
- // First two operands are predicates, the third is a zero since there
- // is no writeback.
+ // First two operands are predicates.
if (MI->getOpcode() == ARM::tPOP_RET &&
- MI->getOperand(3).getReg() == ARM::PC &&
- MI->getNumExplicitOperands() == 4) {
+ MI->getOperand(2).getReg() == ARM::PC &&
+ MI->getNumExplicitOperands() == 3) {
BuildMI(MI->getParent(), MI->getDebugLoc(), TII->get(ARM::tBX_RET));
MI->eraseFromParent();
MadeChange = true;
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrFormats.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrFormats.td Mon Mar 15 11:37:10 2010
@@ -109,6 +109,7 @@
def IndexModeNone : IndexMode<0>;
def IndexModePre : IndexMode<1>;
def IndexModePost : IndexMode<2>;
+def IndexModeUpd : IndexMode<3>;
// Instruction execution domain.
class Domain<bits<2> val> {
@@ -779,18 +780,18 @@
// addrmode4 instructions
-class AXI4ld<dag oops, dag iops, Format f, InstrItinClass itin,
- string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
- asm, "", pattern> {
+class AXI4ld<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
+ asm, cstr, pattern> {
let Inst{20} = 1; // L bit
let Inst{22} = 0; // S bit
let Inst{27-25} = 0b100;
}
-class AXI4st<dag oops, dag iops, Format f, InstrItinClass itin,
- string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
- asm, "", pattern> {
+class AXI4st<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
+ asm, cstr, pattern> {
let Inst{20} = 0; // L bit
let Inst{22} = 0; // S bit
let Inst{27-25} = 0b100;
@@ -924,9 +925,9 @@
// Two-address instructions
class T1It<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
+ string asm, string cstr, list<dag> pattern>
: Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin,
- asm, "$lhs = $dst", pattern>;
+ asm, cstr, pattern>;
// Thumb1 instruction that can either be predicated or set CPSR.
class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
@@ -1123,6 +1124,10 @@
string opc, string asm, list<dag> pattern>
: Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>;
+// Two-address instructions
+class T2XIt<dag oops, dag iops, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, cstr, pattern>;
// T2Iidxldst - Thumb2 indexed load / store instructions.
class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
@@ -1224,10 +1229,10 @@
}
// Load / store multiple
-class AXDI5<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
- : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPLdStMulFrm, itin, asm, "", pattern> {
+class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
+ VFPLdStMulFrm, itin, asm, cstr, pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
let Inst{11-8} = 0b1011;
@@ -1236,10 +1241,10 @@
let Dom = VFPNeonDomain.Value;
}
-class AXSI5<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
- : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPLdStMulFrm, itin, asm, "", pattern> {
+class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
+ VFPLdStMulFrm, itin, asm, cstr, pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
let Inst{11-8} = 0b1010;
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrInfo.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrInfo.td Mon Mar 15 11:37:10 2010
@@ -363,7 +363,7 @@
def addrmode4 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode4", []> {
let PrintMethod = "printAddrMode4Operand";
- let MIOperandInfo = (ops GPR, i32imm);
+ let MIOperandInfo = (ops GPR:$addr, i32imm);
}
// addrmode5 := reg +/- imm8*4
@@ -371,7 +371,7 @@
def addrmode5 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode5", []> {
let PrintMethod = "printAddrMode5Operand";
- let MIOperandInfo = (ops GPR, i32imm);
+ let MIOperandInfo = (ops GPR:$base, i32imm);
}
// addrmode6 := reg with optional writeback
@@ -702,10 +702,11 @@
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
- def LDM_RET : AXI4ld<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
- []>;
+ def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_Br,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>;
// On non-Darwin platforms R9 is callee-saved.
let isCall = 1,
@@ -980,17 +981,31 @@
// Load / store multiple Instructions.
//
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
-def LDM : AXI4ld<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
- []>;
-
-let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def STM : AXI4st<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
- []>;
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
+def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeNone, LdStMulFrm, IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
+
+def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>;
+} // mayLoad, hasExtraDefRegAllocReq
+
+let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
+def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeNone, LdStMulFrm, IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
+
+def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs",
+ "$addr.addr = $wb", []>;
+} // mayStore, hasExtraSrcRegAllocReq
//===----------------------------------------------------------------------===//
// Move Instructions.
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrNEON.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrNEON.td Mon Mar 15 11:37:10 2010
@@ -98,16 +98,6 @@
// NEON operand definitions
//===----------------------------------------------------------------------===//
-// addrmode_neonldstm := reg
-//
-/* TODO: Take advantage of vldm.
-def addrmode_neonldstm : Operand<i32>,
- ComplexPattern<i32, 2, "SelectAddrModeNeonLdStM", []> {
- let PrintMethod = "printAddrNeonLdStMOperand";
- let MIOperandInfo = (ops GPR, i32imm);
-}
-*/
-
def h8imm : Operand<i8> {
let PrintMethod = "printHex8ImmOperand";
}
@@ -125,26 +115,6 @@
// NEON load / store instructions
//===----------------------------------------------------------------------===//
-/* TODO: Take advantage of vldm.
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
-def VLDMD : NI<(outs),
- (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
- let Inst{27-25} = 0b110;
- let Inst{20} = 1;
- let Inst{11-9} = 0b101;
-}
-
-def VLDMS : NI<(outs),
- (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
- let Inst{27-25} = 0b110;
- let Inst{20} = 1;
- let Inst{11-9} = 0b101;
-}
-}
-*/
-
// Use vldmia to load a Q register as a D register pair.
def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
"vldmia", "$addr, ${dst:dregpair}",
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb.td Mon Mar 15 11:37:10 2010
@@ -220,8 +220,8 @@
// FIXME: remove when we have a way to marking a MI with these properties.
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
-def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>,
+def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br,
+ "pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
let isCall = 1,
@@ -452,28 +452,37 @@
//
// These requires base address to be written back or one of the loaded regs.
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
def tLDM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
+ (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
IIC_iLoadm,
- "ldm${addr:submode}${p}\t$addr, $wb", []>,
+ "ldm${addr:submode}${p}\t$addr, $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),
+ IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>,
+ T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
+} // mayLoad, hasExtraDefRegAllocReq
+
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def tSTM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iStorem,
- "stm${addr:submode}${p}\t$addr, $wb", []>,
+def tSTM_UPD : T1It<(outs tGPR:$wb),
+ (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops),
+ IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs",
+ "$addr.addr = $wb", []>,
T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
-def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>,
+def tPOP : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br,
+ "pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
-def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "push${p}\t$wb", []>,
+def tPUSH : T1I<(outs), (ins pred:$p, reglist:$srcs, variable_ops), IIC_Br,
+ "push${p}\t$srcs", []>,
T1Misc<{0,1,0,?,?,?,?}>;
//===----------------------------------------------------------------------===//
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb2.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrThumb2.td Mon Mar 15 11:37:10 2010
@@ -987,29 +987,56 @@
// Load / store multiple Instructions.
//
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
-def t2LDM : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
+def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_iLoadm,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 0; // The W bit.
let Inst{20} = 1; // Load
}
-let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def t2STM : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_iLoadm,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts",
+ "$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 1; // The W bit.
+ let Inst{20} = 1; // Load
+}
+} // mayLoad, hasExtraDefRegAllocReq
+
+let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
+def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops), IIC_iStorem,
+ "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs", []> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-25} = 0b00;
+ let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
+ let Inst{22} = 0;
+ let Inst{21} = 0; // The W bit.
+ let Inst{20} = 0; // Store
+}
+
+def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IIC_iStorem,
+ "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs",
+ "$addr.addr = $wb", []> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-25} = 0b00;
+ let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
+ let Inst{22} = 0;
+ let Inst{21} = 1; // The W bit.
let Inst{20} = 0; // Store
}
+} // mayStore, hasExtraSrcRegAllocReq
//===----------------------------------------------------------------------===//
// Move Instructions.
@@ -1849,15 +1876,15 @@
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
- def t2LDM_RET : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
- []> {
+ def t2LDM_RET : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_Br,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts",
+ "$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 1; // The W bit.
let Inst{20} = 1; // Load
}
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrVFP.td?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMInstrVFP.td Mon Mar 15 11:37:10 2010
@@ -77,33 +77,61 @@
//
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
-def VLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpLoadm,
- "vldm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dsts,
+ variable_ops), IndexModeNone, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts", "", []> {
let Inst{20} = 1;
}
-def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpLoadm,
- "vldm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dsts,
+ variable_ops), IndexModeNone, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts", "", []> {
+ let Inst{20} = 1;
+}
+
+def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts",
+ "$addr.base = $wb", []> {
+ let Inst{20} = 1;
+}
+
+def VLDMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts",
+ "$addr.base = $wb", []> {
let Inst{20} = 1;
}
} // mayLoad, hasExtraDefRegAllocReq
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
-def VSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpStorem,
- "vstm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$srcs,
+ variable_ops), IndexModeNone, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs", "", []> {
+ let Inst{20} = 0;
+}
+
+def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$srcs,
+ variable_ops), IndexModeNone, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs", "", []> {
+ let Inst{20} = 0;
+}
+
+def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs",
+ "$addr.base = $wb", []> {
let Inst{20} = 0;
}
-def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpStorem,
- "vstm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VSTMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs",
+ "$addr.base = $wb", []> {
let Inst{20} = 0;
}
} // mayStore, hasExtraSrcRegAllocReq
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Mon Mar 15 11:37:10 2010
@@ -254,7 +254,6 @@
.addReg(Base, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs))
.addImm(Pred).addReg(PredReg);
- MIB.addReg(0); // Add optional writeback (0 for now).
for (unsigned i = 0; i != NumRegs; ++i)
MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
| getKillRegState(Regs[i].second));
@@ -443,7 +442,7 @@
case ARM::STM:
case ARM::t2LDM:
case ARM::t2STM:
- return (MI->getNumOperands() - 5) * 4;
+ return (MI->getNumOperands() - 4) * 4;
case ARM::VLDMS:
case ARM::VSTMS:
case ARM::VLDMD:
@@ -452,6 +451,21 @@
}
}
+static unsigned getUpdatingLSMultipleOpcode(unsigned Opc) {
+ switch (Opc) {
+ case ARM::LDM: return ARM::LDM_UPD;
+ case ARM::STM: return ARM::STM_UPD;
+ case ARM::t2LDM: return ARM::t2LDM_UPD;
+ case ARM::t2STM: return ARM::t2STM_UPD;
+ case ARM::VLDMS: return ARM::VLDMS_UPD;
+ case ARM::VLDMD: return ARM::VLDMD_UPD;
+ case ARM::VSTMS: return ARM::VSTMS_UPD;
+ case ARM::VSTMD: return ARM::VSTMD_UPD;
+ default: llvm_unreachable("Unhandled opcode!");
+ }
+ return 0;
+}
+
/// MergeBaseUpdateLSMultiple - Fold proceeding/trailing inc/dec of base
/// register into the LDM/STM/VLDM{D|S}/VSTM{D|S} op when possible:
///
@@ -470,117 +484,119 @@
MachineBasicBlock::iterator &I) {
MachineInstr *MI = MBBI;
unsigned Base = MI->getOperand(0).getReg();
+ bool BaseKill = MI->getOperand(0).isKill();
unsigned Bytes = getLSMultipleTransferSize(MI);
unsigned PredReg = 0;
ARMCC::CondCodes Pred = llvm::getInstrPredicate(MI, PredReg);
int Opcode = MI->getOpcode();
- bool isAM4 = Opcode == ARM::LDM || Opcode == ARM::t2LDM ||
- Opcode == ARM::STM || Opcode == ARM::t2STM;
+ DebugLoc dl = MI->getDebugLoc();
+ bool isAM4 = (Opcode == ARM::LDM || Opcode == ARM::t2LDM ||
+ Opcode == ARM::STM || Opcode == ARM::t2STM);
- if (isAM4) {
- if (ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()))
- return false;
+ bool DoMerge = false;
+ ARM_AM::AMSubMode Mode = ARM_AM::ia;
+ unsigned Offset = 0;
- // Can't use the updating AM4 sub-mode if the base register is also a dest
+ if (isAM4) {
+ // Can't use an updating ld/st if the base register is also a dest
// register. e.g. ldmdb r0!, {r0, r1, r2}. The behavior is undefined.
for (unsigned i = 3, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).getReg() == Base)
return false;
}
+ assert(!ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()));
+ Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
+ } else {
+ // VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
+ assert(!ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()));
+ Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
+ Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
+ }
- ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
- if (MBBI != MBB.begin()) {
- MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ // Try merging with the previous instruction.
+ if (MBBI != MBB.begin()) {
+ MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ if (isAM4) {
if (Mode == ARM_AM::ia &&
isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::db, true));
- MI->getOperand(4).setReg(Base);
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
- } else if (Mode == ARM_AM::ib &&
+ DoMerge = true;
+ Mode = ARM_AM::db;
+ } else if (isAM4 && Mode == ARM_AM::ib &&
isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::da, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
+ DoMerge = true;
+ Mode = ARM_AM::da;
+ }
+ } else {
+ if (Mode == ARM_AM::ia &&
+ isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
+ Mode = ARM_AM::db;
+ DoMerge = true;
}
}
+ if (DoMerge)
+ MBB.erase(PrevMBBI);
+ }
- if (MBBI != MBB.end()) {
- MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
+ // Try merging with the next instruction.
+ if (!DoMerge && MBBI != MBB.end()) {
+ MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
+ if (isAM4) {
if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) &&
isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
- return true;
+ DoMerge = true;
} else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) &&
isMatchingDecrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
- return true;
+ DoMerge = true;
}
- }
- } else {
- // VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
- if (ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()))
- return false;
-
- ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
- unsigned Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
- if (MBBI != MBB.begin()) {
- MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ } else {
if (Mode == ARM_AM::ia &&
- isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::db, true, Offset));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
+ isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
+ DoMerge = true;
}
}
-
- if (MBBI != MBB.end()) {
- MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
- if (Mode == ARM_AM::ia &&
- isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::ia, true, Offset));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
+ if (DoMerge) {
+ if (NextMBBI == I) {
+ Advance = true;
+ ++I;
}
- return true;
+ MBB.erase(NextMBBI);
}
}
- return false;
+ if (!DoMerge)
+ return false;
+
+ unsigned NewOpc = getUpdatingLSMultipleOpcode(Opcode);
+ MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
+ .addReg(Base, getDefRegState(true)) // WB base register
+ .addReg(Base, getKillRegState(BaseKill));
+ if (isAM4) {
+ // [t2]LDM_UPD, [t2]STM_UPD
+ MIB.addImm(ARM_AM::getAM4ModeImm(Mode, true))
+ .addImm(Pred).addReg(PredReg);
+ } else {
+ // VLDM[SD}_UPD, VSTM[SD]_UPD
+ MIB.addImm(ARM_AM::getAM5Opc(Mode, true, Offset))
+ .addImm(Pred).addReg(PredReg);
+ }
+ // Transfer the rest of operands.
+ for (unsigned OpNum = 4, e = MI->getNumOperands(); OpNum != e; ++OpNum)
+ MIB.addOperand(MI->getOperand(OpNum));
+ // Transfer memoperands.
+ (*MIB).setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
+
+ MBB.erase(MBBI);
+ return true;
}
static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) {
switch (Opc) {
case ARM::LDR: return ARM::LDR_PRE;
case ARM::STR: return ARM::STR_PRE;
- case ARM::VLDRS: return ARM::VLDMS;
- case ARM::VLDRD: return ARM::VLDMD;
- case ARM::VSTRS: return ARM::VSTMS;
- case ARM::VSTRD: return ARM::VSTMD;
+ case ARM::VLDRS: return ARM::VLDMS_UPD;
+ case ARM::VLDRD: return ARM::VLDMD_UPD;
+ case ARM::VSTRS: return ARM::VSTMS_UPD;
+ case ARM::VSTRD: return ARM::VSTMD_UPD;
case ARM::t2LDRi8:
case ARM::t2LDRi12:
return ARM::t2LDR_PRE;
@@ -596,10 +612,10 @@
switch (Opc) {
case ARM::LDR: return ARM::LDR_POST;
case ARM::STR: return ARM::STR_POST;
- case ARM::VLDRS: return ARM::VLDMS;
- case ARM::VLDRD: return ARM::VLDMD;
- case ARM::VSTRS: return ARM::VSTMS;
- case ARM::VSTRD: return ARM::VSTMD;
+ case ARM::VLDRS: return ARM::VLDMS_UPD;
+ case ARM::VLDRD: return ARM::VLDMD_UPD;
+ case ARM::VSTRS: return ARM::VSTMS_UPD;
+ case ARM::VSTRD: return ARM::VSTMD_UPD;
case ARM::t2LDRi8:
case ARM::t2LDRi12:
return ARM::t2LDR_POST;
@@ -624,14 +640,14 @@
unsigned Bytes = getLSMultipleTransferSize(MI);
int Opcode = MI->getOpcode();
DebugLoc dl = MI->getDebugLoc();
- bool isAM5 = Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
- Opcode == ARM::VSTRD || Opcode == ARM::VSTRS;
- bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
+ bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
+ Opcode == ARM::VSTRD || Opcode == ARM::VSTRS);
+ bool isAM2 = (Opcode == ARM::LDR || Opcode == ARM::STR);
if (isAM2 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0)
return false;
- else if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
+ if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
return false;
- else if (isT2i32Load(Opcode) || isT2i32Store(Opcode))
+ if (isT2i32Load(Opcode) || isT2i32Store(Opcode))
if (MI->getOperand(2).getImm() != 0)
return false;
@@ -648,33 +664,35 @@
unsigned NewOpc = 0;
// AM2 - 12 bits, thumb2 - 8 bits.
unsigned Limit = isAM5 ? 0 : (isAM2 ? 0x1000 : 0x100);
+
+ // Try merging with the previous instruction.
if (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
if (isMatchingDecrement(PrevMBBI, Base, Bytes, Limit, Pred, PredReg)) {
DoMerge = true;
AddSub = ARM_AM::sub;
- NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
} else if (!isAM5 &&
isMatchingIncrement(PrevMBBI, Base, Bytes, Limit,Pred,PredReg)) {
DoMerge = true;
- NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
}
- if (DoMerge)
+ if (DoMerge) {
+ NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
MBB.erase(PrevMBBI);
+ }
}
+ // Try merging with the next instruction.
if (!DoMerge && MBBI != MBB.end()) {
MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
if (!isAM5 &&
isMatchingDecrement(NextMBBI, Base, Bytes, Limit, Pred, PredReg)) {
DoMerge = true;
AddSub = ARM_AM::sub;
- NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
} else if (isMatchingIncrement(NextMBBI, Base, Bytes, Limit,Pred,PredReg)) {
DoMerge = true;
- NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
}
if (DoMerge) {
+ NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
if (NextMBBI == I) {
Advance = true;
++I;
@@ -689,22 +707,25 @@
bool isDPR = NewOpc == ARM::VLDMD || NewOpc == ARM::VSTMD;
unsigned Offset = 0;
if (isAM5)
- Offset = ARM_AM::getAM5Opc((AddSub == ARM_AM::sub)
- ? ARM_AM::db
- : ARM_AM::ia, true, (isDPR ? 2 : 1));
+ Offset = ARM_AM::getAM5Opc(AddSub == ARM_AM::sub ? ARM_AM::db : ARM_AM::ia,
+ true, (isDPR ? 2 : 1));
else if (isAM2)
Offset = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
else
Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
- if (isLd) {
- if (isAM5)
- // VLDMS, VLDMD
- BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
- .addReg(Base, getKillRegState(BaseKill))
- .addImm(Offset).addImm(Pred).addReg(PredReg)
- .addReg(Base, getDefRegState(true)) // WB base register
- .addReg(MI->getOperand(0).getReg(), RegState::Define);
- else if (isAM2)
+
+ if (isAM5) {
+ // VLDM[SD}_UPD, VSTM[SD]_UPD
+ MachineOperand &MO = MI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
+ .addReg(Base, getDefRegState(true)) // WB base register
+ .addReg(Base, getKillRegState(isLd ? BaseKill : false))
+ .addImm(Offset)
+ .addImm(Pred).addReg(PredReg)
+ .addReg(MO.getReg(), (isLd ? getDefRegState(true) :
+ getKillRegState(MO.isKill())));
+ } else if (isLd) {
+ if (isAM2)
// LDR_PRE, LDR_POST,
BuildMI(MBB, MBBI, dl, TII->get(NewOpc), MI->getOperand(0).getReg())
.addReg(Base, RegState::Define)
@@ -716,13 +737,7 @@
.addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
} else {
MachineOperand &MO = MI->getOperand(0);
- if (isAM5)
- // VSTMS, VSTMD
- BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset)
- .addImm(Pred).addReg(PredReg)
- .addReg(Base, getDefRegState(true)) // WB base register
- .addReg(MO.getReg(), getKillRegState(MO.isKill()));
- else if (isAM2)
+ if (isAM2)
// STR_PRE, STR_POST
BuildMI(MBB, MBBI, dl, TII->get(NewOpc), Base)
.addReg(MO.getReg(), getKillRegState(MO.isKill()))
@@ -897,7 +912,6 @@
.addReg(BaseReg, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addImm(Pred).addReg(PredReg)
- .addReg(0)
.addReg(EvenReg, getDefRegState(isLd) | getDeadRegState(EvenDeadKill))
.addReg(OddReg, getDefRegState(isLd) | getDeadRegState(OddDeadKill));
++NumLDRD2LDM;
@@ -906,7 +920,6 @@
.addReg(BaseReg, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addImm(Pred).addReg(PredReg)
- .addReg(0)
.addReg(EvenReg,
getKillRegState(EvenDeadKill) | getUndefRegState(EvenUndef))
.addReg(OddReg,
@@ -1144,7 +1157,8 @@
if (MBBI != MBB.begin() &&
(MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::tBX_RET)) {
MachineInstr *PrevMI = prior(MBBI);
- if (PrevMI->getOpcode() == ARM::LDM || PrevMI->getOpcode() == ARM::t2LDM) {
+ if (PrevMI->getOpcode() == ARM::LDM_UPD ||
+ PrevMI->getOpcode() == ARM::t2LDM_UPD) {
MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1);
if (MO.getReg() != ARM::LR)
return false;
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon Mar 15 11:37:10 2010
@@ -514,8 +514,10 @@
if (MO1.getReg() == ARM::SP) {
// FIXME
bool isLDM = (MI->getOpcode() == ARM::LDM ||
+ MI->getOpcode() == ARM::LDM_UPD ||
MI->getOpcode() == ARM::LDM_RET ||
MI->getOpcode() == ARM::t2LDM ||
+ MI->getOpcode() == ARM::t2LDM_UPD ||
MI->getOpcode() == ARM::t2LDM_RET);
O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
} else
@@ -802,11 +804,10 @@
void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum) {
O << "{";
- // Always skip the first operand, it's the optional (and implicit writeback).
- for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).isImplicit())
continue;
- if ((int)i != OpNum+1) O << ", ";
+ if ((int)i != OpNum) O << ", ";
printOperand(MI, i);
}
O << "}";
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1InstrInfo.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1InstrInfo.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1InstrInfo.cpp Mon Mar 15 11:37:10 2010
@@ -159,7 +159,6 @@
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
AddDefaultPred(MIB);
- MIB.addReg(0); // No write back.
for (unsigned i = CSI.size(); i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
// Add the callee-saved register as live-in. It's killed at the spill.
@@ -182,7 +181,6 @@
DebugLoc DL = MI->getDebugLoc();
MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::tPOP));
AddDefaultPred(MIB);
- MIB.addReg(0); // No write back.
bool NumRegs = false;
for (unsigned i = CSI.size(); i != 0; --i) {
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1RegisterInfo.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb1RegisterInfo.cpp Mon Mar 15 11:37:10 2010
@@ -791,9 +791,9 @@
isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
return true;
else if (MI->getOpcode() == ARM::tPOP) {
- // The first three operands are predicates and such. The last two are
+ // The first two operands are predicates. The last two are
// imp-def and imp-use of SP. Check everything in between.
- for (int i = 3, e = MI->getNumOperands() - 2; i != e; ++i)
+ for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i)
if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
return false;
return true;
@@ -864,7 +864,6 @@
++MBBI;
// Epilogue for vararg functions: pop LR to R3 and branch off it.
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
- .addReg(0) // No write back.
.addReg(ARM::R3, RegState::Define);
emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
Modified: llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb2SizeReduction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb2SizeReduction.cpp?rev=98549&r1=98548&r2=98549&view=diff
==============================================================================
--- llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb2SizeReduction.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Target/ARM/Thumb2SizeReduction.cpp Mon Mar 15 11:37:10 2010
@@ -121,9 +121,11 @@
{ ARM::t2STRHi12,ARM::tSTRH, 0, 5, 0, 1, 0, 0,0, 1 },
{ ARM::t2STRHs, ARM::tSTRH, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2LDM, ARM::tLDM, 0, 0, 0, 1, 1, 1,1, 1 },
{ ARM::t2LDM_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 1 },
- { ARM::t2LDM, ARM::tLDM, ARM::tPOP, 0, 0, 1, 1, 1,1, 1 },
- { ARM::t2STM, ARM::tSTM, ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 },
+ { ARM::t2LDM_UPD,ARM::tLDM_UPD,ARM::tPOP, 0, 0, 1, 1, 1,1, 1 },
+ // ARM::t2STM (with no basereg writeback) has no Thumb1 equivalent
+ { ARM::t2STM_UPD,ARM::tSTM_UPD,ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 },
};
class Thumb2SizeReduce : public MachineFunctionPass {
@@ -231,8 +233,9 @@
static bool VerifyLowRegs(MachineInstr *MI) {
unsigned Opc = MI->getOpcode();
- bool isPCOk = (Opc == ARM::t2LDM_RET) || (Opc == ARM::t2LDM);
- bool isLROk = (Opc == ARM::t2STM);
+ bool isPCOk = (Opc == ARM::t2LDM_RET || Opc == ARM::t2LDM ||
+ Opc == ARM::t2LDM_UPD);
+ bool isLROk = (Opc == ARM::t2STM_UPD);
bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi);
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -307,19 +310,35 @@
HasShift = true;
OpNum = 4;
break;
- case ARM::t2LDM_RET:
- case ARM::t2LDM:
- case ARM::t2STM: {
- OpNum = 0;
+ case ARM::t2LDM: {
unsigned BaseReg = MI->getOperand(0).getReg();
- unsigned Mode = MI->getOperand(1).getImm();
- if (BaseReg == ARM::SP && ARM_AM::getAM4WBFlag(Mode)) {
- Opc = Entry.NarrowOpc2;
- OpNum = 2;
- } else if (Entry.WideOpc == ARM::t2LDM_RET ||
- !isARMLowRegister(BaseReg) ||
- !ARM_AM::getAM4WBFlag(Mode) ||
- ARM_AM::getAM4SubMode(Mode) != ARM_AM::ia) {
+ ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
+ if (!isARMLowRegister(BaseReg) || Mode != ARM_AM::ia)
+ return false;
+ OpNum = 0;
+ isLdStMul = true;
+ break;
+ }
+ case ARM::t2LDM_RET: {
+ unsigned BaseReg = MI->getOperand(1).getReg();
+ if (BaseReg != ARM::SP)
+ return false;
+ Opc = Entry.NarrowOpc2; // tPOP_RET
+ OpNum = 3;
+ isLdStMul = true;
+ break;
+ }
+ case ARM::t2LDM_UPD:
+ case ARM::t2STM_UPD: {
+ OpNum = 0;
+ unsigned BaseReg = MI->getOperand(1).getReg();
+ ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(2).getImm());
+ if (BaseReg == ARM::SP &&
+ (Entry.WideOpc == ARM::t2LDM_UPD && Mode == ARM_AM::ia) ||
+ (Entry.WideOpc == ARM::t2STM_UPD && Mode == ARM_AM::db)) {
+ Opc = Entry.NarrowOpc2; // tPOP or tPUSH
+ OpNum = 3;
+ } else if (!isARMLowRegister(BaseReg) || Mode != ARM_AM::ia) {
return false;
}
isLdStMul = true;
More information about the llvm-branch-commits
mailing list