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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1499983002: Subzero. ARM32. Implements sandboxing. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: 80-col Created 5 years 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/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 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
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 if (Flags.getTargetInstructionSet() != 154 if (Flags.getTargetInstructionSet() !=
155 TargetInstructionSet::BaseInstructionSet) { 155 TargetInstructionSet::BaseInstructionSet) {
156 InstructionSet = static_cast<ARM32InstructionSet>( 156 InstructionSet = static_cast<ARM32InstructionSet>(
157 (Flags.getTargetInstructionSet() - 157 (Flags.getTargetInstructionSet() -
158 TargetInstructionSet::ARM32InstructionSet_Begin) + 158 TargetInstructionSet::ARM32InstructionSet_Begin) +
159 ARM32InstructionSet::Begin); 159 ARM32InstructionSet::Begin);
160 } 160 }
161 } 161 }
162 162
163 TargetARM32::TargetARM32(Cfg *Func) 163 TargetARM32::TargetARM32(Cfg *Func)
164 : TargetLowering(Func), CPUFeatures(Func->getContext()->getFlags()) {} 164 : TargetLowering(Func), NeedSandboxing(Ctx->getFlags().getUseSandboxing()),
165 CPUFeatures(Func->getContext()->getFlags()) {}
165 166
166 void TargetARM32::staticInit() { 167 void TargetARM32::staticInit() {
167 // Limit this size (or do all bitsets need to be the same width)??? 168 // Limit this size (or do all bitsets need to be the same width)???
168 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); 169 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM);
169 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); 170 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM);
170 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); 171 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM);
171 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); 172 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM);
172 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); 173 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM);
173 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); 174 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM);
174 ScratchRegs.resize(RegARM32::Reg_NUM); 175 ScratchRegs.resize(RegARM32::Reg_NUM);
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper, 538 auto *Call = InstCall::create(Func, MaxArgs, NoDest, TargetHelper,
538 NoTailCall, IsTargetHelperCall); 539 NoTailCall, IsTargetHelperCall);
539 Call->addArg(IntrinsicCall->getArg(0)); 540 Call->addArg(IntrinsicCall->getArg(0));
540 Call->addArg(ValExt); 541 Call->addArg(ValExt);
541 Call->addArg(IntrinsicCall->getArg(2)); 542 Call->addArg(IntrinsicCall->getArg(2));
542 Context.insert(Call); 543 Context.insert(Call);
543 Instr->setDeleted(); 544 Instr->setDeleted();
544 return; 545 return;
545 } 546 }
546 case Intrinsics::NaClReadTP: { 547 case Intrinsics::NaClReadTP: {
547 if (Ctx->getFlags().getUseSandboxing()) { 548 if (NeedSandboxing) {
548 UnimplementedError(Func->getContext()->getFlags());
549 return; 549 return;
550 } 550 }
551 static constexpr SizeT MaxArgs = 0; 551 static constexpr SizeT MaxArgs = 0;
552 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp); 552 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp);
553 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, 553 auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper,
554 NoTailCall, IsTargetHelperCall); 554 NoTailCall, IsTargetHelperCall);
555 Context.insert(Call); 555 Context.insert(Call);
556 Instr->setDeleted(); 556 Instr->setDeleted();
557 return; 557 return;
558 } 558 }
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 CalleeSaves[RegARM32::Reg_lr] = true; 1113 CalleeSaves[RegARM32::Reg_lr] = true;
1114 RegsUsed[RegARM32::Reg_lr] = true; 1114 RegsUsed[RegARM32::Reg_lr] = true;
1115 } 1115 }
1116 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 1116 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
1117 if (RegARM32::isI64RegisterPair(i)) { 1117 if (RegARM32::isI64RegisterPair(i)) {
1118 // We don't save register pairs explicitly. Instead, we rely on the code 1118 // We don't save register pairs explicitly. Instead, we rely on the code
1119 // fake-defing/fake-using each register in the pair. 1119 // fake-defing/fake-using each register in the pair.
1120 continue; 1120 continue;
1121 } 1121 }
1122 if (CalleeSaves[i] && RegsUsed[i]) { 1122 if (CalleeSaves[i] && RegsUsed[i]) {
1123 if (NeedSandboxing && i == RegARM32::Reg_r9) {
1124 // r9 is never updated in sandboxed code.
1125 continue;
1126 }
1123 ++NumCallee; 1127 ++NumCallee;
1124 Variable *PhysicalRegister = getPhysicalRegister(i); 1128 Variable *PhysicalRegister = getPhysicalRegister(i);
1125 PreservedRegsSizeBytes += 1129 PreservedRegsSizeBytes +=
1126 typeWidthInBytesOnStack(PhysicalRegister->getType()); 1130 typeWidthInBytesOnStack(PhysicalRegister->getType());
1127 GPRsToPreserve.push_back(getPhysicalRegister(i)); 1131 GPRsToPreserve.push_back(getPhysicalRegister(i));
1128 } 1132 }
1129 } 1133 }
1130 Ctx->statsUpdateRegistersSaved(NumCallee); 1134 Ctx->statsUpdateRegistersSaved(NumCallee);
1131 if (!GPRsToPreserve.empty()) 1135 if (!GPRsToPreserve.empty())
1132 _push(GPRsToPreserve); 1136 _push(GPRsToPreserve);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 } 1170 }
1167 1171
1168 // Combine fixed alloca with SpillAreaSize. 1172 // Combine fixed alloca with SpillAreaSize.
1169 SpillAreaSizeBytes += FixedAllocaSizeBytes; 1173 SpillAreaSizeBytes += FixedAllocaSizeBytes;
1170 1174
1171 // Generate "sub sp, SpillAreaSizeBytes" 1175 // Generate "sub sp, SpillAreaSizeBytes"
1172 if (SpillAreaSizeBytes) { 1176 if (SpillAreaSizeBytes) {
1173 // Use the scratch register if needed to legalize the immediate. 1177 // Use the scratch register if needed to legalize the immediate.
1174 Operand *SubAmount = legalize(Ctx->getConstantInt32(SpillAreaSizeBytes), 1178 Operand *SubAmount = legalize(Ctx->getConstantInt32(SpillAreaSizeBytes),
1175 Legal_Reg | Legal_Flex, getReservedTmpReg()); 1179 Legal_Reg | Legal_Flex, getReservedTmpReg());
1176 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 1180 AutoSandboxer(this).sub_sp(SubAmount);
1177 _sub(SP, SP, SubAmount);
1178 if (FixedAllocaAlignBytes > ARM32_STACK_ALIGNMENT_BYTES) { 1181 if (FixedAllocaAlignBytes > ARM32_STACK_ALIGNMENT_BYTES) {
1179 alignRegisterPow2(SP, FixedAllocaAlignBytes); 1182 AutoSandboxer(this).align_sp(FixedAllocaAlignBytes);
1180 } 1183 }
1181 } 1184 }
1182 1185
1183 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes); 1186 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes);
1184 1187
1185 // Fill in stack offsets for stack args, and copy args into registers for 1188 // Fill in stack offsets for stack args, and copy args into registers for
1186 // those that were register-allocated. Args are pushed right to left, so 1189 // those that were register-allocated. Args are pushed right to left, so
1187 // Arg[0] is closest to the stack/frame pointer. 1190 // Arg[0] is closest to the stack/frame pointer.
1188 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); 1191 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg());
1189 size_t BasicFrameOffset = PreservedRegsSizeBytes; 1192 size_t BasicFrameOffset = PreservedRegsSizeBytes;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 Context.init(Node); 1266 Context.init(Node);
1264 Context.setInsertPoint(InsertPoint); 1267 Context.setInsertPoint(InsertPoint);
1265 1268
1266 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 1269 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
1267 if (UsesFramePointer) { 1270 if (UsesFramePointer) {
1268 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp); 1271 Variable *FP = getPhysicalRegister(RegARM32::Reg_fp);
1269 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake 1272 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
1270 // use of SP before the assignment of SP=FP keeps previous SP adjustments 1273 // use of SP before the assignment of SP=FP keeps previous SP adjustments
1271 // from being dead-code eliminated. 1274 // from being dead-code eliminated.
1272 Context.insert(InstFakeUse::create(Func, SP)); 1275 Context.insert(InstFakeUse::create(Func, SP));
1273 _mov(SP, FP); 1276 AutoSandboxer(this).reset_sp(FP);
1274 } else { 1277 } else {
1275 // add SP, SpillAreaSizeBytes 1278 // add SP, SpillAreaSizeBytes
1276 if (SpillAreaSizeBytes) { 1279 if (SpillAreaSizeBytes) {
1277 // Use the scratch register if needed to legalize the immediate. 1280 // Use the scratch register if needed to legalize the immediate.
1278 Operand *AddAmount = 1281 Operand *AddAmount =
1279 legalize(Ctx->getConstantInt32(SpillAreaSizeBytes), 1282 legalize(Ctx->getConstantInt32(SpillAreaSizeBytes),
1280 Legal_Reg | Legal_Flex, getReservedTmpReg()); 1283 Legal_Reg | Legal_Flex, getReservedTmpReg());
1281 _add(SP, SP, AddAmount); 1284 AutoSandboxer(this).add_sp(AddAmount);
1282 } 1285 }
1283 } 1286 }
1284 1287
1285 // Add pop instructions for preserved registers. 1288 // Add pop instructions for preserved registers.
1286 llvm::SmallBitVector CalleeSaves = 1289 llvm::SmallBitVector CalleeSaves =
1287 getRegisterSet(RegSet_CalleeSave, RegSet_None); 1290 getRegisterSet(RegSet_CalleeSave, RegSet_None);
1288 VarList GPRsToRestore; 1291 VarList GPRsToRestore;
1289 GPRsToRestore.reserve(CalleeSaves.size()); 1292 GPRsToRestore.reserve(CalleeSaves.size());
1290 // Consider FP and LR as callee-save / used as needed. 1293 // Consider FP and LR as callee-save / used as needed.
1291 if (UsesFramePointer) { 1294 if (UsesFramePointer) {
1292 CalleeSaves[RegARM32::Reg_fp] = true; 1295 CalleeSaves[RegARM32::Reg_fp] = true;
1293 } 1296 }
1294 if (!MaybeLeafFunc) { 1297 if (!MaybeLeafFunc) {
1295 CalleeSaves[RegARM32::Reg_lr] = true; 1298 CalleeSaves[RegARM32::Reg_lr] = true;
1296 } 1299 }
1297 // Pop registers in ascending order just like push (instead of in reverse 1300 // Pop registers in ascending order just like push (instead of in reverse
1298 // order). 1301 // order).
1299 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 1302 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
1300 if (RegARM32::isI64RegisterPair(i)) { 1303 if (RegARM32::isI64RegisterPair(i)) {
1301 continue; 1304 continue;
1302 } 1305 }
1303 1306
1304 if (CalleeSaves[i] && RegsUsed[i]) { 1307 if (CalleeSaves[i] && RegsUsed[i]) {
1308 if (NeedSandboxing && i == RegARM32::Reg_r9) {
1309 continue;
1310 }
1305 GPRsToRestore.push_back(getPhysicalRegister(i)); 1311 GPRsToRestore.push_back(getPhysicalRegister(i));
1306 } 1312 }
1307 } 1313 }
1308 if (!GPRsToRestore.empty()) 1314 if (!GPRsToRestore.empty())
1309 _pop(GPRsToRestore); 1315 _pop(GPRsToRestore);
1310 1316
1311 if (!Ctx->getFlags().getUseSandboxing()) 1317 if (!Ctx->getFlags().getUseSandboxing())
1312 return; 1318 return;
1313 1319
1314 // Change the original ret instruction into a sandboxed return sequence. 1320 // Change the original ret instruction into a sandboxed return sequence.
1315 // bundle_lock 1321 // bundle_lock
1316 // bic lr, #0xc000000f 1322 // bic lr, #0xc000000f
1317 // bx lr 1323 // bx lr
1318 // bundle_unlock 1324 // bundle_unlock
1319 // This isn't just aligning to the getBundleAlignLog2Bytes(). It needs to 1325 // This isn't just aligning to the getBundleAlignLog2Bytes(). It needs to
1320 // restrict to the lower 1GB as well. 1326 // restrict to the lower 1GB as well.
1321 Operand *RetMask = 1327 Variable *LR = getPhysicalRegister(RegARM32::Reg_lr);
1322 legalize(Ctx->getConstantInt32(0xc000000f), Legal_Reg | Legal_Flex);
1323 Variable *LR = makeReg(IceType_i32, RegARM32::Reg_lr);
1324 Variable *RetValue = nullptr; 1328 Variable *RetValue = nullptr;
1325 if (RI->getSrcSize()) 1329 if (RI->getSrcSize())
1326 RetValue = llvm::cast<Variable>(RI->getSrc(0)); 1330 RetValue = llvm::cast<Variable>(RI->getSrc(0));
1327 _bundle_lock(); 1331
1328 _bic(LR, LR, RetMask); 1332 AutoSandboxer(this).ret(LR, RetValue);
1329 _ret(LR, RetValue); 1333
1330 _bundle_unlock();
1331 RI->setDeleted(); 1334 RI->setDeleted();
1332 } 1335 }
1333 1336
1334 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { 1337 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const {
1335 constexpr bool ZeroExt = false; 1338 constexpr bool ZeroExt = false;
1336 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); 1339 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset);
1337 } 1340 }
1338 1341
1339 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( 1342 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister(
1340 Variable *Base, int32_t Offset, int32_t ScratchRegNum) { 1343 Variable *Base, int32_t Offset, int32_t ScratchRegNum) {
(...skipping 30 matching lines...) Expand all
1371 TempBaseOffset = 0; 1374 TempBaseOffset = 0;
1372 } 1375 }
1373 } 1376 }
1374 1377
1375 return ScratchReg; 1378 return ScratchReg;
1376 } 1379 }
1377 1380
1378 OperandARM32Mem *TargetARM32::PostLoweringLegalizer::createMemOperand( 1381 OperandARM32Mem *TargetARM32::PostLoweringLegalizer::createMemOperand(
1379 Type Ty, Variable *Base, int32_t Offset, bool AllowOffsets) { 1382 Type Ty, Variable *Base, int32_t Offset, bool AllowOffsets) {
1380 assert(!Base->isRematerializable()); 1383 assert(!Base->isRematerializable());
1381 if (AllowOffsets && Target->isLegalMemOffset(Ty, Offset)) { 1384 if (Offset == 0 || (AllowOffsets && Target->isLegalMemOffset(Ty, Offset))) {
1382 return OperandARM32Mem::create( 1385 return OperandARM32Mem::create(
1383 Target->Func, Ty, Base, 1386 Target->Func, Ty, Base,
1384 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)), 1387 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)),
1385 OperandARM32Mem::Offset); 1388 OperandARM32Mem::Offset);
1386 } 1389 }
1387 1390
1388 if (!AllowOffsets || TempBaseReg == nullptr) { 1391 if (!AllowOffsets || TempBaseReg == nullptr) {
1389 newBaseRegister(Base, Offset, Target->getReservedTmpReg()); 1392 newBaseRegister(Base, Offset, Target->getReservedTmpReg());
1390 } 1393 }
1391 1394
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) 1447 if (MovInstr->isMultiDest() || MovInstr->isMultiSource())
1445 return; 1448 return;
1446 1449
1447 bool Legalized = false; 1450 bool Legalized = false;
1448 if (!Dest->hasReg()) { 1451 if (!Dest->hasReg()) {
1449 auto *SrcR = llvm::cast<Variable>(Src); 1452 auto *SrcR = llvm::cast<Variable>(Src);
1450 assert(SrcR->hasReg()); 1453 assert(SrcR->hasReg());
1451 assert(!SrcR->isRematerializable()); 1454 assert(!SrcR->isRematerializable());
1452 const int32_t Offset = Dest->getStackOffset(); 1455 const int32_t Offset = Dest->getStackOffset();
1453 // This is a _mov(Mem(), Variable), i.e., a store. 1456 // This is a _mov(Mem(), Variable), i.e., a store.
1454 Target->_str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset), 1457 TargetARM32::AutoSandboxer(Target)
1455 MovInstr->getPredicate()); 1458 .str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset),
1459 MovInstr->getPredicate());
1456 // _str() does not have a Dest, so we add a fake-def(Dest). 1460 // _str() does not have a Dest, so we add a fake-def(Dest).
1457 Target->Context.insert(InstFakeDef::create(Target->Func, Dest)); 1461 Target->Context.insert(InstFakeDef::create(Target->Func, Dest));
1458 Legalized = true; 1462 Legalized = true;
1459 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1463 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1460 if (Var->isRematerializable()) { 1464 if (Var->isRematerializable()) {
1461 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1465 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1462 1466
1463 // ExtraOffset is only needed for frame-pointer based frames as we have 1467 // ExtraOffset is only needed for frame-pointer based frames as we have
1464 // to account for spill storage. 1468 // to account for spill storage.
1465 const int32_t ExtraOffset = 1469 const int32_t ExtraOffset =
1466 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) 1470 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg())
1467 ? Target->getFrameFixedAllocaOffset() 1471 ? Target->getFrameFixedAllocaOffset()
1468 : 0; 1472 : 0;
1469 1473
1470 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1474 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1471 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1475 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1472 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1476 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1473 Target->_mov(Dest, T); 1477 Target->_mov(Dest, T);
1474 Legalized = true; 1478 Legalized = true;
1475 } else { 1479 } else {
1476 if (!Var->hasReg()) { 1480 if (!Var->hasReg()) {
1477 // This is a _mov(Variable, Mem()), i.e., a load. 1481 // This is a _mov(Variable, Mem()), i.e., a load.
1478 const int32_t Offset = Var->getStackOffset(); 1482 const int32_t Offset = Var->getStackOffset();
1479 Target->_ldr(Dest, createMemOperand(DestTy, StackOrFrameReg, Offset), 1483 TargetARM32::AutoSandboxer(Target)
1480 MovInstr->getPredicate()); 1484 .ldr(Dest, createMemOperand(DestTy, StackOrFrameReg, Offset),
1485 MovInstr->getPredicate());
1481 Legalized = true; 1486 Legalized = true;
1482 } 1487 }
1483 } 1488 }
1484 } 1489 }
1485 1490
1486 if (Legalized) { 1491 if (Legalized) {
1487 if (MovInstr->isDestRedefined()) { 1492 if (MovInstr->isDestRedefined()) {
1488 Target->_set_dest_redefined(); 1493 Target->_set_dest_redefined();
1489 } 1494 }
1490 MovInstr->setDeleted(); 1495 MovInstr->setDeleted();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 const int32_t ExtraOffset = 1540 const int32_t ExtraOffset =
1536 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg()) 1541 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg())
1537 ? Target->getFrameFixedAllocaOffset() 1542 ? Target->getFrameFixedAllocaOffset()
1538 : 0; 1543 : 0;
1539 Offset += Base->getStackOffset() + ExtraOffset; 1544 Offset += Base->getStackOffset() + ExtraOffset;
1540 Base = Target->getPhysicalRegister(Base->getRegNum()); 1545 Base = Target->getPhysicalRegister(Base->getRegNum());
1541 assert(!Base->isRematerializable()); 1546 assert(!Base->isRematerializable());
1542 Legalized = true; 1547 Legalized = true;
1543 } 1548 }
1544 1549
1545 if (!Legalized) { 1550 if (!Legalized && !Target->NeedSandboxing) {
1546 return nullptr; 1551 return nullptr;
1547 } 1552 }
1548 1553
1549 if (!Mem->isRegReg()) { 1554 if (!Mem->isRegReg()) {
1550 return createMemOperand(Mem->getType(), Base, Offset, AllowOffsets); 1555 return createMemOperand(Mem->getType(), Base, Offset, AllowOffsets);
1551 } 1556 }
1552 1557
1558 if (Target->NeedSandboxing) {
1559 llvm::report_fatal_error("Reg-Reg address mode is not allowed.");
1560 }
1561
1553 assert(MemTraits[Mem->getType()].CanHaveIndex); 1562 assert(MemTraits[Mem->getType()].CanHaveIndex);
1554 1563
1555 if (Offset != 0) { 1564 if (Offset != 0) {
1556 if (TempBaseReg == nullptr) { 1565 if (TempBaseReg == nullptr) {
1557 Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg()); 1566 Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg());
1558 } else { 1567 } else {
1559 uint32_t Imm8, Rotate; 1568 uint32_t Imm8, Rotate;
1560 const int32_t OffsetDiff = Offset - TempBaseOffset; 1569 const int32_t OffsetDiff = Offset - TempBaseOffset;
1561 if (OffsetDiff == 0) { 1570 if (OffsetDiff == 0) {
1562 Base = TempBaseReg; 1571 Base = TempBaseReg;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 Inst *CurInstr = Context.getCur(); 1623 Inst *CurInstr = Context.getCur();
1615 1624
1616 // Check if the previous TempBaseReg is clobbered, and reset if needed. 1625 // Check if the previous TempBaseReg is clobbered, and reset if needed.
1617 Legalizer.resetTempBaseIfClobberedBy(CurInstr); 1626 Legalizer.resetTempBaseIfClobberedBy(CurInstr);
1618 1627
1619 if (auto *MovInstr = llvm::dyn_cast<InstARM32Mov>(CurInstr)) { 1628 if (auto *MovInstr = llvm::dyn_cast<InstARM32Mov>(CurInstr)) {
1620 Legalizer.legalizeMov(MovInstr); 1629 Legalizer.legalizeMov(MovInstr);
1621 } else if (auto *LdrInstr = llvm::dyn_cast<InstARM32Ldr>(CurInstr)) { 1630 } else if (auto *LdrInstr = llvm::dyn_cast<InstARM32Ldr>(CurInstr)) {
1622 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand( 1631 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
1623 llvm::cast<OperandARM32Mem>(LdrInstr->getSrc(0)))) { 1632 llvm::cast<OperandARM32Mem>(LdrInstr->getSrc(0)))) {
1624 _ldr(CurInstr->getDest(), LegalMem, LdrInstr->getPredicate()); 1633 AutoSandboxer(this)
1634 .ldr(CurInstr->getDest(), LegalMem, LdrInstr->getPredicate());
1625 CurInstr->setDeleted(); 1635 CurInstr->setDeleted();
1626 } 1636 }
1627 } else if (auto *LdrexInstr = llvm::dyn_cast<InstARM32Ldrex>(CurInstr)) { 1637 } else if (auto *LdrexInstr = llvm::dyn_cast<InstARM32Ldrex>(CurInstr)) {
1628 constexpr bool DisallowOffsetsBecauseLdrex = false; 1638 constexpr bool DisallowOffsetsBecauseLdrex = false;
1629 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand( 1639 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
1630 llvm::cast<OperandARM32Mem>(LdrexInstr->getSrc(0)), 1640 llvm::cast<OperandARM32Mem>(LdrexInstr->getSrc(0)),
1631 DisallowOffsetsBecauseLdrex)) { 1641 DisallowOffsetsBecauseLdrex)) {
1632 _ldrex(CurInstr->getDest(), LegalMem, LdrexInstr->getPredicate()); 1642 AutoSandboxer(this)
1643 .ldrex(CurInstr->getDest(), LegalMem, LdrexInstr->getPredicate());
1633 CurInstr->setDeleted(); 1644 CurInstr->setDeleted();
1634 } 1645 }
1635 } else if (auto *StrInstr = llvm::dyn_cast<InstARM32Str>(CurInstr)) { 1646 } else if (auto *StrInstr = llvm::dyn_cast<InstARM32Str>(CurInstr)) {
1647 AutoSandboxer Bundle(this);
1636 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand( 1648 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
1637 llvm::cast<OperandARM32Mem>(StrInstr->getSrc(1)))) { 1649 llvm::cast<OperandARM32Mem>(StrInstr->getSrc(1)))) {
1638 _str(llvm::cast<Variable>(CurInstr->getSrc(0)), LegalMem, 1650 AutoSandboxer(this).str(llvm::cast<Variable>(CurInstr->getSrc(0)),
1639 StrInstr->getPredicate()); 1651 LegalMem, StrInstr->getPredicate());
1640 CurInstr->setDeleted(); 1652 CurInstr->setDeleted();
1641 } 1653 }
1642 } else if (auto *StrexInstr = llvm::dyn_cast<InstARM32Strex>(CurInstr)) { 1654 } else if (auto *StrexInstr = llvm::dyn_cast<InstARM32Strex>(CurInstr)) {
1643 constexpr bool DisallowOffsetsBecauseStrex = false; 1655 constexpr bool DisallowOffsetsBecauseStrex = false;
1644 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand( 1656 if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
1645 llvm::cast<OperandARM32Mem>(StrexInstr->getSrc(1)), 1657 llvm::cast<OperandARM32Mem>(StrexInstr->getSrc(1)),
1646 DisallowOffsetsBecauseStrex)) { 1658 DisallowOffsetsBecauseStrex)) {
1647 _strex(CurInstr->getDest(), llvm::cast<Variable>(CurInstr->getSrc(0)), 1659 AutoSandboxer(this).strex(CurInstr->getDest(),
1648 LegalMem, StrexInstr->getPredicate()); 1660 llvm::cast<Variable>(CurInstr->getSrc(0)),
1661 LegalMem, StrexInstr->getPredicate());
1649 CurInstr->setDeleted(); 1662 CurInstr->setDeleted();
1650 } 1663 }
1651 } 1664 }
1652 1665
1653 // Sanity-check: the Legalizer will either have no Temp, or it will be 1666 // Sanity-check: the Legalizer will either have no Temp, or it will be
1654 // bound to IP. 1667 // bound to IP.
1655 Legalizer.assertNoTempOrAssignedToIP(); 1668 Legalizer.assertNoTempOrAssignedToIP();
1656 } 1669 }
1657 } 1670 }
1658 } 1671 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; 1809 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1;
1797 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset(); 1810 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset();
1798 const bool UseFramePointer = 1811 const bool UseFramePointer =
1799 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; 1812 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1;
1800 1813
1801 if (UseFramePointer) 1814 if (UseFramePointer)
1802 setHasFramePointer(); 1815 setHasFramePointer();
1803 1816
1804 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 1817 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
1805 if (OverAligned) { 1818 if (OverAligned) {
1806 alignRegisterPow2(SP, Alignment); 1819 AutoSandboxer(this).align_sp(Alignment);
1807 } 1820 }
1808 1821
1809 Variable *Dest = Inst->getDest(); 1822 Variable *Dest = Inst->getDest();
1810 Operand *TotalSize = Inst->getSizeInBytes(); 1823 Operand *TotalSize = Inst->getSizeInBytes();
1811 1824
1812 if (const auto *ConstantTotalSize = 1825 if (const auto *ConstantTotalSize =
1813 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { 1826 llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
1814 const uint32_t Value = 1827 const uint32_t Value =
1815 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); 1828 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment);
1816 // Constant size alloca. 1829 // Constant size alloca.
1817 if (!UseFramePointer) { 1830 if (!UseFramePointer) {
1818 // If we don't need a Frame Pointer, this alloca has a known offset to the 1831 // If we don't need a Frame Pointer, this alloca has a known offset to the
1819 // stack pointer. We don't need adjust the stack pointer, nor assign any 1832 // stack pointer. We don't need adjust the stack pointer, nor assign any
1820 // value to Dest, as Dest is rematerializable. 1833 // value to Dest, as Dest is rematerializable.
1821 assert(Dest->isRematerializable()); 1834 assert(Dest->isRematerializable());
1822 FixedAllocaSizeBytes += Value; 1835 FixedAllocaSizeBytes += Value;
1823 Context.insert(InstFakeDef::create(Func, Dest)); 1836 Context.insert(InstFakeDef::create(Func, Dest));
1824 return; 1837 return;
1825 } 1838 }
1826 1839
1827 // If a frame pointer is required, then we need to store the alloca'd result 1840 // If a frame pointer is required, then we need to store the alloca'd result
1828 // in Dest. 1841 // in Dest.
1829 Operand *SubAmountRF = 1842 Operand *SubAmountRF =
1830 legalize(Ctx->getConstantInt32(Value), Legal_Reg | Legal_Flex); 1843 legalize(Ctx->getConstantInt32(Value), Legal_Reg | Legal_Flex);
1831 _sub(SP, SP, SubAmountRF); 1844 AutoSandboxer(this).sub_sp(SubAmountRF);
1832 } else { 1845 } else {
1833 // Non-constant sizes need to be adjusted to the next highest multiple of 1846 // Non-constant sizes need to be adjusted to the next highest multiple of
1834 // the required alignment at runtime. 1847 // the required alignment at runtime.
1835 TotalSize = legalize(TotalSize, Legal_Reg | Legal_Flex); 1848 TotalSize = legalize(TotalSize, Legal_Reg | Legal_Flex);
1836 Variable *T = makeReg(IceType_i32); 1849 Variable *T = makeReg(IceType_i32);
1837 _mov(T, TotalSize); 1850 _mov(T, TotalSize);
1838 Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1)); 1851 Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1));
1839 _add(T, T, AddAmount); 1852 _add(T, T, AddAmount);
1840 alignRegisterPow2(T, Alignment); 1853 alignRegisterPow2(T, Alignment);
1841 _sub(SP, SP, T); 1854 AutoSandboxer(this).sub_sp(T);
1842 } 1855 }
1843 1856
1844 // Adds back a few bytes to SP to account for the out args area. 1857 // Adds back a few bytes to SP to account for the out args area.
1845 Variable *T = SP; 1858 Variable *T = SP;
1846 if (MaxOutArgsSizeBytes != 0) { 1859 if (MaxOutArgsSizeBytes != 0) {
1847 T = makeReg(getPointerType()); 1860 T = makeReg(getPointerType());
1848 Operand *OutArgsSizeRF = legalize( 1861 Operand *OutArgsSizeRF = legalize(
1849 Ctx->getConstantInt32(MaxOutArgsSizeBytes), Legal_Reg | Legal_Flex); 1862 Ctx->getConstantInt32(MaxOutArgsSizeBytes), Legal_Reg | Legal_Flex);
1850 _add(T, SP, OutArgsSizeRF); 1863 _add(T, SP, OutArgsSizeRF);
1851 } 1864 }
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3242 case IceType_v8i1: 3255 case IceType_v8i1:
3243 case IceType_v16i1: 3256 case IceType_v16i1:
3244 case IceType_v16i8: 3257 case IceType_v16i8:
3245 case IceType_v8i16: 3258 case IceType_v8i16:
3246 case IceType_v4i32: 3259 case IceType_v4i32:
3247 case IceType_v4f32: 3260 case IceType_v4f32:
3248 ReturnReg = makeReg(Dest->getType(), RegARM32::Reg_q0); 3261 ReturnReg = makeReg(Dest->getType(), RegARM32::Reg_q0);
3249 break; 3262 break;
3250 } 3263 }
3251 } 3264 }
3252 // TODO(jvoung): Handle sandboxing. const bool NeedSandboxing =
3253 // Ctx->getFlags().getUseSandboxing();
3254 3265
3255 // Allow ConstantRelocatable to be left alone as a direct call, but force 3266 // Allow ConstantRelocatable to be left alone as a direct call, but force
3256 // other constants like ConstantInteger32 to be in a register and make it an 3267 // other constants like ConstantInteger32 to be in a register and make it an
3257 // indirect call. 3268 // indirect call.
3258 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { 3269 if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
3259 CallTarget = legalize(CallTarget, Legal_Reg); 3270 CallTarget = legalize(CallTarget, Legal_Reg);
3260 } 3271 }
3261 3272
3262 // Copy arguments to be passed in registers to the appropriate registers. 3273 // Copy arguments to be passed in registers to the appropriate registers.
3263 for (auto &FPArg : FPArgs) { 3274 for (auto &FPArg : FPArgs) {
3264 Variable *Reg = legalizeToReg(FPArg.first, FPArg.second); 3275 Variable *Reg = legalizeToReg(FPArg.first, FPArg.second);
3265 Context.insert(InstFakeUse::create(Func, Reg)); 3276 Context.insert(InstFakeUse::create(Func, Reg));
3266 } 3277 }
3267 for (auto &GPRArg : GPRArgs) { 3278 for (auto &GPRArg : GPRArgs) {
3268 Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second); 3279 Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second);
3269 // Generate a FakeUse of register arguments so that they do not get dead 3280 // Generate a FakeUse of register arguments so that they do not get dead
3270 // code eliminated as a result of the FakeKill of scratch registers after 3281 // code eliminated as a result of the FakeKill of scratch registers after
3271 // the call. 3282 // the call.
3272 Context.insert(InstFakeUse::create(Func, Reg)); 3283 Context.insert(InstFakeUse::create(Func, Reg));
3273 } 3284 }
3274 Inst *NewCall = InstARM32Call::create(Func, ReturnReg, CallTarget); 3285
3275 Context.insert(NewCall); 3286 InstARM32Call *NewCall = AutoSandboxer(this, InstBundleLock::Opt_AlignToEnd)
3287 .bl(ReturnReg, CallTarget);
3288
3276 if (ReturnRegHi) 3289 if (ReturnRegHi)
3277 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 3290 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
3278 3291
3279 // Insert a register-kill pseudo instruction. 3292 // Insert a register-kill pseudo instruction.
3280 Context.insert(InstFakeKill::create(Func, NewCall)); 3293 Context.insert(InstFakeKill::create(Func, NewCall));
3281 3294
3282 // Generate a FakeUse to keep the call live if necessary. 3295 // Generate a FakeUse to keep the call live if necessary.
3283 if (Instr->hasSideEffects() && ReturnReg) { 3296 if (Instr->hasSideEffects() && ReturnReg) {
3284 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); 3297 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg);
3285 Context.insert(FakeUse); 3298 Context.insert(FakeUse);
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 case Intrinsics::Memcpy: { 4618 case Intrinsics::Memcpy: {
4606 llvm::report_fatal_error("memcpy should have been prelowered."); 4619 llvm::report_fatal_error("memcpy should have been prelowered.");
4607 } 4620 }
4608 case Intrinsics::Memmove: { 4621 case Intrinsics::Memmove: {
4609 llvm::report_fatal_error("memmove should have been prelowered."); 4622 llvm::report_fatal_error("memmove should have been prelowered.");
4610 } 4623 }
4611 case Intrinsics::Memset: { 4624 case Intrinsics::Memset: {
4612 llvm::report_fatal_error("memmove should have been prelowered."); 4625 llvm::report_fatal_error("memmove should have been prelowered.");
4613 } 4626 }
4614 case Intrinsics::NaClReadTP: { 4627 case Intrinsics::NaClReadTP: {
4615 llvm::report_fatal_error("nacl-read-tp should have been prelowered."); 4628 if (!NeedSandboxing) {
4629 llvm::report_fatal_error("nacl-read-tp should have been prelowered.");
4630 }
4631 Variable *TP = legalizeToReg(OperandARM32Mem::create(
4632 Func, getPointerType(), getPhysicalRegister(RegARM32::Reg_r9),
4633 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))));
4634 _mov(Dest, TP);
4635 return;
4616 } 4636 }
4617 case Intrinsics::Setjmp: { 4637 case Intrinsics::Setjmp: {
4618 llvm::report_fatal_error("setjmp should have been prelowered."); 4638 llvm::report_fatal_error("setjmp should have been prelowered.");
4619 } 4639 }
4620 case Intrinsics::Sqrt: { 4640 case Intrinsics::Sqrt: {
4621 Variable *Src = legalizeToReg(Instr->getArg(0)); 4641 Variable *Src = legalizeToReg(Instr->getArg(0));
4622 Variable *T = makeReg(Dest->getType()); 4642 Variable *T = makeReg(Dest->getType());
4623 _vsqrt(T, Src); 4643 _vsqrt(T, Src);
4624 _mov(Dest, T); 4644 _mov(Dest, T);
4625 return; 4645 return;
4626 } 4646 }
4627 case Intrinsics::Stacksave: { 4647 case Intrinsics::Stacksave: {
4628 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 4648 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
4629 _mov(Dest, SP); 4649 _mov(Dest, SP);
4630 return; 4650 return;
4631 } 4651 }
4632 case Intrinsics::Stackrestore: { 4652 case Intrinsics::Stackrestore: {
4633 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 4653 Variable *Val = legalizeToReg(Instr->getArg(0));
4634 Operand *Val = legalize(Instr->getArg(0), Legal_Reg | Legal_Flex); 4654 AutoSandboxer(this).reset_sp(Val);
4635 _mov_redefined(SP, Val);
4636 return; 4655 return;
4637 } 4656 }
4638 case Intrinsics::Trap: 4657 case Intrinsics::Trap:
4639 _trap(); 4658 _trap();
4640 return; 4659 return;
4641 case Intrinsics::UnknownIntrinsic: 4660 case Intrinsics::UnknownIntrinsic:
4642 Func->setError("Should not be lowering UnknownIntrinsic"); 4661 Func->setError("Should not be lowering UnknownIntrinsic");
4643 return; 4662 return;
4644 } 4663 }
4645 return; 4664 return;
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4980 // "[reg]" addressing mode (the other supported modes are write back.) 4999 // "[reg]" addressing mode (the other supported modes are write back.)
4981 return nullptr; 5000 return nullptr;
4982 5001
4983 auto *BaseVar = llvm::dyn_cast<Variable>(Base); 5002 auto *BaseVar = llvm::dyn_cast<Variable>(Base);
4984 if (BaseVar == nullptr) 5003 if (BaseVar == nullptr)
4985 return nullptr; 5004 return nullptr;
4986 5005
4987 (void)MemTraitsSize; 5006 (void)MemTraitsSize;
4988 assert(Ty < MemTraitsSize); 5007 assert(Ty < MemTraitsSize);
4989 auto *TypeTraits = &MemTraits[Ty]; 5008 auto *TypeTraits = &MemTraits[Ty];
4990 const bool CanHaveIndex = TypeTraits->CanHaveIndex; 5009 const bool CanHaveIndex = !NeedSandboxing && TypeTraits->CanHaveIndex;
4991 const bool CanHaveShiftedIndex = TypeTraits->CanHaveShiftedIndex; 5010 const bool CanHaveShiftedIndex =
5011 !NeedSandboxing && TypeTraits->CanHaveShiftedIndex;
4992 const bool CanHaveImm = TypeTraits->CanHaveImm; 5012 const bool CanHaveImm = TypeTraits->CanHaveImm;
4993 const int32_t ValidImmMask = TypeTraits->ValidImmMask; 5013 const int32_t ValidImmMask = TypeTraits->ValidImmMask;
4994 (void)ValidImmMask; 5014 (void)ValidImmMask;
4995 assert(!CanHaveImm || ValidImmMask >= 0); 5015 assert(!CanHaveImm || ValidImmMask >= 0);
4996 5016
4997 const VariablesMetadata *VMetadata = Func->getVMetadata(); 5017 const VariablesMetadata *VMetadata = Func->getVMetadata();
4998 const Inst *Reason = nullptr; 5018 const Inst *Reason = nullptr;
4999 5019
5000 do { 5020 do {
5001 if (Reason != nullptr) { 5021 if (Reason != nullptr) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
5152 } else { 5172 } else {
5153 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex); 5173 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex);
5154 Reg = makeReg(Src0F->getType(), RegARM32::Reg_r0); 5174 Reg = makeReg(Src0F->getType(), RegARM32::Reg_r0);
5155 _mov(Reg, Src0F, CondARM32::AL); 5175 _mov(Reg, Src0F, CondARM32::AL);
5156 } 5176 }
5157 } 5177 }
5158 // Add a ret instruction even if sandboxing is enabled, because addEpilog 5178 // Add a ret instruction even if sandboxing is enabled, because addEpilog
5159 // explicitly looks for a ret instruction as a marker for where to insert the 5179 // explicitly looks for a ret instruction as a marker for where to insert the
5160 // frame removal instructions. addEpilog is responsible for restoring the 5180 // frame removal instructions. addEpilog is responsible for restoring the
5161 // "lr" register as needed prior to this ret instruction. 5181 // "lr" register as needed prior to this ret instruction.
5162 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg); 5182 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg);
Karl 2015/12/04 20:41:17 Indentation wrong?
John 2015/12/05 16:20:11 where, the _ret? seems fine to me (there's an unde
5183
5163 // Add a fake use of sp to make sure sp stays alive for the entire function. 5184 // Add a fake use of sp to make sure sp stays alive for the entire function.
5164 // Otherwise post-call sp adjustments get dead-code eliminated. 5185 // Otherwise post-call sp adjustments get dead-code eliminated.
5165 // TODO: Are there more places where the fake use should be inserted? E.g. 5186 // TODO: Are there more places where the fake use should be inserted? E.g.
5166 // "void f(int n){while(1) g(n);}" may not have a ret instruction. 5187 // "void f(int n){while(1) g(n);}" may not have a ret instruction.
5167 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); 5188 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
5168 Context.insert(InstFakeUse::create(Func, SP)); 5189 Context.insert(InstFakeUse::create(Func, SP));
5169 } 5190 }
5170 5191
5171 void TargetARM32::lowerSelect(const InstSelect *Inst) { 5192 void TargetARM32::lowerSelect(const InstSelect *Inst) {
5172 Variable *Dest = Inst->getDest(); 5193 Variable *Dest = Inst->getDest();
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 5926
5906 // Mark as "dead" rather than outright deleting. This is so that other 5927 // Mark as "dead" rather than outright deleting. This is so that other
5907 // peephole style optimizations during or before lowering have access to 5928 // peephole style optimizations during or before lowering have access to
5908 // this instruction in undeleted form. See for example 5929 // this instruction in undeleted form. See for example
5909 // tryOptimizedCmpxchgCmpBr(). 5930 // tryOptimizedCmpxchgCmpBr().
5910 Iter->second.Instr->setDead(); 5931 Iter->second.Instr->setDead();
5911 ++Iter; 5932 ++Iter;
5912 } 5933 }
5913 } 5934 }
5914 5935
5936 TargetARM32::AutoSandboxer::AutoSandboxer(TargetARM32 *Target,
5937 InstBundleLock::Option BundleOption)
5938 : Target(Target) {
5939 if (Target->NeedSandboxing) {
5940 Target->_bundle_lock(BundleOption);
5941 }
5942 }
5943
5944 TargetARM32::AutoSandboxer::~AutoSandboxer() {
5945 if (Target->NeedSandboxing) {
5946 Target->_bundle_unlock();
5947 }
5948 }
5949
5950 namespace {
5951 OperandARM32FlexImm *indirectBranchBicMask(Cfg *Func) {
5952 constexpr uint32_t Imm8 = 0xFC; // 0xC000000F
5953 constexpr uint32_t RotateAmt = 2;
5954 return OperandARM32FlexImm::create(Func, IceType_i32, Imm8, RotateAmt);
5955 }
5956
5957 OperandARM32FlexImm *memOpBicMask(Cfg *Func) {
5958 constexpr uint32_t Imm8 = 0x0C; // 0xC0000000
5959 constexpr uint32_t RotateAmt = 2;
5960 return OperandARM32FlexImm::create(Func, IceType_i32, Imm8, RotateAmt);
5961 }
Karl 2015/12/04 20:41:17 Add blank line?
John 2015/12/05 16:20:11 Done.
5962 static bool baseNeedsBic(Variable *Base) {
5963 return Base->getRegNum() != RegARM32::Reg_r9 &&
5964 Base->getRegNum() != RegARM32::Reg_sp;
5965 }
5966 } // end of anonymous namespace
5967
5968 void TargetARM32::AutoSandboxer::add_sp(Operand *AddAmount) {
5969 Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
5970 Target->_add(SP, SP, AddAmount);
5971 if (Target->NeedSandboxing) {
5972 Target->_bic(SP, SP, memOpBicMask(Target->Func));
5973 }
5974 }
5975
5976 void TargetARM32::AutoSandboxer::align_sp(size_t Alignment) {
5977 Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
5978 Target->alignRegisterPow2(SP, Alignment);
5979 if (Target->NeedSandboxing) {
5980 Target->_bic(SP, SP, memOpBicMask(Target->Func));
5981 }
5982 }
5983
5984 InstARM32Call *TargetARM32::AutoSandboxer::bl(Variable *ReturnReg,
5985 Operand *CallTarget) {
5986 if (Target->NeedSandboxing) {
5987 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
5988 Target->_bic(CallTargetR, CallTargetR,
5989 indirectBranchBicMask(Target->Func));
5990 }
5991 }
5992 auto *Call = InstARM32Call::create(Target->Func, ReturnReg, CallTarget);
5993 Target->Context.insert(Call);
5994 return Call;
5995 }
5996
5997 void TargetARM32::AutoSandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem,
5998 CondARM32::Cond Pred) {
5999 Variable *MemBase = Mem->getBase();
6000 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
6001 assert(!Mem->isRegReg());
6002 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
6003 }
6004 Target->_ldr(Dest, Mem, Pred);
6005 }
6006
6007 void TargetARM32::AutoSandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem,
6008 CondARM32::Cond Pred) {
6009 Variable *MemBase = Mem->getBase();
6010 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
6011 assert(!Mem->isRegReg());
6012 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
6013 }
6014 Target->_ldrex(Dest, Mem, Pred);
6015 }
6016
6017 void TargetARM32::AutoSandboxer::reset_sp(Variable *Src) {
6018 Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
6019 Target->_mov_redefined(SP, Src);
6020 if (Target->NeedSandboxing) {
6021 Target->_bic(SP, SP, memOpBicMask(Target->Func));
6022 }
6023 }
6024
6025 void TargetARM32::AutoSandboxer::ret(Variable *RetAddr, Variable *RetValue) {
6026 if (Target->NeedSandboxing) {
6027 Target->_bic(RetAddr, RetAddr, indirectBranchBicMask(Target->Func));
6028 }
6029 Target->_ret(RetAddr, RetValue);
6030 }
6031
6032 void TargetARM32::AutoSandboxer::str(Variable *Src, OperandARM32Mem *Mem,
6033 CondARM32::Cond Pred) {
6034 Variable *MemBase = Mem->getBase();
6035 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
6036 assert(!Mem->isRegReg());
6037 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
6038 }
6039 Target->_str(Src, Mem, Pred);
6040 }
6041
6042 void TargetARM32::AutoSandboxer::strex(Variable *Dest, Variable *Src,
6043 OperandARM32Mem *Mem,
6044 CondARM32::Cond Pred) {
6045 Variable *MemBase = Mem->getBase();
6046 if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
6047 assert(!Mem->isRegReg());
6048 Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
6049 }
6050 Target->_strex(Dest, Src, Mem, Pred);
6051 }
6052
6053 void TargetARM32::AutoSandboxer::sub_sp(Operand *SubAmount) {
6054 Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
6055 Target->_sub(SP, SP, SubAmount);
6056 if (Target->NeedSandboxing) {
6057 Target->_bic(SP, SP, memOpBicMask(Target->Func));
6058 }
6059 }
6060
5915 TargetDataARM32::TargetDataARM32(GlobalContext *Ctx) 6061 TargetDataARM32::TargetDataARM32(GlobalContext *Ctx)
5916 : TargetDataLowering(Ctx) {} 6062 : TargetDataLowering(Ctx) {}
5917 6063
5918 void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars, 6064 void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars,
5919 const IceString &SectionSuffix) { 6065 const IceString &SectionSuffix) {
5920 switch (Ctx->getFlags().getOutFileType()) { 6066 switch (Ctx->getFlags().getOutFileType()) {
5921 case FT_Elf: { 6067 case FT_Elf: {
5922 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 6068 ELFObjectWriter *Writer = Ctx->getObjectWriter();
5923 Writer->writeDataSection(Vars, llvm::ELF::R_ARM_ABS32, SectionSuffix); 6069 Writer->writeDataSection(Vars, llvm::ELF::R_ARM_ABS32, SectionSuffix);
5924 } break; 6070 } break;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
6100 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 6246 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
6101 // However, for compatibility with current NaCl LLVM, don't claim that. 6247 // However, for compatibility with current NaCl LLVM, don't claim that.
6102 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6248 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6103 } 6249 }
6104 6250
6105 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; 6251 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM];
6106 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6252 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6107 llvm::SmallBitVector TargetARM32::ScratchRegs; 6253 llvm::SmallBitVector TargetARM32::ScratchRegs;
6108 6254
6109 } // end of namespace Ice 6255 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698