Add support for half-word unaligned loads and stores.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137848 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2011-08-17 18:49:18 +00:00
parent cbfadfc4b3
commit 511961a44c
3 changed files with 31 additions and 14 deletions

View File

@ -77,17 +77,28 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInstLowering.Lower(MI, TmpInst0); MCInstLowering.Lower(MI, TmpInst0);
// Convert aligned loads/stores to their unaligned counterparts. // Convert aligned loads/stores to their unaligned counterparts.
// FIXME: expand other unaligned memory accesses too. if (!MI->memoperands_empty()) {
if ((Opc == Mips::LW || Opc == Mips::SW) && !MI->memoperands_empty() && unsigned NaturalAlignment, UnalignedOpc;
(*MI->memoperands_begin())->getAlignment() < 4) {
MCInst Directive; switch (Opc) {
Directive.setOpcode(Mips::MACRO); case Mips::LW: NaturalAlignment = 4; UnalignedOpc = Mips::ULW; break;
OutStreamer.EmitInstruction(Directive); case Mips::SW: NaturalAlignment = 4; UnalignedOpc = Mips::USW; break;
TmpInst0.setOpcode(Opc == Mips::LW ? Mips::ULW : Mips::USW); case Mips::LH: NaturalAlignment = 2; UnalignedOpc = Mips::ULH; break;
OutStreamer.EmitInstruction(TmpInst0); case Mips::LHu: NaturalAlignment = 2; UnalignedOpc = Mips::ULHu; break;
Directive.setOpcode(Mips::NOMACRO); case Mips::SH: NaturalAlignment = 2; UnalignedOpc = Mips::USH; break;
OutStreamer.EmitInstruction(Directive); default: NaturalAlignment = 0;
return; }
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); OutStreamer.EmitInstruction(TmpInst0);

View File

@ -218,8 +218,8 @@ MipsTargetLowering(MipsTargetMachine &TM)
} }
bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const { bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const {
// FIXME: allow unaligned memory accesses for other types too. MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
return VT.getSimpleVT().SimpleTy == MVT::i32; return SVT == MVT::i32 || SVT == MVT::i16;
} }
MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const { MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const {

View File

@ -483,12 +483,18 @@ let usesCustomInserter = 1 in {
def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, "32">; 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. // Replaces LW or SW during MCInstLowering if memory access is unaligned.
def ULW : def ULW :
MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulw\t$dst, $addr", []>; 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 : def USW :
MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "usw\t$dst, $addr", []>; 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 // Instruction definition