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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 1993993004: Subzero, MIPS32: Introduction of floating point registers (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Register allocation works, some code is removed Created 4 years, 7 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
« src/IceRegistersMIPS32.h ('K') | « src/IceTargetLoweringMIPS32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // 1 //
2 // The Subzero Code Generator 2 // The Subzero Code Generator
3 // 3 //
4 // This file is distributed under the University of Illinois Open Source 4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details. 5 // License. See LICENSE.TXT for details.
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 /// 8 ///
9 /// \file 9 /// \file
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 UnimplementedError(getFlags()); 388 UnimplementedError(getFlags());
389 } 389 }
390 390
391 void TargetMIPS32::lowerArguments() { 391 void TargetMIPS32::lowerArguments() {
392 VarList &Args = Func->getArgs(); 392 VarList &Args = Func->getArgs();
393 // We are only handling integer registers for now. The Mips o32 ABI is 393 // We are only handling integer registers for now. The Mips o32 ABI is
394 // somewhat complex but will be implemented in its totality through follow 394 // somewhat complex but will be implemented in its totality through follow
395 // on patches. 395 // on patches.
396 // 396 //
397 unsigned NumGPRRegsUsed = 0; 397 unsigned NumGPRRegsUsed = 0;
398
398 // For each register argument, replace Arg in the argument list with the 399 // For each register argument, replace Arg in the argument list with the
399 // home register. Then generate an instruction in the prolog to copy the 400 // home register. Then generate an instruction in the prolog to copy the
400 // home register to the assigned location of Arg. 401 // home register to the assigned location of Arg.
401 Context.init(Func->getEntryNode()); 402 Context.init(Func->getEntryNode());
402 Context.setInsertPoint(Context.getCur()); 403 Context.setInsertPoint(Context.getCur());
403 for (SizeT I = 0, E = Args.size(); I < E; ++I) { 404 for (SizeT I = 0, E = Args.size(); I < E; ++I) {
404 Variable *Arg = Args[I]; 405 Variable *Arg = Args[I];
405 Type Ty = Arg->getType(); 406 Type Ty = Arg->getType();
406 // TODO(rkotler): handle float/vector types. 407 // TODO(rkotler): handle float/vector types.
407 if (isVectorType(Ty)) { 408 if (isVectorType(Ty)) {
408 UnimplementedError(getFlags()); 409 UnimplementedError(getFlags());
409 continue; 410 continue;
410 } 411 }
412
411 if (isFloatingType(Ty)) { 413 if (isFloatingType(Ty)) {
414 assert(Ty = IceType_f32);
Jim Stichnoth 2016/05/19 23:12:25 Is this really necessary, given the UnimplementedE
obucinac 2016/05/27 11:13:18 Done.
412 UnimplementedError(getFlags()); 415 UnimplementedError(getFlags());
413 continue; 416 continue;
414 } 417 }
418
415 if (Ty == IceType_i64) { 419 if (Ty == IceType_i64) {
416 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) 420 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG)
417 continue; 421 continue;
418 auto RegLo = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); 422 auto RegLo = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed);
419 auto RegHi = RegNumT::fixme(RegLo + 1); 423 auto RegHi = RegNumT::fixme(RegLo + 1);
420 ++NumGPRRegsUsed; 424 ++NumGPRRegsUsed;
421 // Always start i64 registers at an even register, so this may end 425 // Always start i64 registers at an even register, so this may end
422 // up padding away a register. 426 // up padding away a register.
423 if (RegLo % 2 != 0) { 427 if (RegLo % 2 != 0) {
424 RegLo = RegNumT::fixme(RegLo + 1); 428 RegLo = RegNumT::fixme(RegLo + 1);
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 1273
1270 void TargetMIPS32::lowerPhi(const InstPhi * /*Instr*/) { 1274 void TargetMIPS32::lowerPhi(const InstPhi * /*Instr*/) {
1271 Func->setError("Phi found in regular instruction list"); 1275 Func->setError("Phi found in regular instruction list");
1272 } 1276 }
1273 1277
1274 void TargetMIPS32::lowerRet(const InstRet *Instr) { 1278 void TargetMIPS32::lowerRet(const InstRet *Instr) {
1275 Variable *Reg = nullptr; 1279 Variable *Reg = nullptr;
1276 if (Instr->hasRetValue()) { 1280 if (Instr->hasRetValue()) {
1277 Operand *Src0 = Instr->getRetValue(); 1281 Operand *Src0 = Instr->getRetValue();
1278 switch (Src0->getType()) { 1282 switch (Src0->getType()) {
1283 case IceType_f32: {
1284 Operand *Src0F = legalize(Src0, Legal_Reg);
1285 Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
Jim Stichnoth 2016/05/19 23:12:25 Should this be Reg_F0 instead?
obucinac 2016/05/27 11:13:18 We need to rework this to o32 convention. Leaving
1286 _mov(Reg, Src0F);
1287 break;
1288 }
1279 case IceType_i1: 1289 case IceType_i1:
1280 case IceType_i8: 1290 case IceType_i8:
1281 case IceType_i16: 1291 case IceType_i16:
1282 case IceType_i32: { 1292 case IceType_i32: {
1283 // Reg = legalizeToReg(Src0, RegMIPS32::Reg_V0); 1293 // Reg = legalizeToReg(Src0, RegMIPS32::Reg_V0);
1284 Operand *Src0F = legalize(Src0, Legal_Reg); 1294 Operand *Src0F = legalize(Src0, Legal_Reg);
1285 Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0); 1295 Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
1286 _mov(Reg, Src0F); 1296 _mov(Reg, Src0F);
1287 break; 1297 break;
1288 } 1298 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 if (getFlags().getDisableTranslation()) 1406 if (getFlags().getDisableTranslation())
1397 return; 1407 return;
1398 UnimplementedError(getFlags()); 1408 UnimplementedError(getFlags());
1399 } 1409 }
1400 1410
1401 // Helper for legalize() to emit the right code to lower an operand to a 1411 // Helper for legalize() to emit the right code to lower an operand to a
1402 // register of the appropriate type. 1412 // register of the appropriate type.
1403 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { 1413 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
1404 Type Ty = Src->getType(); 1414 Type Ty = Src->getType();
1405 Variable *Reg = makeReg(Ty, RegNum); 1415 Variable *Reg = makeReg(Ty, RegNum);
1406 if (isVectorType(Ty) || isFloatingType(Ty)) { 1416 if (isVectorType(Ty)) {
1417 UnimplementedError(getFlags());
1418 } else if (isFloatingType(Ty)) {
1407 UnimplementedError(getFlags()); 1419 UnimplementedError(getFlags());
1408 } else { 1420 } else {
1409 // Mov's Src operand can really only be the flexible second operand type 1421 // Mov's Src operand can really only be the flexible second operand type
1410 // or a register. Users should guarantee that. 1422 // or a register. Users should guarantee that.
1411 _mov(Reg, Src); 1423 _mov(Reg, Src);
1412 } 1424 }
1413 return Reg; 1425 return Reg;
1414 } 1426 }
1415 1427
1416 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, 1428 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
1417 RegNumT RegNum) { 1429 RegNumT RegNum) {
1418 Type Ty = From->getType(); 1430 Type Ty = From->getType();
1419 // Assert that a physical register is allowed. To date, all calls 1431 // Assert that a physical register is allowed. To date, all calls
1420 // to legalize() allow a physical register. Legal_Flex converts 1432 // to legalize() allow a physical register. Legal_Flex converts
1421 // registers to the right type OperandMIPS32FlexReg as needed. 1433 // registers to the right type OperandMIPS32FlexReg as needed.
1422 assert(Allowed & Legal_Reg); 1434 assert(Allowed & Legal_Reg);
1423 // Go through the various types of operands: 1435 // Go through the various types of operands:
1424 // OperandMIPS32Mem, Constant, and Variable. 1436 // OperandMIPS32Mem, Constant, and Variable.
1425 // Given the above assertion, if type of operand is not legal 1437 // Given the above assertion, if type of operand is not legal
1426 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy 1438 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
1427 // to a register. 1439 // to a register.
1428 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { 1440 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
1429 (void)C; 1441 (void)C;
1430 // TODO(reed kotler): complete this case for proper implementation 1442 // TODO(reed kotler): complete this case for proper implementation
1431 Variable *Reg = makeReg(Ty, RegNum); 1443 Variable *Reg = makeReg(Ty, RegNum);
1432 Context.insert<InstFakeDef>(Reg); 1444 Context.insert<InstFakeDef>(Reg);
1433 return Reg; 1445 return Reg;
1446 } else if (auto *C32 = llvm::dyn_cast<ConstantFloat>(From)) {
1447 const float Value = C32->getValue();
1448 // Check if the immediate will fit in a Flexible second operand,
1449 // if a Flexible second operand is allowed. We need to know the exact
1450 // value, so that rules out relocatable constants.
1451 // Also try the inverse and use MVN if possible.
1452 // Do a movw/movt to a register.
1453 Variable *Reg;
1454 if (RegNum.hasValue())
1455 Reg = getPhysicalRegister(RegNum);
Jim Stichnoth 2016/05/19 23:12:25 I'm very nervous about this use of getPhysicalRegi
obucinac 2016/05/27 11:13:18 We need to rework this to o32 convention. Leaving
1456 else
1457 Reg = makeReg(Ty, RegNum);
1458
1459 const uint32_t UIntValue = llvm::FloatToBits(Value);
1460
1461 if (isInt<16>(int32_t(UIntValue))) {
1462 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty);
1463 Context.insert<InstFakeDef>(Zero);
1464 _addiu(Reg, Zero, UIntValue);
1465 } else {
1466 uint32_t UpperBits = (UIntValue >> 16) & 0xFFFF;
1467 (void)UpperBits;
Jim Stichnoth 2016/05/19 23:12:25 Remove this
obucinac 2016/05/27 11:13:18 Done.
1468 uint32_t LowerBits = UIntValue & 0xFFFF;
1469 Variable *TReg = makeReg(Ty, RegNum);
1470 _lui(TReg, UpperBits);
1471 _ori(Reg, TReg, LowerBits);
1472 }
1473 return Reg;
1434 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { 1474 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
1435 const uint32_t Value = C32->getValue(); 1475 const uint32_t Value = C32->getValue();
1436 // Check if the immediate will fit in a Flexible second operand, 1476 // Check if the immediate will fit in a Flexible second operand,
1437 // if a Flexible second operand is allowed. We need to know the exact 1477 // if a Flexible second operand is allowed. We need to know the exact
1438 // value, so that rules out relocatable constants. 1478 // value, so that rules out relocatable constants.
1439 // Also try the inverse and use MVN if possible. 1479 // Also try the inverse and use MVN if possible.
1440 // Do a movw/movt to a register. 1480 // Do a movw/movt to a register.
1441 Variable *Reg; 1481 Variable *Reg;
1442 if (RegNum.hasValue()) 1482 if (RegNum.hasValue())
1443 Reg = getPhysicalRegister(RegNum); 1483 Reg = getPhysicalRegister(RegNum);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 Str << "\t.set\t" 1526 Str << "\t.set\t"
1487 << "nomips16\n"; 1527 << "nomips16\n";
1488 } 1528 }
1489 1529
1490 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1530 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1491 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1531 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1492 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1532 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1493 1533
1494 } // end of namespace MIPS32 1534 } // end of namespace MIPS32
1495 } // end of namespace Ice 1535 } // end of namespace Ice
OLDNEW
« src/IceRegistersMIPS32.h ('K') | « src/IceTargetLoweringMIPS32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698