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

Unified Diff: src/IceAssemblerMIPS32.cpp

Issue 2341713003: Subzero, MIPS32: Floating point support in ELF output (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Encodings for more existing instructions, alphabetized Created 4 years, 3 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 b9ddff1cf3dddca2e063e13dd7fe942b85ebc64f..54188b256d27d571415ab60f69eddda30119e345 100644
--- a/src/IceAssemblerMIPS32.cpp
+++ b/src/IceAssemblerMIPS32.cpp
@@ -102,6 +102,8 @@ void AssemblerMIPS32::bindCfgNodeLabel(const CfgNode *Node) {
this->bind(L);
}
+namespace {
+
// Checks that Offset can fit in imm16 constant of branch instruction.
void assertCanEncodeBranchOffset(IOffsetT Offset) {
(void)Offset;
@@ -118,34 +120,26 @@ IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
return (Inst & ~kBranchOffsetMask) | Offset;
}
-IOffsetT AssemblerMIPS32::decodeBranchOffset(IValueT Inst) {
- int16_t imm = (Inst & kBranchOffsetMask);
- IOffsetT Offset = imm;
- Offset = Offset << 2;
- return (Offset + kPCReadOffset);
-}
-
-void AssemblerMIPS32::bind(Label *L) {
- IOffsetT BoundPc = Buffer.size();
- assert(!L->isBound()); // Labels can only be bound once.
- while (L->isLinked()) {
- IOffsetT Position = L->getLinkPosition();
- IOffsetT Dest = BoundPc - Position;
- IValueT Inst = Buffer.load<IValueT>(Position);
- Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
- L->setPosition(decodeBranchOffset(Inst));
- }
- L->bindTo(BoundPc);
-}
-
enum RegSetWanted { WantGPRegs, WantFPRegs };
IValueT getEncodedGPRegNum(const Variable *Var) {
- assert(Var->hasReg());
+ assert(Var->hasReg() && isScalarIntegerType(Var->getType()));
const auto Reg = Var->getRegNum();
return RegMIPS32::getEncodedGPR(Reg);
}
+IValueT getEncodedFPRegNum(const Variable *Var) {
+ assert(Var->hasReg() && isScalarFloatingType(Var->getType()));
+ const auto Reg = Var->getRegNum();
+ IValueT RegEncoding;
+ if (RegMIPS32::isFPRReg(Reg)) {
+ RegEncoding = RegMIPS32::getEncodedFPR(Reg);
+ } else {
+ RegEncoding = RegMIPS32::getEncodedFPR64(Reg);
+ }
+ return RegEncoding;
+}
+
bool encodeOperand(const Operand *Opnd, IValueT &Value,
RegSetWanted WantedRegSet) {
Value = 0;
@@ -155,7 +149,8 @@ bool encodeOperand(const Operand *Opnd, IValueT &Value,
case WantGPRegs:
Value = getEncodedGPRegNum(Var);
break;
- default:
+ case WantFPRegs:
+ Value = getEncodedFPRegNum(Var);
break;
}
return true;
@@ -179,6 +174,32 @@ IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
}
+IValueT encodeFPRegister(const Operand *OpReg, const char *RegName,
+ const char *InstName) {
+ return encodeRegister(OpReg, WantFPRegs, RegName, InstName);
+}
+}
+
+IOffsetT AssemblerMIPS32::decodeBranchOffset(IValueT Inst) {
+ int16_t imm = (Inst & kBranchOffsetMask);
+ IOffsetT Offset = imm;
+ Offset = Offset << 2;
+ return (Offset + kPCReadOffset);
+}
+
+void AssemblerMIPS32::bind(Label *L) {
+ IOffsetT BoundPc = Buffer.size();
+ assert(!L->isBound()); // Labels can only be bound once.
+ while (L->isLinked()) {
+ IOffsetT Position = L->getLinkPosition();
+ IOffsetT Dest = BoundPc - Position;
+ IValueT Inst = Buffer.load<IValueT>(Position);
+ Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
+ L->setPosition(decodeBranchOffset(Inst));
+ }
+ L->bindTo(BoundPc);
+}
+
void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt,
const Operand *OpRs, const uint32_t Imm,
const char *InsnName) {
@@ -192,6 +213,19 @@ void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt,
emitInst(Opcode);
}
+void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt,
+ const Operand *OpRs, const uint32_t Imm,
+ const char *InsnName) {
+ const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
+ const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
+
+ Opcode |= Rs << 21;
+ Opcode |= Ft << 16;
+ Opcode |= Imm & 0xffff;
+
+ emitInst(Opcode);
+}
+
void AssemblerMIPS32::emitRdRtSa(IValueT Opcode, const Operand *OpRd,
const Operand *OpRt, const uint32_t Sa,
const char *InsnName) {
@@ -219,22 +253,96 @@ void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd,
emitInst(Opcode);
}
+void AssemblerMIPS32::emitCOP1FmtFsFd(IValueT Opcode, FPInstDataFormat Format,
+ const Operand *OpFd, const Operand *OpFs,
+ const char *InsnName) {
+ const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
+ const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
+
+ Opcode |= Fd << 6;
+ Opcode |= Fs << 11;
+ Opcode |= Format << 21;
+
+ emitInst(Opcode);
+}
+
+void AssemblerMIPS32::emitCOP1FmtFtFsFd(IValueT Opcode, FPInstDataFormat Format,
+ const Operand *OpFd,
+ const Operand *OpFs,
+ const Operand *OpFt,
+ const char *InsnName) {
+ const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
+ const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
+ const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
+
+ Opcode |= Fd << 6;
+ Opcode |= Fs << 11;
+ Opcode |= Ft << 16;
+ Opcode |= Format << 21;
+
+ emitInst(Opcode);
+}
+
+void AssemblerMIPS32::emitCOP1FmtRtFsFd(IValueT Opcode, FPInstDataFormat Format,
+ const Operand *OpFd,
+ const Operand *OpFs,
+ const Operand *OpRt,
+ const char *InsnName) {
+ const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
+ const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
+ const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
+
+ Opcode |= Fd << 6;
+ Opcode |= Fs << 11;
+ Opcode |= Rt << 16;
+ Opcode |= Format << 21;
+
+ emitInst(Opcode);
+}
+
+void AssemblerMIPS32::emitCOP1MovRtFs(IValueT Opcode, const Operand *OpRt,
+ const Operand *OpFs,
+ const char *InsnName) {
+ const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
+ const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
+ Opcode |= Fs << 11;
+ Opcode |= Rt << 16;
+
+ emitInst(Opcode);
+}
+
+void AssemblerMIPS32::abs_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000005;
+ emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "abs.d");
+}
+
+void AssemblerMIPS32::abs_s(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000005;
+ emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "abs.s");
+}
+
+void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000000;
+ emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "add.d");
+}
+
+void AssemblerMIPS32::add_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000000;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s");
+}
+
void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs,
const uint32_t Imm) {
static constexpr IValueT Opcode = 0x24000000;
emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu");
}
-void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs,
- const uint32_t Imm) {
- static constexpr IValueT Opcode = 0x28000000;
- emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti");
-}
-
-void AssemblerMIPS32::sltiu(const Operand *OpRt, const Operand *OpRs,
- const uint32_t Imm) {
- static constexpr IValueT Opcode = 0x2c000000;
- emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "sltiu");
+void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs,
+ const Operand *OpRt) {
+ static constexpr IValueT Opcode = 0x00000021;
+ emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu");
}
void AssemblerMIPS32::and_(const Operand *OpRd, const Operand *OpRs,
@@ -249,6 +357,186 @@ void AssemblerMIPS32::andi(const Operand *OpRt, const Operand *OpRs,
emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "andi");
}
+void AssemblerMIPS32::b(Label *TargetLabel) {
+ static constexpr Operand *OpRsNone = nullptr;
+ static constexpr Operand *OpRtNone = nullptr;
+ if (TargetLabel->isBound()) {
+ const int32_t Dest = TargetLabel->getPosition() - Buffer.size();
+ emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, Dest);
+ return;
+ }
+ const IOffsetT Position = Buffer.size();
+ emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, TargetLabel->getEncodedPosition());
+ TargetLabel->linkTo(*this, Position);
+}
+
+void AssemblerMIPS32::cvt_d_l(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000021;
+ emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "cvt.d.l");
+}
+
+void AssemblerMIPS32::cvt_d_s(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000021;
+ emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "cvt.d.s");
+}
+
+void AssemblerMIPS32::cvt_d_w(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000021;
+ emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "cvt.d.w");
+}
+
+void AssemblerMIPS32::cvt_s_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000020;
+ emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "cvt.s.d");
+}
+
+void AssemblerMIPS32::cvt_s_l(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000020;
+ emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "cvt.s.l");
+}
+
+void AssemblerMIPS32::cvt_s_w(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000020;
+ emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "cvt.s.w");
+}
+
+void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000003;
+ emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "div.d");
+}
+
+void AssemblerMIPS32::div_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000003;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s");
+}
+
+void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase,
+ const uint32_t Offset) {
+ switch (OpRt->getType()) {
+ case IceType_i1:
+ case IceType_i8: {
+ static constexpr IValueT Opcode = 0x80000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb");
+ }
+ case IceType_i16: {
+ static constexpr IValueT Opcode = 0x84000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lh");
+ }
+ case IceType_i32: {
+ static constexpr IValueT Opcode = 0x8C000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw");
+ break;
+ }
+ case IceType_f32: {
+ static constexpr IValueT Opcode = 0xC4000000;
+ emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "lwc1");
+ }
+ case IceType_f64: {
+ static constexpr IValueT Opcode = 0xD4000000;
+ emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "ldc1");
+ break;
+ }
+ default: { UnimplementedError(getFlags()); }
+ }
+}
+
+void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000000;
+ emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1");
+}
+
+void AssemblerMIPS32::mov_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000006;
+ emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "mov.d");
+}
+
+void AssemblerMIPS32::mov_s(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000006;
+ emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "mov.s");
+}
+
+void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) {
+
+ const Type DstType = OpRd->getType();
+ const Type SrcType = OpRs->getType();
+
+ if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
+ (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
+ if (isScalarFloatingType(DstType)) {
+ mtc1(OpRd, OpRs);
+ } else {
+ mfc1(OpRd, OpRs);
+ }
+ } else {
+ switch (DstType) {
+ case IceType_f32:
+ mov_s(OpRd, OpRs);
+ break;
+ case IceType_f64:
+ mov_d(OpRd, OpRs);
+ break;
+ case IceType_i1:
+ case IceType_i8:
+ case IceType_i16:
+ case IceType_i32: {
+ IValueT Opcode = 0x00000021;
+ const IValueT Rd = encodeGPRegister(OpRd, "Rd", "pseudo-move");
+ const IValueT Rs = encodeGPRegister(OpRs, "Rs", "pseudo-move");
+ const IValueT Rt = 0; // $0
+ Opcode |= Rs << 21;
+ Opcode |= Rt << 16;
+ Opcode |= Rd << 11;
+ emitInst(Opcode);
+ break;
+ }
+ default: { UnimplementedError(getFlags()); }
+ }
+ }
+}
+
+void AssemblerMIPS32::movn_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000013;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.d");
+}
+
+void AssemblerMIPS32::movn_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000013;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.s");
+}
+
+void AssemblerMIPS32::movz_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000012;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.d");
+}
+
+void AssemblerMIPS32::movz_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000012;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.s");
+}
+
+void AssemblerMIPS32::mtc1(const Operand *OpRt, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44800000;
+ emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mtc1");
+}
+
+void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000002;
+ emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d");
+}
+
+void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000002;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s");
+}
+
void AssemblerMIPS32::or_(const Operand *OpRd, const Operand *OpRs,
const Operand *OpRt) {
static constexpr IValueT Opcode = 0x00000025;
@@ -261,16 +549,10 @@ void AssemblerMIPS32::ori(const Operand *OpRt, const Operand *OpRs,
emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "ori");
}
-void AssemblerMIPS32::xor_(const Operand *OpRd, const Operand *OpRs,
- const Operand *OpRt) {
- static constexpr IValueT Opcode = 0x00000026;
- emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "xor");
-}
-
-void AssemblerMIPS32::xori(const Operand *OpRt, const Operand *OpRs,
- const uint32_t Imm) {
- static constexpr IValueT Opcode = 0x38000000;
- emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "xori");
+void AssemblerMIPS32::ret(void) {
+ static constexpr IValueT Opcode = 0x03E00008; // JR $31
+ emitInst(Opcode);
+ nop(); // delay slot
}
void AssemblerMIPS32::sll(const Operand *OpRd, const Operand *OpRt,
@@ -279,10 +561,38 @@ void AssemblerMIPS32::sll(const Operand *OpRd, const Operand *OpRt,
emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sll");
}
-void AssemblerMIPS32::srl(const Operand *OpRd, const Operand *OpRt,
- const uint32_t Sa) {
- static constexpr IValueT Opcode = 0x00000002;
- emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl");
+void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs,
+ const Operand *OpRt) {
+ static constexpr IValueT Opcode = 0x0000002A;
+ emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt");
+}
+
+void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs,
+ const uint32_t Imm) {
+ static constexpr IValueT Opcode = 0x28000000;
+ emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti");
+}
+
+void AssemblerMIPS32::sltu(const Operand *OpRd, const Operand *OpRs,
+ const Operand *OpRt) {
+ static constexpr IValueT Opcode = 0x0000002B;
+ emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "sltu");
+}
+
+void AssemblerMIPS32::sltiu(const Operand *OpRt, const Operand *OpRs,
+ const uint32_t Imm) {
+ static constexpr IValueT Opcode = 0x2c000000;
+ emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "sltiu");
+}
+
+void AssemblerMIPS32::sqrt_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000004;
+ emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "sqrt.d");
+}
+
+void AssemblerMIPS32::sqrt_s(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x44000004;
+ emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "sqrt.s");
}
void AssemblerMIPS32::sra(const Operand *OpRd, const Operand *OpRt,
@@ -291,51 +601,87 @@ void AssemblerMIPS32::sra(const Operand *OpRd, const Operand *OpRt,
emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sra");
}
-void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) {
- IValueT Opcode = 0x00000021;
- const IValueT Rd = encodeGPRegister(OpRd, "Rd", "pseudo-move");
- const IValueT Rs = encodeGPRegister(OpRs, "Rs", "pseudo-move");
- const IValueT Rt = 0; // $0
- Opcode |= Rs << 21;
- Opcode |= Rt << 16;
- Opcode |= Rd << 11;
- emitInst(Opcode);
-}
-
-void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs,
- const Operand *OpRt) {
- static constexpr IValueT Opcode = 0x00000021;
- emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu");
+void AssemblerMIPS32::srl(const Operand *OpRd, const Operand *OpRt,
+ const uint32_t Sa) {
+ static constexpr IValueT Opcode = 0x00000002;
+ emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl");
}
-void AssemblerMIPS32::sltu(const Operand *OpRd, const Operand *OpRs,
- const Operand *OpRt) {
- static constexpr IValueT Opcode = 0x0000002B;
- emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "sltu");
+void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000001;
+ emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d");
}
-void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs,
- const Operand *OpRt) {
- static constexpr IValueT Opcode = 0x0000002A;
- emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt");
+void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs,
+ const Operand *OpFt) {
+ static constexpr IValueT Opcode = 0x44000001;
+ emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s");
}
void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
const uint32_t Offset) {
- static constexpr IValueT Opcode = 0xAC000000;
- emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw");
+ switch (OpRt->getType()) {
+ case IceType_i1:
+ case IceType_i8: {
+ static constexpr IValueT Opcode = 0xA0000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sb");
+ break;
+ }
+ case IceType_i16: {
+ static constexpr IValueT Opcode = 0xA4000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sh");
+ break;
+ }
+ case IceType_i32: {
+ static constexpr IValueT Opcode = 0xAC000000;
+ emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw");
+ break;
+ }
+ case IceType_f32: {
+ static constexpr IValueT Opcode = 0xE4000000;
+ emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "swc1");
+ break;
+ }
+ case IceType_f64: {
+ static constexpr IValueT Opcode = 0xF4000000;
+ emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "sdc1");
+ break;
+ }
+ default: { UnimplementedError(getFlags()); }
+ }
}
-void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase,
- const uint32_t Offset) {
- static constexpr IValueT Opcode = 0x8C000000;
- emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw");
+void AssemblerMIPS32::trunc_l_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x4400000D;
+ emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.d");
}
-void AssemblerMIPS32::ret(void) {
- static constexpr IValueT Opcode = 0x03E00008; // JR $31
- emitInst(Opcode);
- nop(); // delay slot
+void AssemblerMIPS32::trunc_l_s(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x4400000D;
+ emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.s");
+}
+
+void AssemblerMIPS32::trunc_w_d(const Operand *OpFd, const Operand *OpFs) {
+ static constexpr IValueT Opcode = 0x4400000D;
+ emitCOP1FmtFsFd(Opcode, Word, 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");
+}
+
+void AssemblerMIPS32::xor_(const Operand *OpRd, const Operand *OpRs,
+ const Operand *OpRt) {
+ static constexpr IValueT Opcode = 0x00000026;
+ emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "xor");
+}
+
+void AssemblerMIPS32::xori(const Operand *OpRt, const Operand *OpRs,
+ const uint32_t Imm) {
+ static constexpr IValueT Opcode = 0x38000000;
+ emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "xori");
}
void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs,
@@ -387,19 +733,6 @@ void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs,
nop(); // delay slot
}
-void AssemblerMIPS32::b(Label *TargetLabel) {
- static constexpr Operand *OpRsNone = nullptr;
- static constexpr Operand *OpRtNone = nullptr;
- if (TargetLabel->isBound()) {
- const int32_t Dest = TargetLabel->getPosition() - Buffer.size();
- emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, Dest);
- return;
- }
- const IOffsetT Position = Buffer.size();
- emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, TargetLabel->getEncodedPosition());
- TargetLabel->linkTo(*this, Position);
-}
-
void AssemblerMIPS32::bcc(const CondMIPS32::Cond Cond, const Operand *OpRs,
const Operand *OpRt, Label *TargetLabel) {
if (TargetLabel->isBound()) {
« 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