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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1768823002: Subzero. ARM32. Fix bugs uncovered by scons tests. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: lit test fix. Created 4 years, 9 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
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 // 1408 //
1409 // This assumes Arg is an argument passed on the stack. This sets the frame 1409 // This assumes Arg is an argument passed on the stack. This sets the frame
1410 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an 1410 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an
1411 // I64 arg that has been split into Lo and Hi components, it calls itself 1411 // I64 arg that has been split into Lo and Hi components, it calls itself
1412 // recursively on the components, taking care to handle Lo first because of the 1412 // recursively on the components, taking care to handle Lo first because of the
1413 // little-endian architecture. Lastly, this function generates an instruction 1413 // little-endian architecture. Lastly, this function generates an instruction
1414 // to copy Arg into its assigned register if applicable. 1414 // to copy Arg into its assigned register if applicable.
1415 void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr, 1415 void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr,
1416 size_t BasicFrameOffset, 1416 size_t BasicFrameOffset,
1417 size_t *InArgsSizeBytes) { 1417 size_t *InArgsSizeBytes) {
1418 const Type Ty = Arg->getType();
1419 *InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
1420
1418 if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) { 1421 if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
1419 Variable *Lo = Arg64On32->getLo(); 1422 Variable *const Lo = Arg64On32->getLo();
1420 Variable *Hi = Arg64On32->getHi(); 1423 Variable *const Hi = Arg64On32->getHi();
1421 finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes); 1424 finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
1422 finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes); 1425 finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
1423 return; 1426 return;
1424 } 1427 }
1425 Type Ty = Arg->getType();
1426 assert(Ty != IceType_i64); 1428 assert(Ty != IceType_i64);
1427 1429
1428 *InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
1429 const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes; 1430 const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes;
1430 *InArgsSizeBytes += typeWidthInBytesOnStack(Ty); 1431 *InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
1431 1432
1432 if (!Arg->hasReg()) { 1433 if (!Arg->hasReg()) {
1433 Arg->setStackOffset(ArgStackOffset); 1434 Arg->setStackOffset(ArgStackOffset);
1434 return; 1435 return;
1435 } 1436 }
1436 1437
1437 // If the argument variable has been assigned a register, we need to copy the 1438 // If the argument variable has been assigned a register, we need to copy the
1438 // value from the stack slot. 1439 // value from the stack slot.
(...skipping 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after
4598 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) 4599 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
4599 return Integer->getValue(); 4600 return Integer->getValue();
4600 return Intrinsics::MemoryOrderInvalid; 4601 return Intrinsics::MemoryOrderInvalid;
4601 } 4602 }
4602 } // end of anonymous namespace 4603 } // end of anonymous namespace
4603 4604
4604 void TargetARM32::lowerLoadLinkedStoreExclusive( 4605 void TargetARM32::lowerLoadLinkedStoreExclusive(
4605 Type Ty, Operand *Addr, std::function<Variable *(Variable *)> Operation, 4606 Type Ty, Operand *Addr, std::function<Variable *(Variable *)> Operation,
4606 CondARM32::Cond Cond) { 4607 CondARM32::Cond Cond) {
4607 4608
4608 auto *Retry = Context.insert<InstARM32Label>(this); 4609 InstARM32Label *Retry = nullptr;
4610
4611 Retry = Context.insert<InstARM32Label>(this);
Eric Holk 2016/03/07 22:58:53 Why did you split this into two lines instead of l
John 2016/03/08 18:14:32 Leftover from one of the changes.
4612
4609 { // scoping for loop highlighting. 4613 { // scoping for loop highlighting.
4614 Variable *Success = makeReg(IceType_i32);
4610 Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty); 4615 Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty);
4611 auto *Success = makeReg(IceType_i32);
4612 auto *_0 = Ctx->getConstantZero(IceType_i32); 4616 auto *_0 = Ctx->getConstantZero(IceType_i32);
4613 4617
4614 Context.insert<InstFakeDef>(Tmp); 4618 Context.insert<InstFakeDef>(Tmp);
4615 Context.insert<InstFakeUse>(Tmp); 4619 Context.insert<InstFakeUse>(Tmp);
4616 Variable *AddrR = legalizeToReg(Addr); 4620 Variable *AddrR = legalizeToReg(Addr);
4617 _ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined(); 4621 _ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined();
4618 auto *StoreValue = Operation(Tmp); 4622 auto *StoreValue = Operation(Tmp);
4619 assert(StoreValue->mustHaveReg()); 4623 assert(StoreValue->mustHaveReg());
4620 _strex(Success, StoreValue, formMemoryOperand(AddrR, Ty), Cond); 4624 // strex requires Dest to be a register other than Value or Addr. This
4621 _cmp(Success, _0, Cond); 4625 // restriction is cleanly represented by adding an "early" definition of
4626 // Dest (or a latter use of all the sources.)
4627 Context.insert<InstFakeDef>(Success);
4628 if (Cond != CondARM32::AL) {
4629 _mov_redefined(Success, legalize(_0, Legal_Reg | Legal_Flex),
4630 InstARM32::getOppositeCondition(Cond));
4631 }
4632 _strex(Success, StoreValue, formMemoryOperand(AddrR, Ty), Cond)
4633 ->setDestRedefined();
4634 _cmp(Success, _0);
4622 } 4635 }
4636
4623 _br(Retry, CondARM32::NE); 4637 _br(Retry, CondARM32::NE);
4624 } 4638 }
4625 4639
4626 namespace { 4640 namespace {
4627 InstArithmetic *createArithInst(Cfg *Func, uint32_t Operation, Variable *Dest, 4641 InstArithmetic *createArithInst(Cfg *Func, uint32_t Operation, Variable *Dest,
4628 Variable *Src0, Operand *Src1) { 4642 Variable *Src0, Operand *Src1) {
4629 InstArithmetic::OpKind Oper; 4643 InstArithmetic::OpKind Oper;
4630 switch (Operation) { 4644 switch (Operation) {
4631 default: 4645 default:
4632 llvm::report_fatal_error("Unknown AtomicRMW operation"); 4646 llvm::report_fatal_error("Unknown AtomicRMW operation");
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
4883 // We require the memory address to be naturally aligned. Given that is the 4897 // We require the memory address to be naturally aligned. Given that is the
4884 // case, then normal loads are atomic. 4898 // case, then normal loads are atomic.
4885 if (!Intrinsics::isMemoryOrderValid( 4899 if (!Intrinsics::isMemoryOrderValid(
4886 ID, getConstantMemoryOrder(Instr->getArg(3)), 4900 ID, getConstantMemoryOrder(Instr->getArg(3)),
4887 getConstantMemoryOrder(Instr->getArg(4)))) { 4901 getConstantMemoryOrder(Instr->getArg(4)))) {
4888 Func->setError("Unexpected memory ordering for AtomicCmpxchg"); 4902 Func->setError("Unexpected memory ordering for AtomicCmpxchg");
4889 return; 4903 return;
4890 } 4904 }
4891 4905
4892 if (DestTy == IceType_i64) { 4906 if (DestTy == IceType_i64) {
4907 Variable *LoadedValue = nullptr;
4908 Variable **LoadedValuePtr = &LoadedValue;
4909
4893 auto *New = makeI64RegPair(); 4910 auto *New = makeI64RegPair();
4894 Context.insert<InstFakeDef>(New); 4911 Context.insert<InstFakeDef>(New);
4895 lowerAssign(InstAssign::create(Func, New, Instr->getArg(2))); 4912 lowerAssign(InstAssign::create(Func, New, Instr->getArg(2)));
4896 4913
4897 auto *Expected = makeI64RegPair(); 4914 auto *Expected = makeI64RegPair();
4898 Context.insert<InstFakeDef>(Expected); 4915 Context.insert<InstFakeDef>(Expected);
4899 lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1))); 4916 lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1)));
4900 4917
4901 _dmb(); 4918 _dmb();
4902 lowerLoadLinkedStoreExclusive( 4919 lowerLoadLinkedStoreExclusive(
4903 DestTy, Instr->getArg(0), 4920 DestTy, Instr->getArg(0),
4904 [this, Expected, New, Instr, DestTy](Variable *Tmp) { 4921 [this, Expected, New, Instr, DestTy, LoadedValuePtr](Variable *Tmp) {
Eric Holk 2016/03/07 22:58:53 How do you feel about during a by-reference captur
John 2016/03/08 18:14:32 I don't like this idiom, but I dislike non const r
4905 auto *ExpectedLoR = llvm::cast<Variable>(loOperand(Expected)); 4922 auto *ExpectedLoR = llvm::cast<Variable>(loOperand(Expected));
4906 auto *ExpectedHiR = llvm::cast<Variable>(hiOperand(Expected)); 4923 auto *ExpectedHiR = llvm::cast<Variable>(hiOperand(Expected));
4907 auto *TmpLoR = llvm::cast<Variable>(loOperand(Tmp)); 4924 auto *TmpLoR = llvm::cast<Variable>(loOperand(Tmp));
4908 auto *TmpHiR = llvm::cast<Variable>(hiOperand(Tmp)); 4925 auto *TmpHiR = llvm::cast<Variable>(hiOperand(Tmp));
4909 _cmp(TmpLoR, ExpectedLoR); 4926 _cmp(TmpLoR, ExpectedLoR);
4910 _cmp(TmpHiR, ExpectedHiR, CondARM32::EQ); 4927 _cmp(TmpHiR, ExpectedHiR, CondARM32::EQ);
4928 *LoadedValuePtr = Tmp;
4911 // Adding an explicit use of Tmp here, or its live range will not 4929 // Adding an explicit use of Tmp here, or its live range will not
4912 // reach here (only those of Tmp.Lo and Tmp.Hi will.) 4930 // reach here (only those of Tmp.Lo and Tmp.Hi will.)
4913 Context.insert<InstFakeUse>(Tmp); 4931 // Context.insert<InstFakeUse>(Tmp);
Jim Stichnoth 2016/03/07 23:25:48 Delete these comments?
John 2016/03/08 18:14:32 Done.
4914 _mov_redefined(ExpectedLoR, TmpLoR); 4932 //_mov_redefined(ExpectedLoR, TmpLoR);
4915 _mov_redefined(ExpectedHiR, TmpHiR); 4933 //_mov_redefined(ExpectedHiR, TmpHiR);
4916 // Same as above. 4934 // Same as above.
4917 Context.insert<InstFakeUse>(Tmp); 4935 // Context.insert<InstFakeUse>(Tmp);
4918 return New; 4936 return New;
4919 }, 4937 },
4920 CondARM32::EQ); 4938 CondARM32::EQ);
4921 _dmb(); 4939 _dmb();
4922 4940
4923 lowerAssign(InstAssign::create(Func, Dest, Expected)); 4941 Context.insert<InstFakeUse>(LoadedValue);
4942 lowerAssign(InstAssign::create(Func, Dest, LoadedValue));
4924 // The fake-use Expected prevents the assignments to Expected (above) 4943 // The fake-use Expected prevents the assignments to Expected (above)
4925 // from being removed if Dest is not used. 4944 // from being removed if Dest is not used.
4926 Context.insert<InstFakeUse>(Expected); 4945 Context.insert<InstFakeUse>(Expected);
4927 // New needs to be alive here, or its live range will end in the 4946 // New needs to be alive here, or its live range will end in the
4928 // strex instruction. 4947 // strex instruction.
4929 Context.insert<InstFakeUse>(New); 4948 Context.insert<InstFakeUse>(New);
4930 return; 4949 return;
4931 } 4950 }
4932 4951
4933 auto *New = legalizeToReg(Instr->getArg(2)); 4952 auto *New = legalizeToReg(Instr->getArg(2));
4934 auto *Expected = legalizeToReg(Instr->getArg(1)); 4953 auto *Expected = legalizeToReg(Instr->getArg(1));
4954 Variable *LoadedValue = nullptr;
4955 Variable **LoadedValuePtr = &LoadedValue;
4935 4956
4936 _dmb(); 4957 _dmb();
4937 lowerLoadLinkedStoreExclusive( 4958 lowerLoadLinkedStoreExclusive(
4938 DestTy, 4959 DestTy, Instr->getArg(0),
4939 Instr->getArg(0), [this, Expected, New, Instr, DestTy](Variable *Tmp) { 4960 [this, Expected, New, Instr, DestTy, LoadedValuePtr](Variable *Tmp) {
4940 lowerIcmpCond(InstIcmp::Eq, Tmp, Expected); 4961 lowerIcmpCond(InstIcmp::Eq, Tmp, Expected);
4941 _mov_redefined(Expected, Tmp); 4962 *LoadedValuePtr = Tmp;
4963 //_mov_redefined(Expected, Tmp);
4942 return New; 4964 return New;
4943 }, CondARM32::EQ); 4965 },
4966 CondARM32::EQ);
4944 _dmb(); 4967 _dmb();
4945 4968
4946 lowerAssign(InstAssign::create(Func, Dest, Expected)); 4969 lowerAssign(InstAssign::create(Func, Dest, LoadedValue));
4947 Context.insert<InstFakeUse>(Expected); 4970 Context.insert<InstFakeUse>(Expected);
4948 Context.insert<InstFakeUse>(New); 4971 Context.insert<InstFakeUse>(New);
4949 return; 4972 return;
4950 } 4973 }
4951 case Intrinsics::AtomicRMW: { 4974 case Intrinsics::AtomicRMW: {
4952 if (!Intrinsics::isMemoryOrderValid( 4975 if (!Intrinsics::isMemoryOrderValid(
4953 ID, getConstantMemoryOrder(Instr->getArg(3)))) { 4976 ID, getConstantMemoryOrder(Instr->getArg(3)))) {
4954 Func->setError("Unexpected memory ordering for AtomicRMW"); 4977 Func->setError("Unexpected memory ordering for AtomicRMW");
4955 return; 4978 return;
4956 } 4979 }
(...skipping 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after
6885 // However, for compatibility with current NaCl LLVM, don't claim that. 6908 // However, for compatibility with current NaCl LLVM, don't claim that.
6886 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6909 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6887 } 6910 }
6888 6911
6889 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; 6912 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM];
6890 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; 6913 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM];
6891 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6914 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6892 6915
6893 } // end of namespace ARM32 6916 } // end of namespace ARM32
6894 } // end of namespace Ice 6917 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698