Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: src/IceAssemblerMIPS32.cpp

Issue 2446273003: [SubZero] Generate relocations for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceAssemblerMIPS32.h ('k') | src/IceInstMIPS32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceAssemblerMIPS32.cpp
diff --git a/src/IceAssemblerMIPS32.cpp b/src/IceAssemblerMIPS32.cpp
index ce690426746ffa73d892fcaeee110cc25ed91476..ca8a6311abfbc52481ffab84f82d8444ac8b1885 100644
--- a/src/IceAssemblerMIPS32.cpp
+++ b/src/IceAssemblerMIPS32.cpp
@@ -225,6 +225,30 @@ void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt,
emitInst(Opcode);
}
+void AssemblerMIPS32::emitRtRsImm16Rel(IValueT Opcode, const Operand *OpRt,
+ const Operand *OpRs,
+ const Operand *OpImm,
+ const RelocOp Reloc,
+ const char *InsnName) {
+ const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
+ const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
+ uint32_t Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpImm)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpImm)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error(std::string(InsnName) + ": Invalid 3rd operand");
+ }
+
+ Opcode |= Rs << 21;
+ Opcode |= Rt << 16;
+ Opcode |= Imm16 & 0xffff;
+
+ emitInst(Opcode);
+}
+
void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt,
const Operand *OpRs, const uint32_t Imm,
const char *InsnName) {
@@ -347,6 +371,12 @@ void AssemblerMIPS32::abs_s(const Operand *OpFd, const Operand *OpFs) {
emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "abs.s");
}
+void AssemblerMIPS32::addi(const Operand *OpRt, const Operand *OpRs,
+ const uint32_t Imm) {
+ static constexpr IValueT Opcode = 0x20000000;
+ emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addi");
+}
+
void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs,
const Operand *OpFt) {
static constexpr IValueT Opcode = 0x44000000;
@@ -365,6 +395,12 @@ void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs,
emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu");
}
+void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs,
+ const Operand *OpImm, const RelocOp Reloc) {
+ static constexpr IValueT Opcode = 0x24000000;
+ emitRtRsImm16Rel(Opcode, OpRt, OpRs, OpImm, Reloc, "addiu");
+}
+
void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs,
const Operand *OpRt) {
static constexpr IValueT Opcode = 0x00000021;
@@ -542,11 +578,110 @@ void AssemblerMIPS32::divu(const Operand *OpRs, const Operand *OpRt) {
emitRsRt(Opcode, OpRs, OpRt, "divu");
}
-void AssemblerMIPS32::lui(const Operand *OpRt, const uint16_t Imm) {
+MIPS32Fixup *AssemblerMIPS32::createMIPS32Fixup(const RelocOp Reloc,
+ const Constant *RelOp) {
+ MIPS32Fixup *Fixup = new (allocate<MIPS32Fixup>()) MIPS32Fixup();
+ switch (Reloc) {
+ case RelocOp::RO_Hi:
+ Fixup->set_kind(llvm::ELF::R_MIPS_HI16);
+ break;
+ case RelocOp::RO_Lo:
+ Fixup->set_kind(llvm::ELF::R_MIPS_LO16);
+ break;
+ case RelocOp::RO_Jal:
+ Fixup->set_kind(llvm::ELF::R_MIPS_26);
+ break;
+ default:
+ llvm::report_fatal_error("Fixup: Invalid Reloc type");
+ break;
+ }
+ Fixup->set_value(RelOp);
+ Buffer.installFixup(Fixup);
+ return Fixup;
+}
+
+size_t MIPS32Fixup::emit(GlobalContext *Ctx, const Assembler &Asm) const {
+ if (!BuildDefs::dump())
+ return InstMIPS32::InstSize;
+ Ostream &Str = Ctx->getStrEmit();
+ IValueT Inst = Asm.load<IValueT>(position());
+ const auto Symbol = symbol().toString();
+ Str << "\t"
+ << ".word " << llvm::format_hex(Inst, 8) << " # ";
+ switch (kind()) {
+ case llvm::ELF::R_MIPS_HI16:
+ Str << "R_MIPS_HI16 ";
+ break;
+ case llvm::ELF::R_MIPS_LO16:
+ Str << "R_MIPS_LO16 ";
+ break;
+ case llvm::ELF::R_MIPS_26:
+ Str << "R_MIPS_26 ";
+ break;
+ default:
+ Str << "Unknown ";
+ break;
+ }
+ Str << Symbol << "\n";
+ return InstMIPS32::InstSize;
+}
+
+void MIPS32Fixup::emitOffset(Assembler *Asm) const {
+ const IValueT Inst = Asm->load<IValueT>(position());
+ IValueT ImmMask = 0;
+ const IValueT Imm = offset();
+ if (kind() == llvm::ELF::R_MIPS_26) {
+ ImmMask = 0x03FFFFFF;
+ } else {
+ ImmMask = 0x0000FFFF;
+ }
+ Asm->store(position(), (Inst & ~ImmMask) | (Imm & ImmMask));
+}
+
+void AssemblerMIPS32::jal(const ConstantRelocatable *Target) {
+ IValueT Opcode = 0x0C000000;
+ emitFixup(createMIPS32Fixup(RelocOp::RO_Jal, Target));
+ emitInst(Opcode);
+ nop();
+}
+
+void AssemblerMIPS32::lui(const Operand *OpRt, const Operand *OpImm,
+ const RelocOp Reloc) {
IValueT Opcode = 0x3C000000;
const IValueT Rt = encodeGPRegister(OpRt, "Rt", "lui");
+ IValueT Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpImm)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpImm)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error("lui: Invalid 2nd operand");
+ }
+
+ Opcode |= Rt << 16;
+ Opcode |= Imm16;
+ emitInst(Opcode);
+}
+
+void AssemblerMIPS32::ldc1(const Operand *OpRt, const Operand *OpBase,
+ const Operand *OpOff, const RelocOp Reloc) {
+ IValueT Opcode = 0xD4000000;
+ const IValueT Rt = encodeFPRegister(OpRt, "Ft", "ldc1");
+ const IValueT Base = encodeGPRegister(OpBase, "Base", "ldc1");
+ IValueT Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error("ldc1: Invalid 2nd operand");
+ }
+
+ Opcode |= Base << 21;
Opcode |= Rt << 16;
- Opcode |= Imm;
+ Opcode |= Imm16;
emitInst(Opcode);
}
@@ -583,6 +718,27 @@ void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase,
}
}
+void AssemblerMIPS32::lwc1(const Operand *OpRt, const Operand *OpBase,
+ const Operand *OpOff, const RelocOp Reloc) {
+ IValueT Opcode = 0xC4000000;
+ const IValueT Rt = encodeFPRegister(OpRt, "Ft", "lwc1");
+ const IValueT Base = encodeGPRegister(OpBase, "Base", "lwc1");
+ IValueT Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error("lwc1: Invalid 2nd operand");
+ }
+
+ Opcode |= Base << 21;
+ Opcode |= Rt << 16;
+ Opcode |= Imm16;
+ emitInst(Opcode);
+}
+
void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) {
static constexpr IValueT Opcode = 0x44000000;
emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1");
@@ -620,7 +776,7 @@ void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) {
if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
(isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
if (isScalarFloatingType(DstType)) {
- mtc1(OpRd, OpRs);
+ mtc1(OpRs, OpRd);
} else {
mfc1(OpRd, OpRs);
}
@@ -758,6 +914,11 @@ void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs,
emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s");
}
+void AssemblerMIPS32::mult(const Operand *OpRs, const Operand *OpRt) {
+ static constexpr IValueT Opcode = 0x00000018;
+ emitRsRt(Opcode, OpRs, OpRt, "mult");
+}
+
void AssemblerMIPS32::multu(const Operand *OpRs, const Operand *OpRt) {
static constexpr IValueT Opcode = 0x00000019;
emitRsRt(Opcode, OpRs, OpRt, "multu");
@@ -875,6 +1036,27 @@ void AssemblerMIPS32::subu(const Operand *OpRd, const Operand *OpRs,
emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "subu");
}
+void AssemblerMIPS32::sdc1(const Operand *OpRt, const Operand *OpBase,
+ const Operand *OpOff, const RelocOp Reloc) {
+ IValueT Opcode = 0xF4000000;
+ const IValueT Rt = encodeFPRegister(OpRt, "Ft", "sdc1");
+ const IValueT Base = encodeGPRegister(OpBase, "Base", "sdc1");
+ IValueT Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error("sdc1: Invalid 2nd operand");
+ }
+
+ Opcode |= Base << 21;
+ Opcode |= Rt << 16;
+ Opcode |= Imm16;
+ emitInst(Opcode);
+}
+
void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
const uint32_t Offset) {
switch (OpRt->getType()) {
@@ -908,6 +1090,27 @@ void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
}
}
+void AssemblerMIPS32::swc1(const Operand *OpRt, const Operand *OpBase,
+ const Operand *OpOff, const RelocOp Reloc) {
+ IValueT Opcode = 0xE4000000;
+ const IValueT Rt = encodeFPRegister(OpRt, "Ft", "swc1");
+ const IValueT Base = encodeGPRegister(OpBase, "Base", "swc1");
+ IValueT Imm16 = 0;
+
+ if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) {
+ emitFixup(createMIPS32Fixup(Reloc, OpRel));
+ } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) {
+ Imm16 = C32->getValue();
+ } else {
+ llvm::report_fatal_error("swc1: Invalid 2nd operand");
+ }
+
+ Opcode |= Base << 21;
+ Opcode |= Rt << 16;
+ Opcode |= Imm16;
+ emitInst(Opcode);
+}
+
void AssemblerMIPS32::teq(const Operand *OpRs, const Operand *OpRt,
const uint32_t TrapCode) {
IValueT Opcode = 0x00000034;
@@ -931,12 +1134,12 @@ void AssemblerMIPS32::trunc_l_s(const Operand *OpFd, const Operand *OpFs) {
void AssemblerMIPS32::trunc_w_d(const Operand *OpFd, const Operand *OpFs) {
static constexpr IValueT Opcode = 0x4400000D;
- emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "trunc.w.d");
+ emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "trunc.w.d");
}
void AssemblerMIPS32::trunc_w_s(const Operand *OpFd, const Operand *OpFs) {
static constexpr IValueT Opcode = 0x4400000D;
- emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "trunc.w.s");
+ emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "trunc.w.s");
}
void AssemblerMIPS32::xor_(const Operand *OpRd, const Operand *OpRs,
« no previous file with comments | « src/IceAssemblerMIPS32.h ('k') | src/IceInstMIPS32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698