Index: src/IceAssemblerMIPS32.cpp |
diff --git a/src/IceAssemblerMIPS32.cpp b/src/IceAssemblerMIPS32.cpp |
index b9ddff1cf3dddca2e063e13dd7fe942b85ebc64f..14741c0ac94b97d511c8eb4d6511bfb31b199bf9 100644 |
--- a/src/IceAssemblerMIPS32.cpp |
+++ b/src/IceAssemblerMIPS32.cpp |
@@ -146,6 +146,16 @@ IValueT getEncodedGPRegNum(const Variable *Var) { |
return RegMIPS32::getEncodedGPR(Reg); |
} |
+IValueT getEncodedFPRegNum(const Variable *Var) { |
+ assert(Var->hasReg()); |
+ const auto Reg = Var->getRegNum(); |
+ if (RegMIPS32::isFPRReg(Reg)) { |
+ return RegMIPS32::getEncodedFPR(Reg); |
+ } else { |
Jim Stichnoth
2016/09/15 04:53:45
http://llvm.org/docs/CodingStandards.html#don-t-us
obucinac
2016/09/15 13:35:06
Done.
|
+ return RegMIPS32::getEncodedFPR64(Reg); |
+ } |
+} |
+ |
bool encodeOperand(const Operand *Opnd, IValueT &Value, |
RegSetWanted WantedRegSet) { |
Value = 0; |
@@ -155,7 +165,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 +190,11 @@ 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); |
+} |
+ |
Jim Stichnoth
2016/09/15 04:53:45
Here's where my proposed anonymous namespace would
obucinac
2016/09/15 13:35:06
Done.
|
void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt, |
const Operand *OpRs, const uint32_t Imm, |
const char *InsnName) { |
@@ -192,6 +208,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,6 +248,69 @@ void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd, |
emitInst(Opcode); |
} |
+void AssemblerMIPS32::emitFPFormatFtFsFd( |
+ 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::add_d(const Operand *OpFd, const Operand *OpFs, |
+ const Operand *OpFt) { |
+ static constexpr IValueT Opcode = 0x44000000; |
+ emitFPFormatFtFsFd(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; |
+ emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s"); |
+} |
+ |
+void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs, |
+ const Operand *OpFt) { |
+ static constexpr IValueT Opcode = 0x44000003; |
+ emitFPFormatFtFsFd(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; |
+ emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s"); |
+} |
+ |
+void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs, |
+ const Operand *OpFt) { |
+ static constexpr IValueT Opcode = 0x44000002; |
+ emitFPFormatFtFsFd(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; |
+ emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s"); |
+} |
+ |
+void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs, |
+ const Operand *OpFt) { |
+ static constexpr IValueT Opcode = 0x44000001; |
+ emitFPFormatFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d"); |
+} |
+ |
+void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs, |
+ const Operand *OpFt) { |
+ static constexpr IValueT Opcode = 0x44000001; |
+ emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s"); |
+} |
+ |
void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, |
const uint32_t Imm) { |
static constexpr IValueT Opcode = 0x24000000; |
@@ -322,14 +414,65 @@ void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs, |
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"); |
+ 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::ret(void) { |