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

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: 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 // Checks that Offset can fit in imm16 constant of branch instruction. 105 // Checks that Offset can fit in imm16 constant of branch instruction.
Jim Stichnoth 2016/09/15 04:53:45 Can all the code from here down to the note below,
obucinac 2016/09/15 13:35:06 Done.
106 void assertCanEncodeBranchOffset(IOffsetT Offset) { 106 void assertCanEncodeBranchOffset(IOffsetT Offset) {
107 (void)Offset; 107 (void)Offset;
108 (void)kBranchOffsetBits; 108 (void)kBranchOffsetBits;
109 assert(Utils::IsAligned(Offset, 4)); 109 assert(Utils::IsAligned(Offset, 4));
110 assert(Utils::IsInt(kBranchOffsetBits, Offset >> 2)); 110 assert(Utils::IsInt(kBranchOffsetBits, Offset >> 2));
111 } 111 }
112 112
113 IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) { 113 IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
114 Offset -= kPCReadOffset; 114 Offset -= kPCReadOffset;
115 assertCanEncodeBranchOffset(Offset); 115 assertCanEncodeBranchOffset(Offset);
(...skipping 23 matching lines...) Expand all
139 } 139 }
140 140
141 enum RegSetWanted { WantGPRegs, WantFPRegs }; 141 enum RegSetWanted { WantGPRegs, WantFPRegs };
142 142
143 IValueT getEncodedGPRegNum(const Variable *Var) { 143 IValueT getEncodedGPRegNum(const Variable *Var) {
144 assert(Var->hasReg()); 144 assert(Var->hasReg());
145 const auto Reg = Var->getRegNum(); 145 const auto Reg = Var->getRegNum();
146 return RegMIPS32::getEncodedGPR(Reg); 146 return RegMIPS32::getEncodedGPR(Reg);
147 } 147 }
148 148
149 IValueT getEncodedFPRegNum(const Variable *Var) {
150 assert(Var->hasReg());
151 const auto Reg = Var->getRegNum();
152 if (RegMIPS32::isFPRReg(Reg)) {
153 return RegMIPS32::getEncodedFPR(Reg);
154 } 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.
155 return RegMIPS32::getEncodedFPR64(Reg);
156 }
157 }
158
149 bool encodeOperand(const Operand *Opnd, IValueT &Value, 159 bool encodeOperand(const Operand *Opnd, IValueT &Value,
150 RegSetWanted WantedRegSet) { 160 RegSetWanted WantedRegSet) {
151 Value = 0; 161 Value = 0;
152 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 162 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
153 if (Var->hasReg()) { 163 if (Var->hasReg()) {
154 switch (WantedRegSet) { 164 switch (WantedRegSet) {
155 case WantGPRegs: 165 case WantGPRegs:
156 Value = getEncodedGPRegNum(Var); 166 Value = getEncodedGPRegNum(Var);
157 break; 167 break;
158 default: 168 case WantFPRegs:
169 Value = getEncodedFPRegNum(Var);
159 break; 170 break;
160 } 171 }
161 return true; 172 return true;
162 } 173 }
163 return false; 174 return false;
164 } 175 }
165 return false; 176 return false;
166 } 177 }
167 178
168 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet, 179 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
169 const char *RegName, const char *InstName) { 180 const char *RegName, const char *InstName) {
170 IValueT Reg = 0; 181 IValueT Reg = 0;
171 if (encodeOperand(OpReg, Reg, WantedRegSet) != true) 182 if (encodeOperand(OpReg, Reg, WantedRegSet) != true)
172 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " + 183 llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
173 RegName); 184 RegName);
174 return Reg; 185 return Reg;
175 } 186 }
176 187
177 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName, 188 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
178 const char *InstName) { 189 const char *InstName) {
179 return encodeRegister(OpReg, WantGPRegs, RegName, InstName); 190 return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
180 } 191 }
181 192
193 IValueT encodeFPRegister(const Operand *OpReg, const char *RegName,
194 const char *InstName) {
195 return encodeRegister(OpReg, WantFPRegs, RegName, InstName);
196 }
197
Jim Stichnoth 2016/09/15 04:53:45 Here's where my proposed anonymous namespace would
obucinac 2016/09/15 13:35:06 Done.
182 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt, 198 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt,
183 const Operand *OpRs, const uint32_t Imm, 199 const Operand *OpRs, const uint32_t Imm,
184 const char *InsnName) { 200 const char *InsnName) {
185 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 201 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
186 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); 202 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
187 203
188 Opcode |= Rs << 21; 204 Opcode |= Rs << 21;
189 Opcode |= Rt << 16; 205 Opcode |= Rt << 16;
190 Opcode |= Imm & 0xffff; 206 Opcode |= Imm & 0xffff;
191 207
192 emitInst(Opcode); 208 emitInst(Opcode);
193 } 209 }
194 210
211 void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt,
212 const Operand *OpRs, const uint32_t Imm,
213 const char *InsnName) {
214 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
215 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
216
217 Opcode |= Rs << 21;
218 Opcode |= Ft << 16;
219 Opcode |= Imm & 0xffff;
220
221 emitInst(Opcode);
222 }
223
195 void AssemblerMIPS32::emitRdRtSa(IValueT Opcode, const Operand *OpRd, 224 void AssemblerMIPS32::emitRdRtSa(IValueT Opcode, const Operand *OpRd,
196 const Operand *OpRt, const uint32_t Sa, 225 const Operand *OpRt, const uint32_t Sa,
197 const char *InsnName) { 226 const char *InsnName) {
198 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName); 227 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName);
199 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 228 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
200 229
201 Opcode |= Rt << 16; 230 Opcode |= Rt << 16;
202 Opcode |= Rd << 11; 231 Opcode |= Rd << 11;
203 Opcode |= (Sa & 0x1f) << 6; 232 Opcode |= (Sa & 0x1f) << 6;
204 233
205 emitInst(Opcode); 234 emitInst(Opcode);
206 } 235 }
207 236
208 void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd, 237 void AssemblerMIPS32::emitRdRsRt(IValueT Opcode, const Operand *OpRd,
209 const Operand *OpRs, const Operand *OpRt, 238 const Operand *OpRs, const Operand *OpRt,
210 const char *InsnName) { 239 const char *InsnName) {
211 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName); 240 const IValueT Rd = encodeGPRegister(OpRd, "Rd", InsnName);
212 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); 241 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName);
213 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); 242 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName);
214 243
215 Opcode |= Rs << 21; 244 Opcode |= Rs << 21;
216 Opcode |= Rt << 16; 245 Opcode |= Rt << 16;
217 Opcode |= Rd << 11; 246 Opcode |= Rd << 11;
218 247
219 emitInst(Opcode); 248 emitInst(Opcode);
220 } 249 }
221 250
251 void AssemblerMIPS32::emitFPFormatFtFsFd(
252 IValueT Opcode, FPInstDataFormat Format, const Operand *OpFd,
253 const Operand *OpFs, const Operand *OpFt, const char *InsnName) {
254 const IValueT Fd = encodeFPRegister(OpFd, "Fd", InsnName);
255 const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
256 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
257
258 Opcode |= Fd << 6;
259 Opcode |= Fs << 11;
260 Opcode |= Ft << 16;
261 Opcode |= Format << 21;
262
263 emitInst(Opcode);
264 }
265
266 void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs,
267 const Operand *OpFt) {
268 static constexpr IValueT Opcode = 0x44000000;
269 emitFPFormatFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "add.d");
270 }
271
272 void AssemblerMIPS32::add_s(const Operand *OpFd, const Operand *OpFs,
273 const Operand *OpFt) {
274 static constexpr IValueT Opcode = 0x44000000;
275 emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s");
276 }
277
278 void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs,
279 const Operand *OpFt) {
280 static constexpr IValueT Opcode = 0x44000003;
281 emitFPFormatFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "div.d");
282 }
283
284 void AssemblerMIPS32::div_s(const Operand *OpFd, const Operand *OpFs,
285 const Operand *OpFt) {
286 static constexpr IValueT Opcode = 0x44000003;
287 emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s");
288 }
289
290 void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs,
291 const Operand *OpFt) {
292 static constexpr IValueT Opcode = 0x44000002;
293 emitFPFormatFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d");
294 }
295
296 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs,
297 const Operand *OpFt) {
298 static constexpr IValueT Opcode = 0x44000002;
299 emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s");
300 }
301
302 void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs,
303 const Operand *OpFt) {
304 static constexpr IValueT Opcode = 0x44000001;
305 emitFPFormatFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d");
306 }
307
308 void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs,
309 const Operand *OpFt) {
310 static constexpr IValueT Opcode = 0x44000001;
311 emitFPFormatFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s");
312 }
313
222 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, 314 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs,
223 const uint32_t Imm) { 315 const uint32_t Imm) {
224 static constexpr IValueT Opcode = 0x24000000; 316 static constexpr IValueT Opcode = 0x24000000;
225 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu"); 317 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu");
226 } 318 }
227 319
228 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs, 320 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs,
229 const uint32_t Imm) { 321 const uint32_t Imm) {
230 static constexpr IValueT Opcode = 0x28000000; 322 static constexpr IValueT Opcode = 0x28000000;
231 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti"); 323 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti");
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 } 407 }
316 408
317 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs, 409 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs,
318 const Operand *OpRt) { 410 const Operand *OpRt) {
319 static constexpr IValueT Opcode = 0x0000002A; 411 static constexpr IValueT Opcode = 0x0000002A;
320 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt"); 412 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt");
321 } 413 }
322 414
323 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase, 415 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
324 const uint32_t Offset) { 416 const uint32_t Offset) {
325 static constexpr IValueT Opcode = 0xAC000000; 417 switch (OpRt->getType()) {
326 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw"); 418 case IceType_i1:
419 case IceType_i8: {
420 static constexpr IValueT Opcode = 0xA0000000;
421 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sb");
422 break;
423 }
424 case IceType_i16: {
425 static constexpr IValueT Opcode = 0xA4000000;
426 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sh");
427 break;
428 }
429 case IceType_i32: {
430 static constexpr IValueT Opcode = 0xAC000000;
431 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sw");
432 break;
433 }
434 case IceType_f32: {
435 static constexpr IValueT Opcode = 0xE4000000;
436 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "swc1");
437 break;
438 }
439 case IceType_f64: {
440 static constexpr IValueT Opcode = 0xF4000000;
441 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "sdc1");
442 break;
443 }
444 default: { UnimplementedError(getFlags()); }
445 }
327 } 446 }
328 447
329 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, 448 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase,
330 const uint32_t Offset) { 449 const uint32_t Offset) {
331 static constexpr IValueT Opcode = 0x8C000000; 450 switch (OpRt->getType()) {
332 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw"); 451 case IceType_i1:
452 case IceType_i8: {
453 static constexpr IValueT Opcode = 0x80000000;
454 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb");
455 }
456 case IceType_i16: {
457 static constexpr IValueT Opcode = 0x84000000;
458 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lh");
459 }
460 case IceType_i32: {
461 static constexpr IValueT Opcode = 0x8C000000;
462 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lw");
463 break;
464 }
465 case IceType_f32: {
466 static constexpr IValueT Opcode = 0xC4000000;
467 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "lwc1");
468 }
469 case IceType_f64: {
470 static constexpr IValueT Opcode = 0xD4000000;
471 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "ldc1");
472 break;
473 }
474 default: { UnimplementedError(getFlags()); }
475 }
333 } 476 }
334 477
335 void AssemblerMIPS32::ret(void) { 478 void AssemblerMIPS32::ret(void) {
336 static constexpr IValueT Opcode = 0x03E00008; // JR $31 479 static constexpr IValueT Opcode = 0x03E00008; // JR $31
337 emitInst(Opcode); 480 emitInst(Opcode);
338 nop(); // delay slot 481 nop(); // delay slot
339 } 482 }
340 483
341 void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, 484 void AssemblerMIPS32::emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs,
342 const Operand *OpRt, IOffsetT Offset) { 485 const Operand *OpRt, IOffsetT Offset) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 emitBr(Cond, OpRs, OpRtNone, Dest); 563 emitBr(Cond, OpRs, OpRtNone, Dest);
421 return; 564 return;
422 } 565 }
423 const IOffsetT Position = Buffer.size(); 566 const IOffsetT Position = Buffer.size();
424 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); 567 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition());
425 TargetLabel->linkTo(*this, Position); 568 TargetLabel->linkTo(*this, Position);
426 } 569 }
427 570
428 } // end of namespace MIPS32 571 } // end of namespace MIPS32
429 } // end of namespace Ice 572 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698