Chromium Code Reviews| 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) { |