aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/Thumb2SizeReduction.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-12-14 03:36:38 +0000
committerBill Wendling <isanbard@gmail.com>2010-12-14 03:36:38 +0000
commitf4caf69720d807573c50d41aa06bcec1c99bdbbd (patch)
treebdf33e0c29180acbfd4f2f74dcfd78e3d1866bdf /lib/Target/ARM/Thumb2SizeReduction.cpp
parent0c1aec18911f2a67fb37b6593d08f4f8cb7e18ef (diff)
The tLDR et al instructions were emitting either a reg/reg or reg/imm
instruction based on the t_addrmode_s# mode and what it returned. There is some obvious badness to this. In particular, it's hard to do MC-encoding when the instruction may change out from underneath you after the t_addrmode_s# variable is finally resolved. The solution is to revert a long-ago change that merged the reg/reg and reg/imm versions. There is the addition of several new addressing modes. They no longer have extraneous operands associated with them. I.e., if it's reg/reg we don't have to have a dummy zero immediate tacked on to the SDNode. There are some obvious cleanups here, which will happen shortly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121747 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Thumb2SizeReduction.cpp')
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp65
1 files changed, 36 insertions, 29 deletions
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 65e210ede1..a8badf7173 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -105,19 +105,19 @@ namespace {
// FIXME: Clean this up after splitting each Thumb load / store opcode
// into multiple ones.
{ ARM::t2LDRi12,ARM::tLDRi, ARM::tLDRspi, 5, 8, 1, 0, 0,0, 1 },
- { ARM::t2LDRs, ARM::tLDR, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2LDRs, ARM::tLDRr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2LDRBi12,ARM::tLDRBi, 0, 5, 0, 1, 0, 0,0, 1 },
- { ARM::t2LDRBs, ARM::tLDRB, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2LDRBs, ARM::tLDRBr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2LDRHi12,ARM::tLDRHi, 0, 5, 0, 1, 0, 0,0, 1 },
- { ARM::t2LDRHs, ARM::tLDRH, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2LDRHs, ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2LDRSBs,ARM::tLDRSB, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2LDRSHs,ARM::tLDRSH, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2STRi12,ARM::tSTRi, ARM::tSTRspi, 5, 8, 1, 0, 0,0, 1 },
- { ARM::t2STRs, ARM::tSTR, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2STRs, ARM::tSTRr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2STRBi12,ARM::tSTRBi, 0, 5, 0, 1, 0, 0,0, 1 },
- { ARM::t2STRBs, ARM::tSTRB, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2STRBs, ARM::tSTRBr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2STRHi12,ARM::tSTRHi, 0, 5, 0, 1, 0, 0,0, 1 },
- { ARM::t2STRHs, ARM::tSTRH, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2STRHs, ARM::tSTRHr, 0, 0, 0, 1, 0, 0,0, 1 },
{ ARM::t2LDMIA, ARM::tLDMIA, 0, 0, 0, 1, 1, 1,1, 1 },
{ ARM::t2LDMIA_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 1 },
@@ -273,7 +273,6 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
bool HasShift = false;
bool HasOffReg = true;
bool isLdStMul = false;
- bool InsertImmOffset = true;
unsigned Opc = Entry.NarrowOpc1;
unsigned OpNum = 3; // First 'rest' of operands.
uint8_t ImmLimit = Entry.Imm1Limit;
@@ -282,39 +281,41 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
default:
llvm_unreachable("Unexpected Thumb2 load / store opcode!");
case ARM::t2LDRi12:
- case ARM::t2STRi12: {
- unsigned BaseReg = MI->getOperand(1).getReg();
- if (BaseReg == ARM::SP) {
+ case ARM::t2STRi12:
+ if (MI->getOperand(1).getReg() == ARM::SP) {
Opc = Entry.NarrowOpc2;
ImmLimit = Entry.Imm2Limit;
HasOffReg = false;
}
+
Scale = 4;
- if (MI->getOperand(2).isImm())
+
+ if (MI->getOperand(2).isImm()) {
HasImmOffset = true;
- else {
+ HasOffReg = false;
+ } else {
if (Entry.WideOpc == ARM::t2LDRi12) {
Opc = ARM::tLDRpci;
OpNum = 2;
}
+
HasImmOffset = false;
- InsertImmOffset = false;
HasBaseReg = false;
HasOffReg = false;
}
break;
- }
case ARM::t2LDRBi12:
case ARM::t2STRBi12:
- if (MI->getOperand(2).isImm())
+ if (MI->getOperand(2).isImm()) {
HasImmOffset = true;
- else {
+ HasOffReg = false;
+ } else {
if (Entry.WideOpc == ARM::t2LDRBi12) {
Opc = ARM::tLDRpci;
OpNum = 2;
}
+
HasImmOffset = false;
- InsertImmOffset = false;
HasBaseReg = false;
HasOffReg = false;
}
@@ -322,15 +323,16 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
case ARM::t2LDRHi12:
case ARM::t2STRHi12:
Scale = 2;
- if (MI->getOperand(2).isImm())
+ if (MI->getOperand(2).isImm()) {
HasImmOffset = true;
- else {
+ HasOffReg = false;
+ } else {
if (Entry.WideOpc == ARM::t2LDRHi12) {
Opc = ARM::tLDRpci;
OpNum = 2;
}
+
HasImmOffset = false;
- InsertImmOffset = false;
HasBaseReg = false;
HasOffReg = false;
}
@@ -351,6 +353,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
unsigned BaseReg = MI->getOperand(0).getReg();
if (!isARMLowRegister(BaseReg) || Entry.WideOpc != ARM::t2LDMIA)
return false;
+
// For the non-writeback version (this one), the base register must be
// one of the registers being loaded.
bool isOK = false;
@@ -360,6 +363,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
break;
}
}
+
if (!isOK)
return false;
@@ -381,6 +385,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
case ARM::t2STMIA_UPD:
case ARM::t2STMDB_UPD: {
OpNum = 0;
+
unsigned BaseReg = MI->getOperand(1).getReg();
if (BaseReg == ARM::SP &&
(Entry.WideOpc == ARM::t2LDMIA_UPD ||
@@ -392,6 +397,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
Entry.WideOpc != ARM::t2STMIA_UPD)) {
return false;
}
+
isLdStMul = true;
break;
}
@@ -402,6 +408,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
if (HasShift) {
OffsetReg = MI->getOperand(2).getReg();
OffsetKill = MI->getOperand(2).isKill();
+
if (MI->getOperand(3).getImm())
// Thumb1 addressing mode doesn't support shift.
return false;
@@ -411,24 +418,24 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
if (HasImmOffset) {
OffsetImm = MI->getOperand(2).getImm();
unsigned MaxOffset = ((1 << ImmLimit) - 1) * Scale;
- if ((OffsetImm & (Scale-1)) || OffsetImm > MaxOffset)
+
+ if ((OffsetImm & (Scale - 1)) || OffsetImm > MaxOffset)
// Make sure the immediate field fits.
return false;
}
// Add the 16-bit load / store instruction.
- // FIXME: Thumb1 addressing mode encode both immediate and register offset.
DebugLoc dl = MI->getDebugLoc();
MachineInstrBuilder MIB = BuildMI(MBB, *MI, dl, TII->get(Opc));
if (!isLdStMul) {
MIB.addOperand(MI->getOperand(0));
- if (HasBaseReg) MIB.addOperand(MI->getOperand(1));
- if (InsertImmOffset && Opc != ARM::tLDRSB && Opc != ARM::tLDRSH) {
- // tLDRSB and tLDRSH do not have an immediate offset field. On the other
- // hand, it must have an offset register.
- // FIXME: Remove this special case.
- MIB.addImm(OffsetImm/Scale);
- }
+
+ if (HasBaseReg)
+ MIB.addOperand(MI->getOperand(1));
+
+ if (HasImmOffset)
+ MIB.addImm(OffsetImm / Scale);
+
assert((!HasShift || OffsetReg) && "Invalid so_reg load / store address!");
if (HasOffReg)