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

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

Powered by Google App Engine
This is Rietveld 408576698