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

Side by Side 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: Addressing review comments, tests added, more instructions added 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 unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceAssemblerMIPS32.cpp - MIPS32 Assembler --------------===// 1 //===- subzero/src/IceAssemblerMIPS32.cpp - MIPS32 Assembler --------------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 if (BuildDefs::dump() && !getFlags().getDisableHybridAssembly()) { 95 if (BuildDefs::dump() && !getFlags().getDisableHybridAssembly()) {
96 constexpr SizeT InstSize = 0; 96 constexpr SizeT InstSize = 0;
97 emitTextInst(Node->getAsmName() + ":", InstSize); 97 emitTextInst(Node->getAsmName() + ":", InstSize);
98 } 98 }
99 SizeT NodeNumber = Node->getIndex(); 99 SizeT NodeNumber = Node->getIndex();
100 assert(!getPreliminary()); 100 assert(!getPreliminary());
101 Label *L = getOrCreateCfgNodeLabel(NodeNumber); 101 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
102 this->bind(L); 102 this->bind(L);
103 } 103 }
104 104
105 namespace {
106
105 // Checks that Offset can fit in imm16 constant of branch instruction. 107 // Checks that Offset can fit in imm16 constant of branch instruction.
106 void assertCanEncodeBranchOffset(IOffsetT Offset) { 108 void assertCanEncodeBranchOffset(IOffsetT Offset) {
107 (void)Offset; 109 (void)Offset;
108 (void)kBranchOffsetBits; 110 (void)kBranchOffsetBits;
109 assert(Utils::IsAligned(Offset, 4)); 111 assert(Utils::IsAligned(Offset, 4));
110 assert(Utils::IsInt(kBranchOffsetBits, Offset >> 2)); 112 assert(Utils::IsInt(kBranchOffsetBits, Offset >> 2));
111 } 113 }
112 114
113 IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) { 115 IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
114 Offset -= kPCReadOffset; 116 Offset -= kPCReadOffset;
115 assertCanEncodeBranchOffset(Offset); 117 assertCanEncodeBranchOffset(Offset);
116 Offset >>= 2; 118 Offset >>= 2;
117 Offset &= kBranchOffsetMask; 119 Offset &= kBranchOffsetMask;
118 return (Inst & ~kBranchOffsetMask) | Offset; 120 return (Inst & ~kBranchOffsetMask) | Offset;
119 } 121 }
120 122
121 IOffsetT AssemblerMIPS32::decodeBranchOffset(IValueT Inst) {
122 int16_t imm = (Inst & kBranchOffsetMask);
123 IOffsetT Offset = imm;
124 Offset = Offset << 2;
125 return (Offset + kPCReadOffset);
126 }
127
128 void AssemblerMIPS32::bind(Label *L) {
129 IOffsetT BoundPc = Buffer.size();
130 assert(!L->isBound()); // Labels can only be bound once.
131 while (L->isLinked()) {
132 IOffsetT Position = L->getLinkPosition();
133 IOffsetT Dest = BoundPc - Position;
134 IValueT Inst = Buffer.load<IValueT>(Position);
135 Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
136 L->setPosition(decodeBranchOffset(Inst));
137 }
138 L->bindTo(BoundPc);
139 }
140
141 enum RegSetWanted { WantGPRegs, WantFPRegs }; 123 enum RegSetWanted { WantGPRegs, WantFPRegs };
142 124
143 IValueT getEncodedGPRegNum(const Variable *Var) { 125 IValueT getEncodedGPRegNum(const Variable *Var) {
144 assert(Var->hasReg()); 126 assert(Var->hasReg() && isScalarIntegerType(Var->getType()));
145 const auto Reg = Var->getRegNum(); 127 const auto Reg = Var->getRegNum();
146 return RegMIPS32::getEncodedGPR(Reg); 128 return RegMIPS32::getEncodedGPR(Reg);
147 } 129 }
148 130
131 IValueT getEncodedFPRegNum(const Variable *Var) {
132 assert(Var->hasReg() && isScalarFloatingType(Var->getType()));
133 const auto Reg = Var->getRegNum();
134 IValueT RegEncoding;
135 if (RegMIPS32::isFPRReg(Reg)) {
136 RegEncoding = RegMIPS32::getEncodedFPR(Reg);
137 } else {
138 RegEncoding = RegMIPS32::getEncodedFPR64(Reg);
139 }
140 return RegEncoding;
141 }
142
149 bool encodeOperand(const Operand *Opnd, IValueT &Value, 143 bool encodeOperand(const Operand *Opnd, IValueT &Value,
150 RegSetWanted WantedRegSet) { 144 RegSetWanted WantedRegSet) {
151 Value = 0; 145 Value = 0;
152 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 146 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
153 if (Var->hasReg()) { 147 if (Var->hasReg()) {
154 switch (WantedRegSet) { 148 switch (WantedRegSet) {
155 case WantGPRegs: 149 case WantGPRegs:
156 Value = getEncodedGPRegNum(Var); 150 Value = getEncodedGPRegNum(Var);
157 break; 151 break;
158 default: 152 case WantFPRegs:
153 Value = getEncodedFPRegNum(Var);
159 break; 154 break;
160 } 155 }
161 return true; 156 return true;
162 } 157 }
163 return false; 158 return false;
164 } 159 }
165 return false; 160 return false;
166 } 161 }
167 162
168 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet, 163 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
169 const char *RegName, const char *InstName) { 164 const char *RegName, const char *InstName) {
170 IValueT Reg = 0; 165 IValueT Reg = 0;
171 if (encodeOperand(OpReg, Reg, WantedRegSet) != true) 166 if (encodeOperand(OpReg, Reg, WantedRegSet) != true)
172 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " + 167 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
173 RegName); 168 RegName);
174 return Reg; 169 return Reg;
175 } 170 }
176 171
177 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName, 172 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
178 const char *InstName) { 173 const char *InstName) {
179 return encodeRegister(OpReg, WantGPRegs, RegName, InstName); 174 return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
180 } 175 }
181 176
177 IValueT encodeFPRegister(const Operand *OpReg, const char *RegName,
178 const char *InstName) {
179 return encodeRegister(OpReg, WantFPRegs, RegName, InstName);
180 }
181 }
Jim Stichnoth 2016/09/16 03:25:00 // end of anonymous namespace
182
183 IOffsetT AssemblerMIPS32::decodeBranchOffset(IValueT Inst) {
184 int16_t imm = (Inst & kBranchOffsetMask);
185 IOffsetT Offset = imm;
186 Offset = Offset << 2;
187 return (Offset + kPCReadOffset);
188 }
189
190 void AssemblerMIPS32::bind(Label *L) {
191 IOffsetT BoundPc = Buffer.size();
192 assert(!L->isBound()); // Labels can only be bound once.
193 while (L->isLinked()) {
194 IOffsetT Position = L->getLinkPosition();
195 IOffsetT Dest = BoundPc - Position;
196 IValueT Inst = Buffer.load<IValueT>(Position);
197 Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
198 L->setPosition(decodeBranchOffset(Inst));
199 }
200 L->bindTo(BoundPc);
201 }
202
182 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt, 203 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt,
183 const Operand *OpRs, const uint32_t Imm, 204 const Operand *OpRs, const uint32_t Imm,
184 const char *InsnName) { 205 const char *InsnName) {
185 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 206 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
186 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); 207 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
187 208
188 Opcode |= Rs << 21; 209 Opcode |= Rs << 21;
189 Opcode |= Rt << 16; 210 Opcode |= Rt << 16;
190 Opcode |= Imm & 0xffff; 211 Opcode |= Imm & 0xffff;
191 212
192 emitInst(Opcode); 213 emitInst(Opcode);
193 } 214 }
194 215
216 void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt,
217 const Operand *OpRs, const uint32_t Imm,
218 const char *InsnName) {
219 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
220 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
221
222 Opcode |= Rs << 21;
223 Opcode |= Ft << 16;
224 Opcode |= Imm & 0xffff;
225
226 emitInst(Opcode);
227 }
228
195 void AssemblerMIPS32::emitRdRtSa(IValueT Opcode, const Operand *OpRd, 229 void AssemblerMIPS32::emitRdRtSa(IValueT Opcode, const Operand *OpRd,
196 const Operand *OpRt, const uint32_t Sa, 230 const Operand *OpRt, const uint32_t Sa,
197 const char *InsnName) { 231 const char *InsnName) {
198 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName); 232 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName);
199 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 233 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
200 234
201 Opcode |= Rt << 16; 235 Opcode |= Rt << 16;
202 Opcode |= Rd << 11; 236 Opcode |= Rd << 11;
203 Opcode |= (Sa & 0x1f) << 6; 237 Opcode |= (Sa & 0x1f) << 6;
204 238
205 emitInst(Opcode); 239 emitInst(Opcode);
206 } 240 }
207 241
208 void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd, 242 void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd,
209 const Operand *OpRs, const Operand *OpRt, 243 const Operand *OpRs, const Operand *OpRt,
210 const char *InsnName) { 244 const char *InsnName) {
211 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName); 245 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName);
212 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); 246 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
213 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 247 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
214 248
215 Opcode |= Rs << 21; 249 Opcode |= Rs << 21;
216 Opcode |= Rt << 16; 250 Opcode |= Rt << 16;
217 Opcode |= Rd << 11; 251 Opcode |= Rd << 11;
218 252
219 emitInst(Opcode); 253 emitInst(Opcode);
220 } 254 }
221 255
256 void AssemblerMIPS32::emitCOP1FmtFsFd(IValueT Opcode, FPInstDataFormat Format,
257 const Operand *OpFd, const Operand *OpFs,
258 const char *InsnName) {
259 const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
260 const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
261
262 Opcode |= Fd << 6;
263 Opcode |= Fs << 11;
264 Opcode |= Format << 21;
265
266 emitInst(Opcode);
267 }
268
269 void AssemblerMIPS32::emitCOP1FmtFtFsFd(IValueT Opcode, FPInstDataFormat Format,
270 const Operand *OpFd,
271 const Operand *OpFs,
272 const Operand *OpFt,
273 const char *InsnName) {
274 const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
275 const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
276 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
277
278 Opcode |= Fd << 6;
279 Opcode |= Fs << 11;
280 Opcode |= Ft << 16;
281 Opcode |= Format << 21;
282
283 emitInst(Opcode);
284 }
285
286 void AssemblerMIPS32::emitCOP1FmtRtFsFd(IValueT Opcode, FPInstDataFormat Format,
287 const Operand *OpFd,
288 const Operand *OpFs,
289 const Operand *OpRt,
290 const char *InsnName) {
291 const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
292 const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
293 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
294
295 Opcode |= Fd << 6;
296 Opcode |= Fs << 11;
297 Opcode |= Rt << 16;
298 Opcode |= Format << 21;
299
300 emitInst(Opcode);
301 }
302
303 void AssemblerMIPS32::emitCOP1MovRtFs(IValueT Opcode, const Operand *OpRt,
304 const Operand *OpFs,
305 const char *InsnName) {
306 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
307 const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
308 Opcode |= Fs << 11;
309 Opcode |= Rt << 16;
310
311 emitInst(Opcode);
312 }
313
314 void AssemblerMIPS32::abs_d(const Operand *OpFd, const Operand *OpFs) {
315 static constexpr IValueT Opcode = 0x44000005;
316 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "abs.d");
317 }
318
319 void AssemblerMIPS32::abs_s(const Operand *OpFd, const Operand *OpFs) {
320 static constexpr IValueT Opcode = 0x44000005;
321 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "abs.s");
322 }
323
324 void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs,
325 const Operand *OpFt) {
326 static constexpr IValueT Opcode = 0x44000000;
327 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "add.d");
328 }
329
330 void AssemblerMIPS32::add_s(const Operand *OpFd, const Operand *OpFs,
331 const Operand *OpFt) {
332 static constexpr IValueT Opcode = 0x44000000;
333 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s");
334 }
335
336 void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs,
337 const Operand *OpFt) {
338 static constexpr IValueT Opcode = 0x44000003;
339 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "div.d");
340 }
341
342 void AssemblerMIPS32::div_s(const Operand *OpFd, const Operand *OpFs,
343 const Operand *OpFt) {
344 static constexpr IValueT Opcode = 0x44000003;
345 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s");
346 }
347
348 void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) {
349 static constexpr IValueT Opcode = 0x44000000;
350 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1");
351 }
352
353 void AssemblerMIPS32::mov_d(const Operand *OpFd, const Operand *OpFs) {
354 static constexpr IValueT Opcode = 0x44000006;
355 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "mov.d");
356 }
357
358 void AssemblerMIPS32::mov_s(const Operand *OpFd, const Operand *OpFs) {
359 static constexpr IValueT Opcode = 0x44000006;
360 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "mov.s");
361 }
362
363 void AssemblerMIPS32::movn_d(const Operand *OpFd, const Operand *OpFs,
364 const Operand *OpFt) {
365 static constexpr IValueT Opcode = 0x44000013;
366 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.d");
367 }
368
369 void AssemblerMIPS32::movn_s(const Operand *OpFd, const Operand *OpFs,
370 const Operand *OpFt) {
371 static constexpr IValueT Opcode = 0x44000013;
372 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.s");
373 }
374
375 void AssemblerMIPS32::movz_d(const Operand *OpFd, const Operand *OpFs,
376 const Operand *OpFt) {
377 static constexpr IValueT Opcode = 0x44000012;
378 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.d");
379 }
380
381 void AssemblerMIPS32::movz_s(const Operand *OpFd, const Operand *OpFs,
382 const Operand *OpFt) {
383 static constexpr IValueT Opcode = 0x44000012;
384 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.s");
385 }
386
387 void AssemblerMIPS32::mtc1(const Operand *OpRt, const Operand *OpFs) {
388 static constexpr IValueT Opcode = 0x44800000;
389 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mtc1");
390 }
391
392 void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs,
393 const Operand *OpFt) {
394 static constexpr IValueT Opcode = 0x44000002;
395 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d");
396 }
397
398 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs,
399 const Operand *OpFt) {
400 static constexpr IValueT Opcode = 0x44000002;
401 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s");
402 }
403
404 void AssemblerMIPS32::sqrt_d(const Operand *OpFd, const Operand *OpFs) {
405 static constexpr IValueT Opcode = 0x44000004;
406 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "sqrt.d");
407 }
408
409 void AssemblerMIPS32::sqrt_s(const Operand *OpFd, const Operand *OpFs) {
410 static constexpr IValueT Opcode = 0x44000004;
411 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "sqrt.s");
412 }
413
414 void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs,
415 const Operand *OpFt) {
416 static constexpr IValueT Opcode = 0x44000001;
417 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d");
418 }
419
420 void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs,
421 const Operand *OpFt) {
422 static constexpr IValueT Opcode = 0x44000001;
423 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s");
424 }
425
222 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, 426 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs,
223 const uint32_t Imm) { 427 const uint32_t Imm) {
224 static constexpr IValueT Opcode = 0x24000000; 428 static constexpr IValueT Opcode = 0x24000000;
225 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu"); 429 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu");
226 } 430 }
227 431
228 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs, 432 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs,
229 const uint32_t Imm) { 433 const uint32_t Imm) {
230 static constexpr IValueT Opcode = 0x28000000; 434 static constexpr IValueT Opcode = 0x28000000;
231 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti"); 435 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti");
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl"); 489 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl");
286 } 490 }
287 491
288 void AssemblerMIPS32::sra(const Operand *OpRd, const Operand *OpRt, 492 void AssemblerMIPS32::sra(const Operand *OpRd, const Operand *OpRt,
289 const uint32_t Sa) { 493 const uint32_t Sa) {
290 static constexpr IValueT Opcode = 0x00000003; 494 static constexpr IValueT Opcode = 0x00000003;
291 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sra"); 495 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sra");
292 } 496 }
293 497
294 void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) { 498 void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) {
295 IValueT Opcode = 0x00000021; 499
296 const IValueT Rd = encodeGPRegister(OpRd, "Rd", "pseudo-move"); 500 const Type DstType = OpRd->getType();
297 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "pseudo-move"); 501 const Type SrcType = OpRs->getType();
298 const IValueT Rt = 0; // $0 502
299 Opcode |= Rs << 21; 503 if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
300 Opcode |= Rt << 16; 504 (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
301 Opcode |= Rd << 11; 505 if (isScalarFloatingType(DstType)) {
302 emitInst(Opcode); 506 mtc1(OpRd, OpRs);
507 } else {
508 mfc1(OpRd, OpRs);
509 }
510 } else {
511 switch (DstType) {
512 case IceType_f32:
513 mov_s(OpRd, OpRs);
514 break;
515 case IceType_f64:
516 mov_d(OpRd, OpRs);
517 break;
518 case IceType_i1:
519 case IceType_i8:
520 case IceType_i16:
521 case IceType_i32: {
522 IValueT Opcode = 0x00000021;
523 const IValueT Rd = encodeGPRegister(OpRd, "Rd", "pseudo-move");
524 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "pseudo-move");
525 const IValueT Rt = 0; // $0
526 Opcode |= Rs << 21;
527 Opcode |= Rt << 16;
528 Opcode |= Rd << 11;
529 emitInst(Opcode);
530 break;
531 }
532 default: { UnimplementedError(getFlags()); }
533 }
534 }
303 } 535 }
304 536
305 void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs, 537 void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs,
306 const Operand *OpRt) { 538 const Operand *OpRt) {
307 static constexpr IValueT Opcode = 0x00000021; 539 static constexpr IValueT Opcode = 0x00000021;
308 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu"); 540 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu");
309 } 541 }
310 542
311 void AssemblerMIPS32::sltu(const Operand *OpRd, const Operand *OpRs, 543 void AssemblerMIPS32::sltu(const Operand *OpRd, const Operand *OpRs,
312 const Operand *OpRt) { 544 const Operand *OpRt) {
313 static constexpr IValueT Opcode = 0x0000002B; 545 static constexpr IValueT Opcode = 0x0000002B;
314 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "sltu"); 546 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "sltu");
315 } 547 }
316 548
317 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs, 549 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs,
318 const Operand *OpRt) { 550 const Operand *OpRt) {
319 static constexpr IValueT Opcode = 0x0000002A; 551 static constexpr IValueT Opcode = 0x0000002A;
320 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt"); 552 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt");
321 } 553 }
322 554
323 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase, 555 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
324 const uint32_t Offset) { 556 const uint32_t Offset) {
325 static constexpr IValueT Opcode = 0xAC000000; 557 switch (OpRt->getType()) {
326 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw"); 558 case IceType_i1:
559 case IceType_i8: {
560 static constexpr IValueT Opcode = 0xA0000000;
561 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sb");
562 break;
563 }
564 case IceType_i16: {
565 static constexpr IValueT Opcode = 0xA4000000;
566 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sh");
567 break;
568 }
569 case IceType_i32: {
570 static constexpr IValueT Opcode = 0xAC000000;
571 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw");
572 break;
573 }
574 case IceType_f32: {
575 static constexpr IValueT Opcode = 0xE4000000;
576 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "swc1");
577 break;
578 }
579 case IceType_f64: {
580 static constexpr IValueT Opcode = 0xF4000000;
581 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "sdc1");
582 break;
583 }
584 default: { UnimplementedError(getFlags()); }
585 }
327 } 586 }
328 587
329 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, 588 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase,
330 const uint32_t Offset) { 589 const uint32_t Offset) {
331 static constexpr IValueT Opcode = 0x8C000000; 590 switch (OpRt->getType()) {
332 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw"); 591 case IceType_i1:
592 case IceType_i8: {
593 static constexpr IValueT Opcode = 0x80000000;
594 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb");
595 }
596 case IceType_i16: {
597 static constexpr IValueT Opcode = 0x84000000;
598 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lh");
599 }
600 case IceType_i32: {
601 static constexpr IValueT Opcode = 0x8C000000;
602 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw");
603 break;
604 }
605 case IceType_f32: {
606 static constexpr IValueT Opcode = 0xC4000000;
607 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "lwc1");
608 }
609 case IceType_f64: {
610 static constexpr IValueT Opcode = 0xD4000000;
611 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "ldc1");
612 break;
613 }
614 default: { UnimplementedError(getFlags()); }
615 }
333 } 616 }
334 617
335 void AssemblerMIPS32::ret(void) { 618 void AssemblerMIPS32::ret(void) {
336 static constexpr IValueT Opcode = 0x03E00008; // JR $31 619 static constexpr IValueT Opcode = 0x03E00008; // JR $31
337 emitInst(Opcode); 620 emitInst(Opcode);
338 nop(); // delay slot 621 nop(); // delay slot
339 } 622 }
340 623
341 void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, 624 void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs,
342 const Operand *OpRt, IOffsetT Offset) { 625 const Operand *OpRt, IOffsetT Offset) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 emitBr(Cond, OpRs, OpRtNone, Dest); 703 emitBr(Cond, OpRs, OpRtNone, Dest);
421 return; 704 return;
422 } 705 }
423 const IOffsetT Position = Buffer.size(); 706 const IOffsetT Position = Buffer.size();
424 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); 707 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition());
425 TargetLabel->linkTo(*this, Position); 708 TargetLabel->linkTo(*this, Position);
426 } 709 }
427 710
428 } // end of namespace MIPS32 711 } // end of namespace MIPS32
429 } // end of namespace Ice 712 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698