diff options
author | Akira Hatanaka <ahatanak@gmail.com> | 2011-08-17 18:49:18 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanak@gmail.com> | 2011-08-17 18:49:18 +0000 |
commit | b2e7558c40a485330e57073e9375ee6532104583 (patch) | |
tree | 35ed491705de807905bab5d25bae5b32184701ea | |
parent | 35ea5cfd46ef17a3486d75395200df81c798ed12 (diff) | |
download | bcm5719-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.cpp | 33 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 8 |
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 |