mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
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:
parent
cbfadfc4b3
commit
511961a44c
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user