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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2123723002: SubZero: legalize for f32/f64 constants in MIPS32 (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fix: seperate parts for constants from other types Created 4 years, 5 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/IceInstMIPS32.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 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1014 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1015 return Ctx->getConstantInt32( 1015 return Ctx->getConstantInt32(
1016 static_cast<uint32_t>(Const->getValue() >> 32)); 1016 static_cast<uint32_t>(Const->getValue() >> 32));
1017 } 1017 }
1018 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { 1018 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
1019 // Conservatively disallow memory operands with side-effects 1019 // Conservatively disallow memory operands with side-effects
1020 // in case of duplication. 1020 // in case of duplication.
1021 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset); 1021 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
1022 const Type SplitType = IceType_i32; 1022 const Type SplitType = IceType_i32;
1023 Variable *Base = Mem->getBase(); 1023 Variable *Base = Mem->getBase();
1024 ConstantInteger32 *Offset = Mem->getOffset(); 1024 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
Jim Stichnoth 2016/07/05 14:29:27 auto *Offset = ...
1025 assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4)); 1025 assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4));
1026 int32_t NextOffsetVal = Offset->getValue() + 4; 1026 int32_t NextOffsetVal = Offset->getValue() + 4;
1027 constexpr bool SignExt = false; 1027 constexpr bool SignExt = false;
1028 if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) { 1028 if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) {
1029 // We have to make a temp variable and add 4 to either Base or Offset. 1029 // We have to make a temp variable and add 4 to either Base or Offset.
1030 // If we add 4 to Offset, this will convert a non-RegReg addressing 1030 // If we add 4 to Offset, this will convert a non-RegReg addressing
1031 // mode into a RegReg addressing mode. Since NaCl sandboxing disallows 1031 // mode into a RegReg addressing mode. Since NaCl sandboxing disallows
1032 // RegReg addressing modes, prefer adding to base and replacing instead. 1032 // RegReg addressing modes, prefer adding to base and replacing instead.
1033 // Thus we leave the old offset alone. 1033 // Thus we leave the old offset alone.
1034 Constant *Four = Ctx->getConstantInt32(4); 1034 Constant *Four = Ctx->getConstantInt32(4);
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 Type Ty = From->getType(); 2207 Type Ty = From->getType();
2208 // Assert that a physical register is allowed. To date, all calls 2208 // Assert that a physical register is allowed. To date, all calls
2209 // to legalize() allow a physical register. Legal_Flex converts 2209 // to legalize() allow a physical register. Legal_Flex converts
2210 // registers to the right type OperandMIPS32FlexReg as needed. 2210 // registers to the right type OperandMIPS32FlexReg as needed.
2211 assert(Allowed & Legal_Reg); 2211 assert(Allowed & Legal_Reg);
2212 // Go through the various types of operands: 2212 // Go through the various types of operands:
2213 // OperandMIPS32Mem, Constant, and Variable. 2213 // OperandMIPS32Mem, Constant, and Variable.
2214 // Given the above assertion, if type of operand is not legal 2214 // Given the above assertion, if type of operand is not legal
2215 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy 2215 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
2216 // to a register. 2216 // to a register.
2217 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { 2217 if (llvm::isa<Constant>(From)) {
2218 (void)C; 2218 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
2219 // TODO(reed kotler): complete this case for proper implementation 2219 (void)C;
2220 Variable *Reg = makeReg(Ty, RegNum); 2220 // TODO(reed kotler): complete this case for proper implementation
2221 Context.insert<InstFakeDef>(Reg); 2221 Variable *Reg = makeReg(Ty, RegNum);
2222 return Reg; 2222 Context.insert<InstFakeDef>(Reg);
2223 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { 2223 return Reg;
2224 const uint32_t Value = C32->getValue(); 2224 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
2225 // Check if the immediate will fit in a Flexible second operand, 2225 const uint32_t Value = C32->getValue();
2226 // if a Flexible second operand is allowed. We need to know the exact 2226 // Check if the immediate will fit in a Flexible second operand,
2227 // value, so that rules out relocatable constants. 2227 // if a Flexible second operand is allowed. We need to know the exact
2228 // Also try the inverse and use MVN if possible. 2228 // value, so that rules out relocatable constants.
2229 // Do a movw/movt to a register. 2229 // Also try the inverse and use MVN if possible.
2230 Variable *Reg; 2230 // Do a movw/movt to a register.
2231 if (RegNum.hasValue()) 2231 Variable *Reg;
2232 Reg = getPhysicalRegister(RegNum); 2232 if (RegNum.hasValue())
2233 else 2233 Reg = getPhysicalRegister(RegNum);
2234 Reg = makeReg(Ty, RegNum); 2234 else
2235 if (isInt<16>(int32_t(Value))) { 2235 Reg = makeReg(Ty, RegNum);
2236 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); 2236 if (isInt<16>(int32_t(Value))) {
2237 Context.insert<InstFakeDef>(Zero); 2237 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty);
2238 _addiu(Reg, Zero, Value); 2238 Context.insert<InstFakeDef>(Zero);
2239 } else { 2239 _addiu(Reg, Zero, Value);
2240 uint32_t UpperBits = (Value >> 16) & 0xFFFF; 2240 } else {
2241 (void)UpperBits; 2241 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
2242 uint32_t LowerBits = Value & 0xFFFF; 2242 (void)UpperBits;
2243 Variable *TReg = makeReg(Ty, RegNum); 2243 uint32_t LowerBits = Value & 0xFFFF;
2244 _lui(TReg, UpperBits); 2244 Variable *TReg = makeReg(Ty, RegNum);
2245 _ori(Reg, TReg, LowerBits); 2245 _lui(TReg, Ctx->getConstantInt32(UpperBits));
2246 _ori(Reg, TReg, LowerBits);
2247 }
2248 return Reg;
2249 } else if (isScalarFloatingType(Ty)) {
2250 // Load floats/doubles from literal pool.
2251 auto *CFrom = llvm::cast<Constant>(From);
2252 assert(CFrom->getShouldBePooled());
2253 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName());
2254 Variable *TReg1 = makeReg(getPointerType());
2255 Variable *TReg2 = makeReg(Ty);
2256 Context.insert<InstFakeDef>(TReg2);
2257 _lui(TReg1, Offset, hi);
2258 OperandMIPS32Mem *Addr =
2259 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset);
2260 if (Ty == IceType_f32)
2261 _lwc1(TReg2, Addr, lo);
2262 else
2263 _ldc1(TReg2, Addr, lo);
2264 return copyToReg(TReg2, RegNum);
2246 } 2265 }
2247 return Reg;
2248 } 2266 }
2267
2249 if (auto *Var = llvm::dyn_cast<Variable>(From)) { 2268 if (auto *Var = llvm::dyn_cast<Variable>(From)) {
2250 // Check if the variable is guaranteed a physical register. This 2269 // Check if the variable is guaranteed a physical register. This
2251 // can happen either when the variable is pre-colored or when it is 2270 // can happen either when the variable is pre-colored or when it is
2252 // assigned infinite weight. 2271 // assigned infinite weight.
2253 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); 2272 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
2254 // We need a new physical register for the operand if: 2273 // We need a new physical register for the operand if:
2255 // Mem is not allowed and Var isn't guaranteed a physical 2274 // Mem is not allowed and Var isn't guaranteed a physical
2256 // register, or 2275 // register, or
2257 // RegNum is required and Var->getRegNum() doesn't match. 2276 // RegNum is required and Var->getRegNum() doesn't match.
2258 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 2277 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 Str << "\t.set\t" 2360 Str << "\t.set\t"
2342 << "nomips16\n"; 2361 << "nomips16\n";
2343 } 2362 }
2344 2363
2345 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 2364 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
2346 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 2365 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
2347 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 2366 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
2348 2367
2349 } // end of namespace MIPS32 2368 } // end of namespace MIPS32
2350 } // end of namespace Ice 2369 } // end of namespace Ice
OLDNEW
« src/IceInstMIPS32.h ('K') | « src/IceTargetLoweringMIPS32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698