#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/DebugInfo.h"
MipsMCInstLower MCInstLowering(Mang, *MF, *this);
unsigned Opc = MI->getOpcode();
-
- // If target is Mips1, expand double precision load/store to two single
- // precision loads/stores (and delay slot if MI is a load).
- if (Subtarget->isMips1() && (Opc == Mips::LDC1 || Opc == Mips::SDC1)) {
- SmallVector<MCInst, 4> MCInsts;
- const unsigned* SubReg =
- TM.getRegisterInfo()->getSubRegisters(MI->getOperand(0).getReg());
- MCInstLowering.LowerMips1F64LoadStore(MI, Opc, MCInsts,
- Subtarget->isLittle(), SubReg);
-
- for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
- I != MCInsts.end(); ++I)
- OutStreamer.EmitInstruction(*I);
-
- return;
- }
-
MCInst TmpInst0;
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);
const char *MipsAsmPrinter::getCurrentABIString() const {
switch (Subtarget->getTargetABI()) {
case MipsSubtarget::O32: return "abi32";
- case MipsSubtarget::O64: return "abiO64";
case MipsSubtarget::N32: return "abiN32";
case MipsSubtarget::N64: return "abi64";
case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64