aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanak@gmail.com>2011-08-12 21:30:06 +0000
committerAkira Hatanaka <ahatanak@gmail.com>2011-08-12 21:30:06 +0000
commit5c21c9e78ebbb5b766fac31bf30433926dcc2a5d (patch)
treed8550ce4ac592525bd51b8cd353fa2e6ac738591 /lib
parent4dfe220ad55e0f1e5edbf7cdd07f88497ddfdf25 (diff)
downloadexternal_llvm-5c21c9e78ebbb5b766fac31bf30433926dcc2a5d.zip
external_llvm-5c21c9e78ebbb5b766fac31bf30433926dcc2a5d.tar.gz
external_llvm-5c21c9e78ebbb5b766fac31bf30433926dcc2a5d.tar.bz2
Define unaligned load and store.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp17
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp11
-rw-r--r--lib/Target/Mips/MipsISelLowering.h2
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td7
4 files changed, 35 insertions, 2 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 049a939..4013d6c 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -25,6 +25,7 @@
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
@@ -54,6 +55,22 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MipsMCInstLower MCInstLowering(Mang, *MF, *this);
MCInst TmpInst0;
MCInstLowering.Lower(MI, TmpInst0);
+ unsigned Opc = MI->getOpcode();
+
+ // 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;
+ }
+
OutStreamer.EmitInstruction(TmpInst0);
}
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 54fa2d4..28ab854 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -195,6 +195,11 @@ MipsTargetLowering(MipsTargetMachine &TM)
setExceptionSelectorRegister(Mips::A1);
}
+bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const {
+ // FIXME: allow unaligned memory accesses for other types too.
+ return VT.getSimpleVT().SimpleTy == MVT::i32;
+}
+
MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const {
return MVT::i32;
}
@@ -1685,6 +1690,7 @@ WriteByValArg(SDValue& Chain, DebugLoc dl,
unsigned NumWords = (Flags.getByValSize() + 3) / 4;
unsigned LastWord = FirstWord + NumWords;
unsigned CurWord;
+ unsigned ByValAlign = Flags.getByValAlign();
// copy the first 4 words of byval arg to registers A0 - A3
for (CurWord = FirstWord; CurWord < std::min(LastWord, O32IntRegsSize);
@@ -1694,7 +1700,8 @@ WriteByValArg(SDValue& Chain, DebugLoc dl,
MVT::i32));
SDValue LoadVal = DAG.getLoad(MVT::i32, dl, Chain, LoadPtr,
MachinePointerInfo(),
- false, false, 0);
+ false, false, std::min(ByValAlign,
+ (unsigned )4));
MemOpChains.push_back(LoadVal.getValue(1));
unsigned DstReg = O32IntRegs[CurWord];
RegsToPass.push_back(std::make_pair(DstReg, LoadVal));
@@ -1710,7 +1717,7 @@ WriteByValArg(SDValue& Chain, DebugLoc dl,
SDValue Dst = DAG.getFrameIndex(LastFI, PtrType);
Chain = DAG.getMemcpy(Chain, dl, Dst, Src,
DAG.getConstant(SizeInBytes, MVT::i32),
- /*Align*/4,
+ /*Align*/ByValAlign,
/*isVolatile=*/false, /*AlwaysInline=*/false,
MachinePointerInfo(0), MachinePointerInfo(0));
MemOpChains.push_back(Chain);
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index cfb96ee..2d86619 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -95,6 +95,8 @@ namespace llvm {
public:
explicit MipsTargetLowering(MipsTargetMachine &TM);
+ virtual bool allowsUnalignedMemoryAccesses (EVT VT) const;
+
/// LowerOperation - Provide custom lowering hooks for some operations.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index d43961e9..0680c36 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -474,6 +474,13 @@ let usesCustomInserter = 1 in {
def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, "32">;
}
+// Unaligned memory load and store.
+// 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 USW :
+ MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "usw\t$dst, $addr", []>;
+
//===----------------------------------------------------------------------===//
// Instruction definition
//===----------------------------------------------------------------------===//