blob: 2cf59531a359f7437ab35f00f83e1b88a98bf264 [file] [log] [blame]
Jim Stichnoth6da4cef2015-06-11 13:26:33 -07001//===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the TargetLoweringMIPS32 class, which consists almost
11// entirely of the lowering sequence for each high-level instruction.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Support/MathExtras.h"
16
17#include "IceCfg.h"
18#include "IceCfgNode.h"
19#include "IceClFlags.h"
20#include "IceDefs.h"
21#include "IceELFObjectWriter.h"
22#include "IceGlobalInits.h"
23#include "IceInstMIPS32.h"
24#include "IceLiveness.h"
25#include "IceOperand.h"
26#include "IceRegistersMIPS32.h"
27#include "IceTargetLoweringMIPS32.def"
28#include "IceTargetLoweringMIPS32.h"
29#include "IceUtils.h"
30
31namespace Ice {
32
Jim Stichnotheafb56c2015-06-22 10:35:22 -070033TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -070034 // TODO: Don't initialize IntegerRegisters and friends every time.
35 // Instead, initialize in some sort of static initializer for the
36 // class.
37 llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM);
38 llvm::SmallBitVector FloatRegisters(RegMIPS32::Reg_NUM);
39 llvm::SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM);
40 llvm::SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM);
41 ScratchRegs.resize(RegMIPS32::Reg_NUM);
42#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
43 isFP) \
44 IntegerRegisters[RegMIPS32::val] = isInt; \
45 FloatRegisters[RegMIPS32::val] = isFP; \
46 VectorRegisters[RegMIPS32::val] = isFP; \
47 ScratchRegs[RegMIPS32::val] = scratch;
48 REGMIPS32_TABLE;
49#undef X
50 TypeToRegisterSet[IceType_void] = InvalidRegisters;
51 TypeToRegisterSet[IceType_i1] = IntegerRegisters;
52 TypeToRegisterSet[IceType_i8] = IntegerRegisters;
53 TypeToRegisterSet[IceType_i16] = IntegerRegisters;
54 TypeToRegisterSet[IceType_i32] = IntegerRegisters;
55 TypeToRegisterSet[IceType_i64] = IntegerRegisters;
56 TypeToRegisterSet[IceType_f32] = FloatRegisters;
57 TypeToRegisterSet[IceType_f64] = FloatRegisters;
58 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
59 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
60 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
61 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
62 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
63 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
64 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
65}
66
67void TargetMIPS32::translateO2() {
68 TimerMarker T(TimerStack::TT_O2, Func);
69
70 // TODO(stichnot): share passes with X86?
71 // https://code.google.com/p/nativeclient/issues/detail?id=4094
72
73 if (!Ctx->getFlags().getPhiEdgeSplit()) {
74 // Lower Phi instructions.
75 Func->placePhiLoads();
76 if (Func->hasError())
77 return;
78 Func->placePhiStores();
79 if (Func->hasError())
80 return;
81 Func->deletePhis();
82 if (Func->hasError())
83 return;
84 Func->dump("After Phi lowering");
85 }
86
87 // Address mode optimization.
88 Func->getVMetadata()->init(VMK_SingleDefs);
89 Func->doAddressOpt();
90
91 // Argument lowering
92 Func->doArgLowering();
93
94 // Target lowering. This requires liveness analysis for some parts
95 // of the lowering decisions, such as compare/branch fusing. If
96 // non-lightweight liveness analysis is used, the instructions need
97 // to be renumbered first. TODO: This renumbering should only be
98 // necessary if we're actually calculating live intervals, which we
99 // only do for register allocation.
100 Func->renumberInstructions();
101 if (Func->hasError())
102 return;
103
104 // TODO: It should be sufficient to use the fastest liveness
105 // calculation, i.e. livenessLightweight(). However, for some
106 // reason that slows down the rest of the translation. Investigate.
107 Func->liveness(Liveness_Basic);
108 if (Func->hasError())
109 return;
110 Func->dump("After MIPS32 address mode opt");
111
112 Func->genCode();
113 if (Func->hasError())
114 return;
115 Func->dump("After MIPS32 codegen");
116
117 // Register allocation. This requires instruction renumbering and
118 // full liveness analysis.
119 Func->renumberInstructions();
120 if (Func->hasError())
121 return;
122 Func->liveness(Liveness_Intervals);
123 if (Func->hasError())
124 return;
125 // Validate the live range computations. The expensive validation
126 // call is deliberately only made when assertions are enabled.
127 assert(Func->validateLiveness());
128 // The post-codegen dump is done here, after liveness analysis and
129 // associated cleanup, to make the dump cleaner and more useful.
130 Func->dump("After initial MIPS32 codegen");
131 Func->getVMetadata()->init(VMK_All);
132 regAlloc(RAK_Global);
133 if (Func->hasError())
134 return;
135 Func->dump("After linear scan regalloc");
136
137 if (Ctx->getFlags().getPhiEdgeSplit()) {
138 Func->advancedPhiLowering();
139 Func->dump("After advanced Phi lowering");
140 }
141
142 // Stack frame mapping.
143 Func->genFrame();
144 if (Func->hasError())
145 return;
146 Func->dump("After stack frame mapping");
147
148 Func->contractEmptyNodes();
149 Func->reorderNodes();
150
151 // Branch optimization. This needs to be done just before code
152 // emission. In particular, no transformations that insert or
153 // reorder CfgNodes should be done after branch optimization. We go
154 // ahead and do it before nop insertion to reduce the amount of work
155 // needed for searching for opportunities.
156 Func->doBranchOpt();
157 Func->dump("After branch optimization");
158
159 // Nop insertion
160 if (Ctx->getFlags().shouldDoNopInsertion()) {
161 Func->doNopInsertion();
162 }
163}
164
165void TargetMIPS32::translateOm1() {
166 TimerMarker T(TimerStack::TT_Om1, Func);
167
168 // TODO: share passes with X86?
169
170 Func->placePhiLoads();
171 if (Func->hasError())
172 return;
173 Func->placePhiStores();
174 if (Func->hasError())
175 return;
176 Func->deletePhis();
177 if (Func->hasError())
178 return;
179 Func->dump("After Phi lowering");
180
181 Func->doArgLowering();
182
183 Func->genCode();
184 if (Func->hasError())
185 return;
186 Func->dump("After initial MIPS32 codegen");
187
188 regAlloc(RAK_InfOnly);
189 if (Func->hasError())
190 return;
191 Func->dump("After regalloc of infinite-weight variables");
192
193 Func->genFrame();
194 if (Func->hasError())
195 return;
196 Func->dump("After stack frame mapping");
197
198 // Nop insertion
199 if (Ctx->getFlags().shouldDoNopInsertion()) {
200 Func->doNopInsertion();
201 }
202}
203
204bool TargetMIPS32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
205 (void)I;
206 (void)NextNode;
207 llvm::report_fatal_error("Not yet implemented");
208}
209
210IceString TargetMIPS32::RegNames[] = {
211#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
212 isFP) \
213 name,
214 REGMIPS32_TABLE
215#undef X
216};
217
218IceString TargetMIPS32::getRegName(SizeT RegNum, Type Ty) const {
219 assert(RegNum < RegMIPS32::Reg_NUM);
220 (void)Ty;
221 return RegNames[RegNum];
222}
223
224Variable *TargetMIPS32::getPhysicalRegister(SizeT RegNum, Type Ty) {
225 if (Ty == IceType_void)
226 Ty = IceType_i32;
227 if (PhysicalRegisters[Ty].empty())
228 PhysicalRegisters[Ty].resize(RegMIPS32::Reg_NUM);
229 assert(RegNum < PhysicalRegisters[Ty].size());
230 Variable *Reg = PhysicalRegisters[Ty][RegNum];
231 if (Reg == nullptr) {
232 Reg = Func->makeVariable(Ty);
233 Reg->setRegNum(RegNum);
234 PhysicalRegisters[Ty][RegNum] = Reg;
235 // Specially mark SP as an "argument" so that it is considered
236 // live upon function entry.
237 if (RegNum == RegMIPS32::Reg_SP) {
238 Func->addImplicitArg(Reg);
239 Reg->setIgnoreLiveness();
240 }
241 }
242 return Reg;
243}
244
245void TargetMIPS32::emitVariable(const Variable *Var) const {
246 Ostream &Str = Ctx->getStrEmit();
247 (void)Var;
248 (void)Str;
249 llvm::report_fatal_error("emitVariable: Not yet implemented");
250}
251
252void TargetMIPS32::lowerArguments() {
253 llvm::report_fatal_error("lowerArguments: Not yet implemented");
254}
255
256Type TargetMIPS32::stackSlotType() { return IceType_i32; }
257
258void TargetMIPS32::addProlog(CfgNode *Node) {
259 (void)Node;
260 llvm::report_fatal_error("addProlog: Not yet implemented");
261}
262
263void TargetMIPS32::addEpilog(CfgNode *Node) {
264 (void)Node;
265 llvm::report_fatal_error("addEpilog: Not yet implemented");
266}
267
268llvm::SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include,
269 RegSetMask Exclude) const {
270 llvm::SmallBitVector Registers(RegMIPS32::Reg_NUM);
271
272#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
273 isFP) \
274 if (scratch && (Include & RegSet_CallerSave)) \
275 Registers[RegMIPS32::val] = true; \
276 if (preserved && (Include & RegSet_CalleeSave)) \
277 Registers[RegMIPS32::val] = true; \
278 if (stackptr && (Include & RegSet_StackPointer)) \
279 Registers[RegMIPS32::val] = true; \
280 if (frameptr && (Include & RegSet_FramePointer)) \
281 Registers[RegMIPS32::val] = true; \
282 if (scratch && (Exclude & RegSet_CallerSave)) \
283 Registers[RegMIPS32::val] = false; \
284 if (preserved && (Exclude & RegSet_CalleeSave)) \
285 Registers[RegMIPS32::val] = false; \
286 if (stackptr && (Exclude & RegSet_StackPointer)) \
287 Registers[RegMIPS32::val] = false; \
288 if (frameptr && (Exclude & RegSet_FramePointer)) \
289 Registers[RegMIPS32::val] = false;
290
291 REGMIPS32_TABLE
292
293#undef X
294
295 return Registers;
296}
297
298void TargetMIPS32::lowerAlloca(const InstAlloca *Inst) {
299 UsesFramePointer = true;
300 // Conservatively require the stack to be aligned. Some stack
301 // adjustment operations implemented below assume that the stack is
302 // aligned before the alloca. All the alloca code ensures that the
303 // stack alignment is preserved after the alloca. The stack alignment
304 // restriction can be relaxed in some cases.
305 NeedsStackAlignment = true;
306 (void)Inst;
307 llvm::report_fatal_error("Not yet implemented");
308}
309
310void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
311 switch (Inst->getOp()) {
312 case InstArithmetic::_num:
313 llvm_unreachable("Unknown arithmetic operator");
314 break;
315 case InstArithmetic::Add:
316 llvm::report_fatal_error("Not yet implemented");
317 break;
318 case InstArithmetic::And:
319 llvm::report_fatal_error("Not yet implemented");
320 break;
321 case InstArithmetic::Or:
322 llvm::report_fatal_error("Not yet implemented");
323 break;
324 case InstArithmetic::Xor:
325 llvm::report_fatal_error("Not yet implemented");
326 break;
327 case InstArithmetic::Sub:
328 llvm::report_fatal_error("Not yet implemented");
329 break;
330 case InstArithmetic::Mul:
331 llvm::report_fatal_error("Not yet implemented");
332 break;
333 case InstArithmetic::Shl:
334 llvm::report_fatal_error("Not yet implemented");
335 break;
336 case InstArithmetic::Lshr:
337 llvm::report_fatal_error("Not yet implemented");
338 break;
339 case InstArithmetic::Ashr:
340 llvm::report_fatal_error("Not yet implemented");
341 break;
342 case InstArithmetic::Udiv:
343 llvm::report_fatal_error("Not yet implemented");
344 break;
345 case InstArithmetic::Sdiv:
346 llvm::report_fatal_error("Not yet implemented");
347 break;
348 case InstArithmetic::Urem:
349 llvm::report_fatal_error("Not yet implemented");
350 break;
351 case InstArithmetic::Srem:
352 llvm::report_fatal_error("Not yet implemented");
353 break;
354 case InstArithmetic::Fadd:
355 llvm::report_fatal_error("Not yet implemented");
356 break;
357 case InstArithmetic::Fsub:
358 llvm::report_fatal_error("Not yet implemented");
359 break;
360 case InstArithmetic::Fmul:
361 llvm::report_fatal_error("Not yet implemented");
362 break;
363 case InstArithmetic::Fdiv:
364 llvm::report_fatal_error("Not yet implemented");
365 break;
366 case InstArithmetic::Frem:
367 llvm::report_fatal_error("Not yet implemented");
368 break;
369 }
370}
371
372void TargetMIPS32::lowerAssign(const InstAssign *Inst) {
373 (void)Inst;
374 llvm::report_fatal_error("Not yet implemented");
375}
376
377void TargetMIPS32::lowerBr(const InstBr *Inst) {
378 (void)Inst;
379 llvm::report_fatal_error("Not yet implemented");
380}
381
382void TargetMIPS32::lowerCall(const InstCall *Inst) {
383 (void)Inst;
384 llvm::report_fatal_error("Not yet implemented");
385}
386
387void TargetMIPS32::lowerCast(const InstCast *Inst) {
388 InstCast::OpKind CastKind = Inst->getCastKind();
389 switch (CastKind) {
390 default:
391 Func->setError("Cast type not supported");
392 return;
393 case InstCast::Sext: {
394 llvm::report_fatal_error("Not yet implemented");
395 break;
396 }
397 case InstCast::Zext: {
398 llvm::report_fatal_error("Not yet implemented");
399 break;
400 }
401 case InstCast::Trunc: {
402 llvm::report_fatal_error("Not yet implemented");
403 break;
404 }
405 case InstCast::Fptrunc:
406 llvm::report_fatal_error("Not yet implemented");
407 break;
408 case InstCast::Fpext: {
409 llvm::report_fatal_error("Not yet implemented");
410 break;
411 }
412 case InstCast::Fptosi:
413 llvm::report_fatal_error("Not yet implemented");
414 break;
415 case InstCast::Fptoui:
416 llvm::report_fatal_error("Not yet implemented");
417 break;
418 case InstCast::Sitofp:
419 llvm::report_fatal_error("Not yet implemented");
420 break;
421 case InstCast::Uitofp: {
422 llvm::report_fatal_error("Not yet implemented");
423 break;
424 }
425 case InstCast::Bitcast: {
426 llvm::report_fatal_error("Not yet implemented");
427 break;
428 }
429 }
430}
431
432void TargetMIPS32::lowerExtractElement(const InstExtractElement *Inst) {
433 (void)Inst;
434 llvm::report_fatal_error("Not yet implemented");
435}
436
437void TargetMIPS32::lowerFcmp(const InstFcmp *Inst) {
438 (void)Inst;
439 llvm::report_fatal_error("Not yet implemented");
440}
441
442void TargetMIPS32::lowerIcmp(const InstIcmp *Inst) {
443 (void)Inst;
444 llvm::report_fatal_error("Not yet implemented");
445}
446
447void TargetMIPS32::lowerInsertElement(const InstInsertElement *Inst) {
448 (void)Inst;
449 llvm::report_fatal_error("Not yet implemented");
450}
451
452void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
453 switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
454 case Intrinsics::AtomicCmpxchg: {
455 llvm::report_fatal_error("Not yet implemented");
456 return;
457 }
458 case Intrinsics::AtomicFence:
459 llvm::report_fatal_error("Not yet implemented");
460 return;
461 case Intrinsics::AtomicFenceAll:
462 // NOTE: FenceAll should prevent and load/store from being moved
463 // across the fence (both atomic and non-atomic). The InstMIPS32Mfence
464 // instruction is currently marked coarsely as "HasSideEffects".
465 llvm::report_fatal_error("Not yet implemented");
466 return;
467 case Intrinsics::AtomicIsLockFree: {
468 llvm::report_fatal_error("Not yet implemented");
469 return;
470 }
471 case Intrinsics::AtomicLoad: {
472 llvm::report_fatal_error("Not yet implemented");
473 return;
474 }
475 case Intrinsics::AtomicRMW:
476 llvm::report_fatal_error("Not yet implemented");
477 return;
478 case Intrinsics::AtomicStore: {
479 llvm::report_fatal_error("Not yet implemented");
480 return;
481 }
482 case Intrinsics::Bswap: {
483 llvm::report_fatal_error("Not yet implemented");
484 return;
485 }
486 case Intrinsics::Ctpop: {
487 llvm::report_fatal_error("Not yet implemented");
488 return;
489 }
490 case Intrinsics::Ctlz: {
491 llvm::report_fatal_error("Not yet implemented");
492 return;
493 }
494 case Intrinsics::Cttz: {
495 llvm::report_fatal_error("Not yet implemented");
496 return;
497 }
498 case Intrinsics::Fabs: {
499 llvm::report_fatal_error("Not yet implemented");
500 return;
501 }
502 case Intrinsics::Longjmp: {
503 InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2);
504 Call->addArg(Instr->getArg(0));
505 Call->addArg(Instr->getArg(1));
506 lowerCall(Call);
507 return;
508 }
509 case Intrinsics::Memcpy: {
510 // In the future, we could potentially emit an inline memcpy/memset, etc.
511 // for intrinsic calls w/ a known length.
512 InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3);
513 Call->addArg(Instr->getArg(0));
514 Call->addArg(Instr->getArg(1));
515 Call->addArg(Instr->getArg(2));
516 lowerCall(Call);
517 return;
518 }
519 case Intrinsics::Memmove: {
520 InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3);
521 Call->addArg(Instr->getArg(0));
522 Call->addArg(Instr->getArg(1));
523 Call->addArg(Instr->getArg(2));
524 lowerCall(Call);
525 return;
526 }
527 case Intrinsics::Memset: {
528 // The value operand needs to be extended to a stack slot size
529 // because the PNaCl ABI requires arguments to be at least 32 bits
530 // wide.
531 Operand *ValOp = Instr->getArg(1);
532 assert(ValOp->getType() == IceType_i8);
533 Variable *ValExt = Func->makeVariable(stackSlotType());
534 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
535 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3);
536 Call->addArg(Instr->getArg(0));
537 Call->addArg(ValExt);
538 Call->addArg(Instr->getArg(2));
539 lowerCall(Call);
540 return;
541 }
542 case Intrinsics::NaClReadTP: {
543 if (Ctx->getFlags().getUseSandboxing()) {
544 llvm::report_fatal_error("Not yet implemented");
545 } else {
546 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
547 lowerCall(Call);
548 }
549 return;
550 }
551 case Intrinsics::Setjmp: {
552 InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1);
553 Call->addArg(Instr->getArg(0));
554 lowerCall(Call);
555 return;
556 }
557 case Intrinsics::Sqrt: {
558 llvm::report_fatal_error("Not yet implemented");
559 return;
560 }
561 case Intrinsics::Stacksave: {
562 llvm::report_fatal_error("Not yet implemented");
563 return;
564 }
565 case Intrinsics::Stackrestore: {
566 llvm::report_fatal_error("Not yet implemented");
567 return;
568 }
569 case Intrinsics::Trap:
570 llvm::report_fatal_error("Not yet implemented");
571 return;
572 case Intrinsics::UnknownIntrinsic:
573 Func->setError("Should not be lowering UnknownIntrinsic");
574 return;
575 }
576 return;
577}
578
579void TargetMIPS32::lowerLoad(const InstLoad *Inst) {
580 (void)Inst;
581 llvm::report_fatal_error("Not yet implemented");
582}
583
584void TargetMIPS32::doAddressOptLoad() {
585 llvm::report_fatal_error("Not yet implemented");
586}
587
588void TargetMIPS32::randomlyInsertNop(float Probability) {
589 RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
590 if (RNG.getTrueWithProbability(Probability)) {
591 llvm::report_fatal_error("Not yet implemented");
592 }
593}
594
595void TargetMIPS32::lowerPhi(const InstPhi * /*Inst*/) {
596 Func->setError("Phi found in regular instruction list");
597}
598
599void TargetMIPS32::lowerRet(const InstRet *Inst) {
600 (void)Inst;
601 llvm::report_fatal_error("Not yet implemented");
602}
603
604void TargetMIPS32::lowerSelect(const InstSelect *Inst) {
605 (void)Inst;
606 llvm::report_fatal_error("Not yet implemented");
607}
608
609void TargetMIPS32::lowerStore(const InstStore *Inst) {
610 (void)Inst;
611 llvm::report_fatal_error("Not yet implemented");
612}
613
614void TargetMIPS32::doAddressOptStore() {
615 llvm::report_fatal_error("Not yet implemented");
616}
617
618void TargetMIPS32::lowerSwitch(const InstSwitch *Inst) {
619 (void)Inst;
620 llvm::report_fatal_error("Not yet implemented");
621}
622
623void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
624 llvm_unreachable("Not yet implemented");
625}
626
627// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
628// preserve integrity of liveness analysis. Undef values are also
629// turned into zeroes, since loOperand() and hiOperand() don't expect
630// Undef input.
631void TargetMIPS32::prelowerPhis() {
632 llvm::report_fatal_error("Not yet implemented");
633}
634
635// Lower the pre-ordered list of assignments into mov instructions.
636// Also has to do some ad-hoc register allocation as necessary.
637void TargetMIPS32::lowerPhiAssignments(CfgNode *Node,
638 const AssignList &Assignments) {
639 (void)Node;
640 (void)Assignments;
641 llvm::report_fatal_error("Not yet implemented");
642}
643
644void TargetMIPS32::postLower() {
645 if (Ctx->getFlags().getOptLevel() == Opt_m1)
646 return;
647 // Find two-address non-SSA instructions where Dest==Src0, and set
648 // the DestNonKillable flag to keep liveness analysis consistent.
649 llvm::report_fatal_error("Not yet implemented");
650}
651
652void TargetMIPS32::makeRandomRegisterPermutation(
653 llvm::SmallVectorImpl<int32_t> &Permutation,
654 const llvm::SmallBitVector &ExcludeRegisters) const {
655 (void)Permutation;
656 (void)ExcludeRegisters;
657 llvm::report_fatal_error("Not yet implemented");
658}
659
660/* TODO(jvoung): avoid duplicate symbols with multiple targets.
661void ConstantUndef::emitWithoutDollar(GlobalContext *) const {
662 llvm_unreachable("Not expecting to emitWithoutDollar undef");
663}
664
665void ConstantUndef::emit(GlobalContext *) const {
666 llvm_unreachable("undef value encountered by emitter.");
667}
668*/
669
670TargetDataMIPS32::TargetDataMIPS32(GlobalContext *Ctx)
671 : TargetDataLowering(Ctx) {}
672
John Porto8b1a7052015-06-17 13:20:08 -0700673void TargetDataMIPS32::lowerGlobals(const VariableDeclarationList &Vars,
674 const IceString &SectionSuffix) {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700675 switch (Ctx->getFlags().getOutFileType()) {
676 case FT_Elf: {
677 ELFObjectWriter *Writer = Ctx->getObjectWriter();
John Porto8b1a7052015-06-17 13:20:08 -0700678 Writer->writeDataSection(Vars, llvm::ELF::R_MIPS_GLOB_DAT, SectionSuffix);
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700679 } break;
680 case FT_Asm:
681 case FT_Iasm: {
682 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly();
683 OstreamLocker L(Ctx);
John Porto8b1a7052015-06-17 13:20:08 -0700684 for (const VariableDeclaration *Var : Vars) {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700685 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
John Porto8b1a7052015-06-17 13:20:08 -0700686 emitGlobal(*Var, SectionSuffix);
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700687 }
688 }
689 } break;
690 }
691}
692
John Porto0f86d032015-06-15 07:44:27 -0700693void TargetDataMIPS32::lowerConstants() {
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700694 if (Ctx->getFlags().getDisableTranslation())
695 return;
696 llvm::report_fatal_error("Not yet implemented");
697}
698
Jan Voungfb792842015-06-11 15:27:50 -0700699TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
700 : TargetHeaderLowering(Ctx) {}
701
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700702} // end of namespace Ice