#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsMCInstLower.h"
+#include "MipsMCSymbolRefExpr.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h"
#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);
- 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;
+ 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);