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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 1416493002: Implements simple returns and call args for Mips. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 2 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/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// 1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===//
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
11 /// This file implements the TargetLoweringMIPS32 class, which consists almost 11 /// This file implements the TargetLoweringMIPS32 class, which consists almost
12 /// entirely of the lowering sequence for each high-level instruction. 12 /// entirely of the lowering sequence for each high-level instruction.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "IceTargetLoweringMIPS32.h" 16 #include "IceTargetLoweringMIPS32.h"
17 17
18 #include "IceCfg.h" 18 #include "IceCfg.h"
19 #include "IceCfgNode.h" 19 #include "IceCfgNode.h"
20 #include "IceClFlags.h" 20 #include "IceClFlags.h"
21 #include "IceDefs.h" 21 #include "IceDefs.h"
22 #include "IceELFObjectWriter.h" 22 #include "IceELFObjectWriter.h"
23 #include "IceGlobalInits.h" 23 #include "IceGlobalInits.h"
24 #include "IceInstMIPS32.h" 24 #include "IceInstMIPS32.h"
25 #include "IceLiveness.h" 25 #include "IceLiveness.h"
26 #include "IceOperand.h" 26 #include "IceOperand.h"
27 #include "IcePhiLoweringImpl.h"
27 #include "IceRegistersMIPS32.h" 28 #include "IceRegistersMIPS32.h"
28 #include "IceTargetLoweringMIPS32.def" 29 #include "IceTargetLoweringMIPS32.def"
29 #include "IceUtils.h" 30 #include "IceUtils.h"
30 #include "llvm/Support/MathExtras.h" 31 #include "llvm/Support/MathExtras.h"
31 32
32 namespace Ice { 33 namespace Ice {
33 34
35 using llvm::isInt;
36
34 namespace { 37 namespace {
35 void UnimplementedError(const ClFlags &Flags) { 38 void UnimplementedError(const ClFlags &Flags) {
36 if (!Flags.getSkipUnimplemented()) { 39 if (!Flags.getSkipUnimplemented()) {
37 // Use llvm_unreachable instead of report_fatal_error, which gives better 40 // Use llvm_unreachable instead of report_fatal_error, which gives better
38 // stack traces. 41 // stack traces.
39 llvm_unreachable("Not yet implemented"); 42 llvm_unreachable("Not yet implemented");
40 abort(); 43 abort();
41 } 44 }
42 } 45 }
46
47 // The maximum number of arguments to pass in GPR registers.
48 const uint32_t MIPS32_MAX_GPR_ARG = 4;
Jim Stichnoth 2015/10/18 11:48:40 Use constexpr if possible.
rkotlerimgtec 2015/10/19 00:12:00 Done.
49
43 } // end of anonymous namespace 50 } // end of anonymous namespace
44 51
45 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) { 52 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {
46 // TODO: Don't initialize IntegerRegisters and friends every time. Instead, 53 // TODO: Don't initialize IntegerRegisters and friends every time. Instead,
47 // initialize in some sort of static initializer for the class. 54 // initialize in some sort of static initializer for the class.
55
48 llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); 56 llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM);
49 llvm::SmallBitVector FloatRegisters(RegMIPS32::Reg_NUM); 57 llvm::SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM);
58 llvm::SmallBitVector Float32Registers(RegMIPS32::Reg_NUM);
59 llvm::SmallBitVector Float64Registers(RegMIPS32::Reg_NUM);
50 llvm::SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM); 60 llvm::SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM);
51 llvm::SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM); 61 llvm::SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM);
52 ScratchRegs.resize(RegMIPS32::Reg_NUM); 62 ScratchRegs.resize(RegMIPS32::Reg_NUM);
53 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ 63 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
54 isFP) \ 64 isI64Pair, isFP32, isFP64, isVec128, alias_init) \
55 IntegerRegisters[RegMIPS32::val] = isInt; \ 65 IntegerRegisters[RegMIPS32::val] = isInt; \
56 FloatRegisters[RegMIPS32::val] = isFP; \ 66 I64PairRegisters[RegMIPS32::val] = isI64Pair; \
57 VectorRegisters[RegMIPS32::val] = isFP; \ 67 Float32Registers[RegMIPS32::val] = isFP32; \
68 Float64Registers[RegMIPS32::val] = isFP64; \
69 VectorRegisters[RegMIPS32::val] = isVec128; \
58 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \ 70 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \
59 RegisterAliases[RegMIPS32::val].set(RegMIPS32::val); \ 71 for (SizeT RegAlias : alias_init) { \
72 assert(!RegisterAliases[RegMIPS32::val][RegAlias] && \
73 "Duplicate alias for " #val); \
74 RegisterAliases[RegMIPS32::val].set(RegAlias); \
75 } \
76 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \
77 assert(RegisterAliases[RegMIPS32::val][RegMIPS32::val]); \
60 ScratchRegs[RegMIPS32::val] = scratch; 78 ScratchRegs[RegMIPS32::val] = scratch;
61 REGMIPS32_TABLE; 79 REGMIPS32_TABLE;
62 #undef X 80 #undef X
63 TypeToRegisterSet[IceType_void] = InvalidRegisters; 81 TypeToRegisterSet[IceType_void] = InvalidRegisters;
64 TypeToRegisterSet[IceType_i1] = IntegerRegisters; 82 TypeToRegisterSet[IceType_i1] = IntegerRegisters;
65 TypeToRegisterSet[IceType_i8] = IntegerRegisters; 83 TypeToRegisterSet[IceType_i8] = IntegerRegisters;
66 TypeToRegisterSet[IceType_i16] = IntegerRegisters; 84 TypeToRegisterSet[IceType_i16] = IntegerRegisters;
67 TypeToRegisterSet[IceType_i32] = IntegerRegisters; 85 TypeToRegisterSet[IceType_i32] = IntegerRegisters;
68 TypeToRegisterSet[IceType_i64] = IntegerRegisters; 86 TypeToRegisterSet[IceType_i64] = IntegerRegisters;
69 TypeToRegisterSet[IceType_f32] = FloatRegisters; 87 TypeToRegisterSet[IceType_f32] = Float32Registers;
70 TypeToRegisterSet[IceType_f64] = FloatRegisters; 88 TypeToRegisterSet[IceType_f64] = Float64Registers;
71 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 89 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
72 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 90 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
73 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 91 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
74 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 92 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
75 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 93 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
76 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 94 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
77 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 95 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
78 } 96 }
79 97
80 void TargetMIPS32::translateO2() { 98 void TargetMIPS32::translateO2() {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 (void)NextNode; 235 (void)NextNode;
218 UnimplementedError(Func->getContext()->getFlags()); 236 UnimplementedError(Func->getContext()->getFlags());
219 return false; 237 return false;
220 } 238 }
221 239
222 IceString TargetMIPS32::getRegName(SizeT RegNum, Type Ty) const { 240 IceString TargetMIPS32::getRegName(SizeT RegNum, Type Ty) const {
223 assert(RegNum < RegMIPS32::Reg_NUM); 241 assert(RegNum < RegMIPS32::Reg_NUM);
224 (void)Ty; 242 (void)Ty;
225 static const char *RegNames[] = { 243 static const char *RegNames[] = {
226 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ 244 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
227 isFP) \ 245 isI64Pair, isFP32, isFP64, isVec128, alias_init) \
228 name, 246 name,
229 REGMIPS32_TABLE 247 REGMIPS32_TABLE
230 #undef X 248 #undef X
231 }; 249 };
232 return RegNames[RegNum]; 250 return RegNames[RegNum];
233 } 251 }
234 252
235 Variable *TargetMIPS32::getPhysicalRegister(SizeT RegNum, Type Ty) { 253 Variable *TargetMIPS32::getPhysicalRegister(SizeT RegNum, Type Ty) {
236 if (Ty == IceType_void) 254 if (Ty == IceType_void)
237 Ty = IceType_i32; 255 Ty = IceType_i32;
(...skipping 14 matching lines...) Expand all
252 } 270 }
253 return Reg; 271 return Reg;
254 } 272 }
255 273
256 void TargetMIPS32::emitJumpTable(const Cfg *Func, 274 void TargetMIPS32::emitJumpTable(const Cfg *Func,
257 const InstJumpTable *JumpTable) const { 275 const InstJumpTable *JumpTable) const {
258 (void)JumpTable; 276 (void)JumpTable;
259 UnimplementedError(Func->getContext()->getFlags()); 277 UnimplementedError(Func->getContext()->getFlags());
260 } 278 }
261 279
280 /// Provide a trivial wrapper to legalize() for this common usage.
281 Variable *TargetMIPS32::legalizeToReg(Operand *From, int32_t RegNum) {
282 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
283 }
284
285 /// Legalize undef values to concrete values.
286 Operand *TargetMIPS32::legalizeUndef(Operand *From, int32_t RegNum) {
287 (void)RegNum;
288 Type Ty = From->getType();
289 if (llvm::isa<ConstantUndef>(From)) {
290 // Lower undefs to zero. Another option is to lower undefs to an
291 // uninitialized register; however, using an uninitialized register
292 // results in less predictable code.
293 //
294 // If in the future the implementation is changed to lower undef
295 // values to uninitialized registers, a FakeDef will be needed:
296 // Context.insert(InstFakeDef::create(Func, Reg));
297 // This is in order to ensure that the live range of Reg is not
298 // overestimated. If the constant being lowered is a 64 bit value,
299 // then the result should be split and the lo and hi components will
300 // need to go in uninitialized registers.
301 if (isVectorType(Ty))
302 UnimplementedError(Func->getContext()->getFlags());
303 return Ctx->getConstantZero(Ty);
304 }
305 return From;
306 }
307
308 Variable *TargetMIPS32::makeReg(Type Type, int32_t RegNum) {
309 // There aren't any 64-bit integer registers for Mips32.
310 assert(Type != IceType_i64);
311 Variable *Reg = Func->makeVariable(Type);
312 if (RegNum == Variable::NoRegister)
313 Reg->setMustHaveReg();
314 else
315 Reg->setRegNum(RegNum);
316 return Reg;
317 }
318
262 void TargetMIPS32::emitVariable(const Variable *Var) const { 319 void TargetMIPS32::emitVariable(const Variable *Var) const {
263 if (!BuildDefs::dump()) 320 if (!BuildDefs::dump())
264 return; 321 return;
265 Ostream &Str = Ctx->getStrEmit(); 322 Ostream &Str = Ctx->getStrEmit();
266 (void)Var; 323 const Type FrameSPTy = IceType_i32;
267 (void)Str; 324 if (Var->hasReg()) {
325 Str << '$' << getRegName(Var->getRegNum(), Var->getType());
326 return;
327 } else {
328 int32_t Offset = Var->getStackOffset();
329 Str << Offset;
330 Str << "(" << getRegName(getFrameOrStackReg(), FrameSPTy);
331 Str << ")";
332 }
268 UnimplementedError(Func->getContext()->getFlags()); 333 UnimplementedError(Func->getContext()->getFlags());
Jim Stichnoth 2015/10/18 11:48:39 Is the stack reference part actually unimplemented
rkotlerimgtec 2015/10/19 00:12:00 It's incomplete. I was starting to add it but real
269 } 334 }
270 335
271 void TargetMIPS32::lowerArguments() { 336 void TargetMIPS32::lowerArguments() {
272 VarList &Args = Func->getArgs(); 337 VarList &Args = Func->getArgs();
273 if (Args.size() > 0) 338 // We are only handling integer registers for now. The Mips o32 ABI is
274 UnimplementedError(Func->getContext()->getFlags()); 339 // somewhat complex but will be implemented in it's totality through follow
Jim Stichnoth 2015/10/18 11:48:39 its
rkotlerimgtec 2015/10/19 00:12:00 Done.
340 // on patches.
341 //
342 unsigned NumGPRRegsUsed = 0;
343 (void)NumGPRRegsUsed;
Jim Stichnoth 2015/10/18 11:48:39 remove this
rkotlerimgtec 2015/10/19 00:12:00 Done.
344 // For each register argument, replace Arg in the argument list with the
345 // home register. Then generate an instruction in the prolog to copy the
346 // home register to the assigned location of Arg.
347 Context.init(Func->getEntryNode());
348 Context.setInsertPoint(Context.getCur());
349 for (SizeT I = 0, E = Args.size(); I < E; ++I) {
Jim Stichnoth 2015/10/18 11:48:40 I can't tell for sure whether I or E are really us
rkotlerimgtec 2015/10/19 00:12:00 I is used.
350 Variable *Arg = Args[I];
351 Type Ty = Arg->getType();
352 // TODO(rkotler): handle float/vector types.
353 if (isVectorType(Ty)) {
354 UnimplementedError(Func->getContext()->getFlags());
355 continue;
Jim Stichnoth 2015/10/18 11:48:39 Don't use "else if" following a "continue". I.e.,
rkotlerimgtec 2015/10/19 00:12:00 Done.
356 } else if (isFloatingType(Ty)) {
357 UnimplementedError(Func->getContext()->getFlags());
358 continue;
359 } else if (Ty == IceType_i64) {
360 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG)
361 continue;
362 int32_t RegLo = RegMIPS32::Reg_A0 + NumGPRRegsUsed;
363 int32_t RegHi = RegLo + 1;
364 ++NumGPRRegsUsed;
365 // Always start i64 registers at an even register, so this may end
366 // up padding away a register.
367 if (RegLo % 2 != 0) {
368 ++RegLo;
369 ++NumGPRRegsUsed;
370 }
371 // If this leaves us without room to consume another register,
372 // leave any previously speculatively consumed registers as consumed.
373 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG)
374 continue;
375 // RegHi = RegMIPS32::Reg_A0 + NumGPRRegsUsed;
376 ++NumGPRRegsUsed;
377 Variable *RegisterArg = Func->makeVariable(Ty);
378 auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg);
379 if (BuildDefs::dump())
380 RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func));
381 RegisterArg64On32->initHiLo(Func);
382 RegisterArg64On32->setIsArg();
383 RegisterArg64On32->getLo()->setRegNum(RegLo);
384 RegisterArg64On32->getHi()->setRegNum(RegHi);
385 Arg->setIsArg(false);
386 Args[I] = RegisterArg64On32;
387 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
388 continue;
389 } else {
390 assert(Ty == IceType_i32);
391 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG)
392 continue;
393 int32_t RegNum = RegMIPS32::Reg_A0 + NumGPRRegsUsed;
394 ++NumGPRRegsUsed;
395 Variable *RegisterArg = Func->makeVariable(Ty);
396 if (BuildDefs::dump()) {
397 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
398 }
399 RegisterArg->setRegNum(RegNum);
400 RegisterArg->setIsArg();
401 Arg->setIsArg(false);
402 Args[I] = RegisterArg;
403 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
404 }
405 }
275 } 406 }
276 407
277 Type TargetMIPS32::stackSlotType() { return IceType_i32; } 408 Type TargetMIPS32::stackSlotType() { return IceType_i32; }
278 409
279 void TargetMIPS32::addProlog(CfgNode *Node) { 410 void TargetMIPS32::addProlog(CfgNode *Node) {
280 (void)Node; 411 (void)Node;
412 return;
281 UnimplementedError(Func->getContext()->getFlags()); 413 UnimplementedError(Func->getContext()->getFlags());
282 } 414 }
283 415
284 void TargetMIPS32::addEpilog(CfgNode *Node) { 416 void TargetMIPS32::addEpilog(CfgNode *Node) {
285 (void)Node; 417 (void)Node;
286 UnimplementedError(Func->getContext()->getFlags()); 418 return;
419 UnimplementedError(Func->getContext()->getFlags());
420 }
421
Jim Stichnoth 2015/10/18 11:48:39 just one blank line here
rkotlerimgtec 2015/10/19 00:12:00 Done.
422
423 Operand *TargetMIPS32::loOperand(Operand *Operand) {
424 assert(Operand->getType() == IceType_i64);
425 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
426 return Var64On32->getLo();
427 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
Jim Stichnoth 2015/10/18 11:48:39 auto *Const
rkotlerimgtec 2015/10/19 00:12:00 Done.
rkotlerimgtec 2015/10/19 00:12:01 Done.
428 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue()));
429 }
430 if (OperandMIPS32Mem *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
Jim Stichnoth 2015/10/18 11:48:39 auto *Mem
rkotlerimgtec 2015/10/19 00:12:00 Done.
431 // Conservatively disallow memory operands with side-effects (pre/post
432 // increment) in case of duplication.
433 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
434 return OperandMIPS32Mem::create(Func, IceType_i32, Mem->getBase(),
435 Mem->getOffset(), Mem->getAddrMode());
436 }
437 llvm_unreachable("Unsupported operand type");
438 return nullptr;
439 }
440
441 Operand *TargetMIPS32::hiOperand(Operand *Operand) {
442 assert(Operand->getType() == IceType_i64);
443 if (Operand->getType() != IceType_i64)
444 return Operand;
445 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
446 return Var64On32->getHi();
447 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
Jim Stichnoth 2015/10/18 11:48:40 auto *Const
rkotlerimgtec 2015/10/19 00:12:00 Done.
448 return Ctx->getConstantInt32(
449 static_cast<uint32_t>(Const->getValue() >> 32));
450 }
451 if (OperandMIPS32Mem *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
Jim Stichnoth 2015/10/18 11:48:39 auto *Mem
rkotlerimgtec 2015/10/19 00:12:00 Done.
452 // Conservatively disallow memory operands with side-effects
453 // in case of duplication.
454 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
455 const Type SplitType = IceType_i32;
456 Variable *Base = Mem->getBase();
457 ConstantInteger32 *Offset = Mem->getOffset();
458 assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4));
459 int32_t NextOffsetVal = Offset->getValue() + 4;
460 const bool SignExt = false;
Jim Stichnoth 2015/10/18 11:48:39 constexpr
rkotlerimgtec 2015/10/19 00:12:00 Done.
461 if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) {
462 // We have to make a temp variable and add 4 to either Base or Offset.
463 // If we add 4 to Offset, this will convert a non-RegReg addressing
464 // mode into a RegReg addressing mode. Since NaCl sandboxing disallows
465 // RegReg addressing modes, prefer adding to base and replacing instead.
466 // Thus we leave the old offset alone.
467 Constant *Four = Ctx->getConstantInt32(4);
468 Variable *NewBase = Func->makeVariable(Base->getType());
469 lowerArithmetic(InstArithmetic::create(Func, InstArithmetic::Add, NewBase,
470 Base, Four));
471 Base = NewBase;
472 } else {
473 Offset =
474 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(NextOffsetVal));
475 }
476 return OperandMIPS32Mem::create(Func, SplitType, Base, Offset,
477 Mem->getAddrMode());
478 }
479 llvm_unreachable("Unsupported operand type");
480 return nullptr;
287 } 481 }
288 482
289 llvm::SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include, 483 llvm::SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include,
290 RegSetMask Exclude) const { 484 RegSetMask Exclude) const {
291 llvm::SmallBitVector Registers(RegMIPS32::Reg_NUM); 485 llvm::SmallBitVector Registers(RegMIPS32::Reg_NUM);
292 486
293 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ 487 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \
294 isFP) \ 488 isI64Pair, isFP32, isFP64, isVec128, alias_init) \
295 if (scratch && (Include & RegSet_CallerSave)) \ 489 if (scratch && (Include & RegSet_CallerSave)) \
296 Registers[RegMIPS32::val] = true; \ 490 Registers[RegMIPS32::val] = true; \
297 if (preserved && (Include & RegSet_CalleeSave)) \ 491 if (preserved && (Include & RegSet_CalleeSave)) \
298 Registers[RegMIPS32::val] = true; \ 492 Registers[RegMIPS32::val] = true; \
299 if (stackptr && (Include & RegSet_StackPointer)) \ 493 if (stackptr && (Include & RegSet_StackPointer)) \
300 Registers[RegMIPS32::val] = true; \ 494 Registers[RegMIPS32::val] = true; \
301 if (frameptr && (Include & RegSet_FramePointer)) \ 495 if (frameptr && (Include & RegSet_FramePointer)) \
302 Registers[RegMIPS32::val] = true; \ 496 Registers[RegMIPS32::val] = true; \
303 if (scratch && (Exclude & RegSet_CallerSave)) \ 497 if (scratch && (Exclude & RegSet_CallerSave)) \
304 Registers[RegMIPS32::val] = false; \ 498 Registers[RegMIPS32::val] = false; \
(...skipping 17 matching lines...) Expand all
322 // operations implemented below assume that the stack is aligned before the 516 // operations implemented below assume that the stack is aligned before the
323 // alloca. All the alloca code ensures that the stack alignment is preserved 517 // alloca. All the alloca code ensures that the stack alignment is preserved
324 // after the alloca. The stack alignment restriction can be relaxed in some 518 // after the alloca. The stack alignment restriction can be relaxed in some
325 // cases. 519 // cases.
326 NeedsStackAlignment = true; 520 NeedsStackAlignment = true;
327 (void)Inst; 521 (void)Inst;
328 UnimplementedError(Func->getContext()->getFlags()); 522 UnimplementedError(Func->getContext()->getFlags());
329 } 523 }
330 524
331 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { 525 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
332 switch (Inst->getOp()) { 526 Variable *Dest = Inst->getDest();
333 case InstArithmetic::_num: 527 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
528 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
529 (void)Src0;
530 (void)Src1;
531 if (Dest->getType() == IceType_i64) {
334 UnimplementedError(Func->getContext()->getFlags()); 532 UnimplementedError(Func->getContext()->getFlags());
335 break; 533 } else if (isVectorType(Dest->getType())) {
336 case InstArithmetic::Add:
337 UnimplementedError(Func->getContext()->getFlags()); 534 UnimplementedError(Func->getContext()->getFlags());
338 break; 535 } else { // Dest->getType() is non-i64 scalar
339 case InstArithmetic::And: 536 switch (Inst->getOp()) {
340 UnimplementedError(Func->getContext()->getFlags()); 537 case InstArithmetic::_num:
341 break; 538 UnimplementedError(Func->getContext()->getFlags());
342 case InstArithmetic::Or: 539 break;
343 UnimplementedError(Func->getContext()->getFlags()); 540 case InstArithmetic::Add:
344 break; 541 UnimplementedError(Func->getContext()->getFlags());
345 case InstArithmetic::Xor: 542 // Variable *T = makeReg(Dest->getType());
346 UnimplementedError(Func->getContext()->getFlags()); 543 // _add(T, Src0, Src1);
347 break; 544 // _mov(Dest, T);
348 case InstArithmetic::Sub: 545 return;
349 UnimplementedError(Func->getContext()->getFlags()); 546 case InstArithmetic::And:
350 break; 547 UnimplementedError(Func->getContext()->getFlags());
351 case InstArithmetic::Mul: 548 break;
352 UnimplementedError(Func->getContext()->getFlags()); 549 case InstArithmetic::Or:
353 break; 550 UnimplementedError(Func->getContext()->getFlags());
354 case InstArithmetic::Shl: 551 break;
355 UnimplementedError(Func->getContext()->getFlags()); 552 case InstArithmetic::Xor:
356 break; 553 UnimplementedError(Func->getContext()->getFlags());
357 case InstArithmetic::Lshr: 554 break;
358 UnimplementedError(Func->getContext()->getFlags()); 555 case InstArithmetic::Sub:
359 break; 556 UnimplementedError(Func->getContext()->getFlags());
360 case InstArithmetic::Ashr: 557 break;
361 UnimplementedError(Func->getContext()->getFlags()); 558 case InstArithmetic::Mul:
362 break; 559 UnimplementedError(Func->getContext()->getFlags());
363 case InstArithmetic::Udiv: 560 break;
364 UnimplementedError(Func->getContext()->getFlags()); 561 case InstArithmetic::Shl:
365 break; 562 UnimplementedError(Func->getContext()->getFlags());
366 case InstArithmetic::Sdiv: 563 break;
367 UnimplementedError(Func->getContext()->getFlags()); 564 case InstArithmetic::Lshr:
368 break; 565 UnimplementedError(Func->getContext()->getFlags());
369 case InstArithmetic::Urem: 566 break;
370 UnimplementedError(Func->getContext()->getFlags()); 567 case InstArithmetic::Ashr:
371 break; 568 UnimplementedError(Func->getContext()->getFlags());
372 case InstArithmetic::Srem: 569 break;
373 UnimplementedError(Func->getContext()->getFlags()); 570 case InstArithmetic::Udiv:
374 break; 571 UnimplementedError(Func->getContext()->getFlags());
375 case InstArithmetic::Fadd: 572 break;
376 UnimplementedError(Func->getContext()->getFlags()); 573 case InstArithmetic::Sdiv:
377 break; 574 UnimplementedError(Func->getContext()->getFlags());
378 case InstArithmetic::Fsub: 575 break;
379 UnimplementedError(Func->getContext()->getFlags()); 576 case InstArithmetic::Urem:
380 break; 577 UnimplementedError(Func->getContext()->getFlags());
381 case InstArithmetic::Fmul: 578 break;
382 UnimplementedError(Func->getContext()->getFlags()); 579 case InstArithmetic::Srem:
383 break; 580 UnimplementedError(Func->getContext()->getFlags());
384 case InstArithmetic::Fdiv: 581 break;
385 UnimplementedError(Func->getContext()->getFlags()); 582 case InstArithmetic::Fadd:
386 break; 583 UnimplementedError(Func->getContext()->getFlags());
387 case InstArithmetic::Frem: 584 break;
388 UnimplementedError(Func->getContext()->getFlags()); 585 case InstArithmetic::Fsub:
389 break; 586 UnimplementedError(Func->getContext()->getFlags());
587 break;
588 case InstArithmetic::Fmul:
589 UnimplementedError(Func->getContext()->getFlags());
590 break;
591 case InstArithmetic::Fdiv:
592 UnimplementedError(Func->getContext()->getFlags());
593 break;
594 case InstArithmetic::Frem:
595 UnimplementedError(Func->getContext()->getFlags());
596 break;
597 }
390 } 598 }
391 } 599 }
392 600
393 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { 601 void TargetMIPS32::lowerAssign(const InstAssign *Inst) {
394 (void)Inst; 602 Variable *Dest = Inst->getDest();
395 UnimplementedError(Func->getContext()->getFlags()); 603 Operand *Src0 = Inst->getSrc(0);
604 assert(Dest->getType() == Src0->getType());
605 if (Dest->getType() == IceType_i64) {
606 Src0 = legalizeUndef(Src0);
607 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
608 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
609 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
610 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
611 // Variable *T_Lo = nullptr, *T_Hi = nullptr;
612 Variable *T_Lo = makeReg(IceType_i32);
613 Variable *T_Hi = makeReg(IceType_i32);
614 _mov(T_Lo, Src0Lo);
615 _mov(DestLo, T_Lo);
616 _mov(T_Hi, Src0Hi);
617 _mov(DestHi, T_Hi);
618 } else {
619 Operand *SrcR;
620 if (Dest->hasReg()) {
621 // If Dest already has a physical register, then legalize the Src operand
622 // into a Variable with the same register assignment. This especially
623 // helps allow the use of Flex operands.
624 SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum());
625 } else {
626 // Dest could be a stack operand. Since we could potentially need
627 // to do a Store (and store can only have Register operands),
628 // legalize this to a register.
629 SrcR = legalize(Src0, Legal_Reg);
630 }
631 if (isVectorType(Dest->getType())) {
632 UnimplementedError(Func->getContext()->getFlags());
633 } else {
634 _mov(Dest, SrcR);
635 }
636 }
396 } 637 }
397 638
398 void TargetMIPS32::lowerBr(const InstBr *Inst) { 639 void TargetMIPS32::lowerBr(const InstBr *Inst) {
399 (void)Inst; 640 (void)Inst;
400 UnimplementedError(Func->getContext()->getFlags()); 641 UnimplementedError(Func->getContext()->getFlags());
401 } 642 }
402 643
403 void TargetMIPS32::lowerCall(const InstCall *Inst) { 644 void TargetMIPS32::lowerCall(const InstCall *Inst) {
404 (void)Inst; 645 (void)Inst;
405 UnimplementedError(Func->getContext()->getFlags()); 646 UnimplementedError(Func->getContext()->getFlags());
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 UnimplementedError(Func->getContext()->getFlags()); 853 UnimplementedError(Func->getContext()->getFlags());
613 } 854 }
614 } 855 }
615 856
616 void TargetMIPS32::lowerPhi(const InstPhi * /*Inst*/) { 857 void TargetMIPS32::lowerPhi(const InstPhi * /*Inst*/) {
617 Func->setError("Phi found in regular instruction list"); 858 Func->setError("Phi found in regular instruction list");
618 } 859 }
619 860
620 void TargetMIPS32::lowerRet(const InstRet *Inst) { 861 void TargetMIPS32::lowerRet(const InstRet *Inst) {
621 Variable *Reg = nullptr; 862 Variable *Reg = nullptr;
622 if (Inst->hasRetValue()) 863 if (Inst->hasRetValue()) {
623 UnimplementedError(Func->getContext()->getFlags()); 864 Operand *Src0 = Inst->getRetValue();
865 switch (Src0->getType()) {
866 case IceType_i1:
867 case IceType_i8:
868 case IceType_i16:
869 case IceType_i32: {
870 // Reg = legalizeToReg(Src0, RegMIPS32::Reg_V0);
871 Operand *Src0F = legalize(Src0, Legal_Reg);
872 Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
873 _mov(Reg, Src0F);
874 break;
875 }
876 case IceType_i64: {
877 Src0 = legalizeUndef(Src0);
878 Variable *R0 = legalizeToReg(loOperand(Src0), RegMIPS32::Reg_V0);
879 Variable *R1 = legalizeToReg(hiOperand(Src0), RegMIPS32::Reg_V1);
880 Reg = R0;
881 Context.insert(InstFakeUse::create(Func, R1));
882 break;
883 }
884
885 default:
886 UnimplementedError(Func->getContext()->getFlags());
887 }
888 }
624 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg); 889 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg);
625 } 890 }
626 891
627 void TargetMIPS32::lowerSelect(const InstSelect *Inst) { 892 void TargetMIPS32::lowerSelect(const InstSelect *Inst) {
628 (void)Inst; 893 (void)Inst;
629 UnimplementedError(Func->getContext()->getFlags()); 894 UnimplementedError(Func->getContext()->getFlags());
630 } 895 }
631 896
632 void TargetMIPS32::lowerStore(const InstStore *Inst) { 897 void TargetMIPS32::lowerStore(const InstStore *Inst) {
633 (void)Inst; 898 (void)Inst;
(...skipping 10 matching lines...) Expand all
644 } 909 }
645 910
646 void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) { 911 void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
647 UnimplementedError(Func->getContext()->getFlags()); 912 UnimplementedError(Func->getContext()->getFlags());
648 } 913 }
649 914
650 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve 915 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
651 // integrity of liveness analysis. Undef values are also turned into zeroes, 916 // integrity of liveness analysis. Undef values are also turned into zeroes,
652 // since loOperand() and hiOperand() don't expect Undef input. 917 // since loOperand() and hiOperand() don't expect Undef input.
653 void TargetMIPS32::prelowerPhis() { 918 void TargetMIPS32::prelowerPhis() {
654 UnimplementedError(Func->getContext()->getFlags()); 919 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func);
655 } 920 }
656 921
657 void TargetMIPS32::postLower() { 922 void TargetMIPS32::postLower() {
658 if (Ctx->getFlags().getOptLevel() == Opt_m1) 923 if (Ctx->getFlags().getOptLevel() == Opt_m1)
659 return; 924 return;
660 // Find two-address non-SSA instructions where Dest==Src0, and set the 925 // Find two-address non-SSA instructions where Dest==Src0, and set the
661 // IsDestRedefined flag to keep liveness analysis consistent. 926 // IsDestRedefined flag to keep liveness analysis consistent.
662 UnimplementedError(Func->getContext()->getFlags()); 927 UnimplementedError(Func->getContext()->getFlags());
663 } 928 }
664 929
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 return; 974 return;
710 UnimplementedError(Ctx->getFlags()); 975 UnimplementedError(Ctx->getFlags());
711 } 976 }
712 977
713 void TargetDataMIPS32::lowerJumpTables() { 978 void TargetDataMIPS32::lowerJumpTables() {
714 if (Ctx->getFlags().getDisableTranslation()) 979 if (Ctx->getFlags().getDisableTranslation())
715 return; 980 return;
716 UnimplementedError(Ctx->getFlags()); 981 UnimplementedError(Ctx->getFlags());
717 } 982 }
718 983
984 // Helper for legalize() to emit the right code to lower an operand to a
985 // register of the appropriate type.
986 Variable *TargetMIPS32::copyToReg(Operand *Src, int32_t RegNum) {
987 Type Ty = Src->getType();
988 Variable *Reg = makeReg(Ty, RegNum);
989 if (isVectorType(Ty) || isFloatingType(Ty)) {
990 UnimplementedError(Ctx->getFlags());
991 } else {
992 // Mov's Src operand can really only be the flexible second operand type
993 // or a register. Users should guarantee that.
994 _mov(Reg, Src);
995 }
996 return Reg;
997 }
998
999 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
1000 int32_t RegNum) {
1001 Type Ty = From->getType();
1002 // Assert that a physical register is allowed. To date, all calls
1003 // to legalize() allow a physical register. Legal_Flex converts
1004 // registers to the right type OperandMIPS32FlexReg as needed.
1005 assert(Allowed & Legal_Reg);
1006 // Go through the various types of operands:
1007 // OperandMIPS32Mem, OperandMIPS32Flex, Constant, and Variable.
1008 // Given the above assertion, if type of operand is not legal
1009 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
1010 // to a register.
1011 if (auto C = llvm::dyn_cast<ConstantRelocatable>(From)) {
1012 (void)C;
1013 return From;
1014 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
1015 uint32_t Value = static_cast<uint32_t>(C32->getValue());
1016 // Check if the immediate will fit in a Flexible second operand,
1017 // if a Flexible second operand is allowed. We need to know the exact
1018 // value, so that rules out relocatable constants.
1019 // Also try the inverse and use MVN if possible.
1020 // Do a movw/movt to a register.
1021 Variable *Reg;
1022 if (RegNum == Variable::NoRegister)
1023 Reg = makeReg(Ty, RegNum);
1024 else
1025 Reg = getPhysicalRegister(RegNum);
1026 if (isInt<16>(int32_t(Value))) {
1027 _addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value);
1028 } else {
1029 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
1030 (void)UpperBits;
1031 uint32_t LowerBits = Value & 0xFFFF;
1032 Variable *TReg = makeReg(Ty, RegNum);
1033 _lui(TReg, UpperBits);
1034 _ori(Reg, TReg, LowerBits);
1035 }
1036 return Reg;
1037 }
1038 if (auto Var = llvm::dyn_cast<Variable>(From)) {
1039 // Check if the variable is guaranteed a physical register. This
1040 // can happen either when the variable is pre-colored or when it is
1041 // assigned infinite weight.
1042 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
1043 // We need a new physical register for the operand if:
1044 // Mem is not allowed and Var isn't guaranteed a physical
1045 // register, or
1046 // RegNum is required and Var->getRegNum() doesn't match.
1047 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
1048 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
1049 From = copyToReg(From, RegNum);
1050 }
1051 return From;
1052 }
1053 return From;
1054 }
1055
1056 /// Provide a trivial wrapper to legalize() for this common usage.
1057 // Variable *TargetMIPS32::legalizeToVar(Operand *From, int32_t RegNum) {
1058 // return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
1059 //}
1060
719 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) 1061 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
720 : TargetHeaderLowering(Ctx) {} 1062 : TargetHeaderLowering(Ctx) {}
721 1063
1064 void TargetHeaderMIPS32::lower() {
1065 OstreamLocker L(Ctx);
1066 Ostream &Str = Ctx->getStrEmit();
1067 Str << "\t.set\tnomicromips\n";
1068 Str << "\t.set\tnomips16\n";
1069 }
1070
722 } // end of namespace Ice 1071 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698