summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanak@gmail.com>2011-08-17 18:49:18 +0000
committerAkira Hatanaka <ahatanak@gmail.com>2011-08-17 18:49:18 +0000
commitb2e7558c40a485330e57073e9375ee6532104583 (patch)
tree35ed491705de807905bab5d25bae5b32184701ea
parent35ea5cfd46ef17a3486d75395200df81c798ed12 (diff)
downloadbcm5719-llvm-b2e7558c40a485330e57073e9375ee6532104583.tar.gz
bcm5719-llvm-b2e7558c40a485330e57073e9375ee6532104583.zip
Add support for half-word unaligned loads and stores.
llvm-svn: 137848
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp33
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp4
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.td8
3 files changed, 31 insertions, 14 deletions
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 28358abc00f..9b7e1914013 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -77,17 +77,28 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInstLowering.Lower(MI, TmpInst0);
// Convert aligned loads/stores to their unaligned counterparts.
- // FIXME: expand other unaligned memory accesses too.
- if ((Opc == Mips::LW || Opc == Mips::SW) && !MI->memoperands_empty() &&
- (*MI->memoperands_begin())->getAlignment() < 4) {
- MCInst Directive;
- Directive.setOpcode(Mips::MACRO);
- OutStreamer.EmitInstruction(Directive);
- TmpInst0.setOpcode(Opc == Mips::LW ? Mips::ULW : Mips::USW);
- OutStreamer.EmitInstruction(TmpInst0);
- Directive.setOpcode(Mips::NOMACRO);
- OutStreamer.EmitInstruction(Directive);
- return;
+ if (!MI->memoperands_empty()) {
+ unsigned NaturalAlignment, UnalignedOpc;
+
+ switch (Opc) {
+ case Mips::LW: NaturalAlignment = 4; UnalignedOpc = Mips::ULW; break;
+ case Mips::SW: NaturalAlignment = 4; UnalignedOpc = Mips::USW; break;
+ case Mips::LH: NaturalAlignment = 2; UnalignedOpc = Mips::ULH; break;
+ case Mips::LHu: NaturalAlignment = 2; UnalignedOpc = Mips::ULHu; break;
+ case Mips::SH: NaturalAlignment = 2; UnalignedOpc = Mips::USH; break;
+ default: NaturalAlignment = 0;
+ }
+
+ if ((*MI->memoperands_begin())->getAlignment() < NaturalAlignment) {
+ MCInst Directive;
+ Directive.setOpcode(Mips::MACRO);
+ OutStreamer.EmitInstruction(Directive);
+ TmpInst0.setOpcode(UnalignedOpc);
+ OutStreamer.EmitInstruction(TmpInst0);
+ Directive.setOpcode(Mips::NOMACRO);
+ OutStreamer.EmitInstruction(Directive);
+ return;
+ }
}
OutStreamer.EmitInstruction(TmpInst0);
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index eb049f1868a..2ac7a266db8 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -218,8 +218,8 @@ MipsTargetLowering(MipsTargetMachine &TM)
}
bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const {
- // FIXME: allow unaligned memory accesses for other types too.
- return VT.getSimpleVT().SimpleTy == MVT::i32;
+ MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
+ return SVT == MVT::i32 || SVT == MVT::i16;
}
MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const {
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index a30761dbbab..e41c78ab458 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -483,12 +483,18 @@ let usesCustomInserter = 1 in {
def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, "32">;
}
-// Unaligned memory load and store.
+// Unaligned loads and stores.
// Replaces LW or SW during MCInstLowering if memory access is unaligned.
def ULW :
MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulw\t$dst, $addr", []>;
+def ULH :
+ MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulh\t$dst, $addr", []>;
+def ULHu :
+ MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulhu\t$dst, $addr", []>;
def USW :
MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "usw\t$dst, $addr", []>;
+def USH :
+ MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "ush\t$dst, $addr", []>;
//===----------------------------------------------------------------------===//
// Instruction definition
OpenPOWER on IntegriCloud