summaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-11-13 07:34:59 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-11-13 07:34:59 +0000
commit148cad8b308c0f8fdb37b368f2c911861dd2421a (patch)
treeb95481051e3ee6f057c173c8867c7da3223130d7 /lib/Target
parenta6ce05f82a5145beab06521a729c529b7efe2d6d (diff)
downloadexternal_llvm-148cad8b308c0f8fdb37b368f2c911861dd2421a.zip
external_llvm-148cad8b308c0f8fdb37b368f2c911861dd2421a.tar.gz
external_llvm-148cad8b308c0f8fdb37b368f2c911861dd2421a.tar.bz2
Fix pre- and post-indexed load / store encoding bugs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59230 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp38
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td40
-rw-r--r--lib/Target/ARM/ARMInstrInfo.h34
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td56
4 files changed, 98 insertions, 70 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index c583ed1..500d6ac 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -312,10 +312,12 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
case ARMII::DPSoRegFrm:
emitDataProcessingInstruction(MI);
break;
- case ARMII::LdStFrm:
+ case ARMII::LdFrm:
+ case ARMII::StFrm:
emitLoadStoreInstruction(MI);
break;
- case ARMII::LdStMiscFrm:
+ case ARMII::LdMiscFrm:
+ case ARMII::StMiscFrm:
emitMiscLoadStoreInstruction(MI);
break;
case ARMII::LdStMulFrm:
@@ -687,6 +689,8 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
+ unsigned Form = TID.TSFlags & ARMII::FormMask;
+ bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0;
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@@ -694,8 +698,17 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
- // Set first operand
unsigned OpIdx = 0;
+
+ // Operand 0 of a pre- and post-indexed store is the address base
+ // writeback. Skip it.
+ bool Skipped = false;
+ if (IsPrePost && Form == ARMII::StFrm) {
+ ++OpIdx;
+ Skipped = true;
+ }
+
+ // Set first operand
if (ImplicitRd)
// Special handling for implicit use (e.g. PC).
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd)
@@ -712,7 +725,7 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// If this is a two-address operand, skip it. e.g. LDR_PRE.
- if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
++OpIdx;
const MachineOperand &MO2 = MI.getOperand(OpIdx);
@@ -749,6 +762,8 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
+ unsigned Form = TID.TSFlags & ARMII::FormMask;
+ bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0;
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@@ -756,11 +771,20 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+ unsigned OpIdx = 0;
+
+ // Operand 0 of a pre- and post-indexed store is the address base
+ // writeback. Skip it.
+ bool Skipped = false;
+ if (IsPrePost && Form == ARMII::StMiscFrm) {
+ ++OpIdx;
+ Skipped = true;
+ }
+
// Set first operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
+ Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
// Set second operand
- unsigned OpIdx = 1;
if (ImplicitRn)
// Special handling for implicit use (e.g. PC).
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn)
@@ -769,7 +793,7 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// If this is a two-address operand, skip it. e.g. LDRH_POST.
- if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
++OpIdx;
const MachineOperand &MO2 = MI.getOperand(OpIdx);
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 192dfdf..c2d8df3 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -27,25 +27,27 @@ def BrMiscFrm : Format<4>;
def DPFrm : Format<5>;
def DPSoRegFrm : Format<6>;
-def LdStFrm : Format<7>;
-def LdStMiscFrm : Format<8>;
-def LdStMulFrm : Format<9>;
-
-def ArithMiscFrm : Format<10>;
-def ExtFrm : Format<11>;
-
-def VFPUnaryFrm : Format<12>;
-def VFPBinaryFrm : Format<13>;
-def VFPConv1Frm : Format<14>;
-def VFPConv2Frm : Format<15>;
-def VFPConv3Frm : Format<16>;
-def VFPConv4Frm : Format<17>;
-def VFPConv5Frm : Format<18>;
-def VFPLdStFrm : Format<19>;
-def VFPLdStMulFrm : Format<20>;
-def VFPMiscFrm : Format<21>;
-
-def ThumbFrm : Format<22>;
+def LdFrm : Format<7>;
+def StFrm : Format<8>;
+def LdMiscFrm : Format<9>;
+def StMiscFrm : Format<10>;
+def LdStMulFrm : Format<11>;
+
+def ArithMiscFrm : Format<12>;
+def ExtFrm : Format<13>;
+
+def VFPUnaryFrm : Format<14>;
+def VFPBinaryFrm : Format<15>;
+def VFPConv1Frm : Format<16>;
+def VFPConv2Frm : Format<17>;
+def VFPConv3Frm : Format<18>;
+def VFPConv4Frm : Format<19>;
+def VFPConv5Frm : Format<20>;
+def VFPLdStFrm : Format<21>;
+def VFPLdStMulFrm : Format<22>;
+def VFPMiscFrm : Format<23>;
+
+def ThumbFrm : Format<24>;
// Misc flag for data processing instructions that indicates whether
// the instruction has a Rn register operand.
diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h
index 1ef965c..476e5fd 100644
--- a/lib/Target/ARM/ARMInstrInfo.h
+++ b/lib/Target/ARM/ARMInstrInfo.h
@@ -87,30 +87,32 @@ namespace ARMII {
DPSoRegFrm = 6 << FormShift,
// Load and Store
- LdStFrm = 7 << FormShift,
- LdStMiscFrm = 8 << FormShift,
- LdStMulFrm = 9 << FormShift,
+ LdFrm = 7 << FormShift,
+ StFrm = 8 << FormShift,
+ LdMiscFrm = 9 << FormShift,
+ StMiscFrm = 10 << FormShift,
+ LdStMulFrm = 11 << FormShift,
// Miscellaneous arithmetic instructions
- ArithMiscFrm = 10 << FormShift,
+ ArithMiscFrm = 12 << FormShift,
// Extend instructions
- ExtFrm = 11 << FormShift,
+ ExtFrm = 13 << FormShift,
// VFP formats
- VFPUnaryFrm = 12 << FormShift,
- VFPBinaryFrm = 13 << FormShift,
- VFPConv1Frm = 14 << FormShift,
- VFPConv2Frm = 15 << FormShift,
- VFPConv3Frm = 16 << FormShift,
- VFPConv4Frm = 17 << FormShift,
- VFPConv5Frm = 18 << FormShift,
- VFPLdStFrm = 19 << FormShift,
- VFPLdStMulFrm = 20 << FormShift,
- VFPMiscFrm = 21 << FormShift,
+ VFPUnaryFrm = 14 << FormShift,
+ VFPBinaryFrm = 15 << FormShift,
+ VFPConv1Frm = 16 << FormShift,
+ VFPConv2Frm = 17 << FormShift,
+ VFPConv3Frm = 18 << FormShift,
+ VFPConv4Frm = 19 << FormShift,
+ VFPConv5Frm = 20 << FormShift,
+ VFPLdStFrm = 21 << FormShift,
+ VFPLdStMulFrm = 22 << FormShift,
+ VFPMiscFrm = 23 << FormShift,
// Thumb format
- ThumbFrm = 22 << FormShift,
+ ThumbFrm = 24 << FormShift,
//===------------------------------------------------------------------===//
// Field shifts - such shifts are used to set field while generating
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index d4588dd..a437ca7 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -615,134 +615,134 @@ let isBranch = 1, isTerminator = 1 in {
// Load
let isSimpleLoad = 1 in
-def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdStFrm,
+def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
"ldr", " $dst, $addr",
[(set GPR:$dst, (load addrmode2:$addr))]>;
// Special LDR for loads from non-pc-relative constpools.
let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1 in
-def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdStFrm,
+def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
"ldr", " $dst, $addr", []>;
// Loads with zero extension
-def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdStMiscFrm,
+def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
"ldr", "h $dst, $addr",
[(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
-def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdStFrm,
+def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
"ldr", "b $dst, $addr",
[(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
// Loads with sign extension
-def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdStMiscFrm,
+def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
"ldr", "sh $dst, $addr",
[(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
-def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdStMiscFrm,
+def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
"ldr", "sb $dst, $addr",
[(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
let mayLoad = 1 in {
// Load doubleword
-def LDRD : AI3ldd<(outs GPR:$dst), (ins addrmode3:$addr), LdStMiscFrm,
+def LDRD : AI3ldd<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
"ldr", "d $dst, $addr",
[]>, Requires<[IsARM, HasV5T]>;
// Indexed loads
def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
- (ins addrmode2:$addr), LdStFrm,
+ (ins addrmode2:$addr), LdFrm,
"ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
- (ins GPR:$base, am2offset:$offset), LdStFrm,
+ (ins GPR:$base, am2offset:$offset), LdFrm,
"ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
- (ins addrmode3:$addr), LdStMiscFrm,
+ (ins addrmode3:$addr), LdMiscFrm,
"ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
- (ins GPR:$base,am3offset:$offset), LdStMiscFrm,
+ (ins GPR:$base,am3offset:$offset), LdMiscFrm,
"ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
- (ins addrmode2:$addr), LdStFrm,
+ (ins addrmode2:$addr), LdFrm,
"ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
- (ins GPR:$base,am2offset:$offset), LdStFrm,
+ (ins GPR:$base,am2offset:$offset), LdFrm,
"ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
- (ins addrmode3:$addr), LdStMiscFrm,
+ (ins addrmode3:$addr), LdMiscFrm,
"ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
- (ins GPR:$base,am3offset:$offset), LdStMiscFrm,
- "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
+ (ins GPR:$base,am3offset:$offset), LdMiscFrm,
+ "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
- (ins addrmode3:$addr), LdStMiscFrm,
+ (ins addrmode3:$addr), LdMiscFrm,
"ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
- (ins GPR:$base,am3offset:$offset), LdStMiscFrm,
+ (ins GPR:$base,am3offset:$offset), LdMiscFrm,
"ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
}
// Store
-def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), LdStFrm,
+def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
"str", " $src, $addr",
[(store GPR:$src, addrmode2:$addr)]>;
// Stores with truncate
-def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), LdStMiscFrm,
+def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
"str", "h $src, $addr",
[(truncstorei16 GPR:$src, addrmode3:$addr)]>;
-def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), LdStFrm,
+def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
"str", "b $src, $addr",
[(truncstorei8 GPR:$src, addrmode2:$addr)]>;
// Store doubleword
let mayStore = 1 in
-def STRD : AI3std<(outs), (ins GPR:$src, addrmode3:$addr), LdStMiscFrm,
+def STRD : AI3std<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
"str", "d $src, $addr",
[]>, Requires<[IsARM, HasV5T]>;
// Indexed stores
def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base, am2offset:$offset), LdStFrm,
+ (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
"str", " $src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
def STR_POST : AI2stwpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset), LdStFrm,
+ (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
"str", " $src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb,
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am3offset:$offset), LdStMiscFrm,
+ (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
"str", "h $src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am3offset:$offset), LdStMiscFrm,
+ (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
"str", "h $src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
GPR:$base, am3offset:$offset))]>;
def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset), LdStFrm,
+ (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
"str", "b $src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset), LdStFrm,
+ (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
"str", "b $src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;