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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1326013002: Refactor Lo and Hi out of Variable. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Refactor Hi and Lo out of Variable Created 5 years, 3 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') | src/IceTargetLoweringMIPS32.h » ('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 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 Context.setInsertPoint(Context.getCur()); 521 Context.setInsertPoint(Context.getCur());
522 522
523 for (SizeT I = 0, E = Args.size(); I < E; ++I) { 523 for (SizeT I = 0, E = Args.size(); I < E; ++I) {
524 Variable *Arg = Args[I]; 524 Variable *Arg = Args[I];
525 Type Ty = Arg->getType(); 525 Type Ty = Arg->getType();
526 if (Ty == IceType_i64) { 526 if (Ty == IceType_i64) {
527 std::pair<int32_t, int32_t> RegPair; 527 std::pair<int32_t, int32_t> RegPair;
528 if (!CC.I64InRegs(&RegPair)) 528 if (!CC.I64InRegs(&RegPair))
529 continue; 529 continue;
530 Variable *RegisterArg = Func->makeVariable(Ty); 530 Variable *RegisterArg = Func->makeVariable(Ty);
531 Variable *RegisterLo = Func->makeVariable(IceType_i32); 531 auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg);
532 Variable *RegisterHi = Func->makeVariable(IceType_i32); 532 if (BuildDefs::dump())
533 if (BuildDefs::dump()) { 533 RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func));
534 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 534 RegisterArg64On32->initHiLo(Func);
535 RegisterLo->setName(Func, "home_reg_lo:" + Arg->getName(Func)); 535 RegisterArg64On32->setIsArg();
536 RegisterHi->setName(Func, "home_reg_hi:" + Arg->getName(Func)); 536 RegisterArg64On32->getLo()->setRegNum(RegPair.first);
537 } 537 RegisterArg64On32->getHi()->setRegNum(RegPair.second);
538 RegisterLo->setRegNum(RegPair.first);
539 RegisterLo->setIsArg();
540 RegisterHi->setRegNum(RegPair.second);
541 RegisterHi->setIsArg();
542 RegisterArg->setLoHi(RegisterLo, RegisterHi);
543 RegisterArg->setIsArg();
544 Arg->setIsArg(false); 538 Arg->setIsArg(false);
545 539
546 Args[I] = RegisterArg; 540 Args[I] = RegisterArg64On32;
547 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 541 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
548 continue; 542 continue;
549 } else { 543 } else {
550 int32_t RegNum; 544 int32_t RegNum;
551 if (isVectorType(Ty) || isFloatingType(Ty)) { 545 if (isVectorType(Ty) || isFloatingType(Ty)) {
552 if (!CC.FPInReg(Ty, &RegNum)) 546 if (!CC.FPInReg(Ty, &RegNum))
553 continue; 547 continue;
554 } else { 548 } else {
555 assert(Ty == IceType_i32); 549 assert(Ty == IceType_i32);
556 if (!CC.I32InReg(&RegNum)) 550 if (!CC.I32InReg(&RegNum))
(...skipping 18 matching lines...) Expand all
575 // 569 //
576 // This assumes Arg is an argument passed on the stack. This sets the frame 570 // This assumes Arg is an argument passed on the stack. This sets the frame
577 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an 571 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an
578 // I64 arg that has been split into Lo and Hi components, it calls itself 572 // I64 arg that has been split into Lo and Hi components, it calls itself
579 // recursively on the components, taking care to handle Lo first because of the 573 // recursively on the components, taking care to handle Lo first because of the
580 // little-endian architecture. Lastly, this function generates an instruction 574 // little-endian architecture. Lastly, this function generates an instruction
581 // to copy Arg into its assigned register if applicable. 575 // to copy Arg into its assigned register if applicable.
582 void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr, 576 void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr,
583 size_t BasicFrameOffset, 577 size_t BasicFrameOffset,
584 size_t &InArgsSizeBytes) { 578 size_t &InArgsSizeBytes) {
585 Variable *Lo = Arg->getLo(); 579 if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
586 Variable *Hi = Arg->getHi(); 580 Variable *Lo = Arg64On32->getLo();
587 Type Ty = Arg->getType(); 581 Variable *Hi = Arg64On32->getHi();
588 if (Lo && Hi && Ty == IceType_i64) {
589 assert(Lo->getType() != IceType_i64); // don't want infinite recursion
590 assert(Hi->getType() != IceType_i64); // don't want infinite recursion
591 finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes); 582 finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
592 finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes); 583 finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
593 return; 584 return;
594 } 585 }
586 Type Ty = Arg->getType();
595 InArgsSizeBytes = applyStackAlignmentTy(InArgsSizeBytes, Ty); 587 InArgsSizeBytes = applyStackAlignmentTy(InArgsSizeBytes, Ty);
596 Arg->setStackOffset(BasicFrameOffset + InArgsSizeBytes); 588 Arg->setStackOffset(BasicFrameOffset + InArgsSizeBytes);
597 InArgsSizeBytes += typeWidthInBytesOnStack(Ty); 589 InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
598 // If the argument variable has been assigned a register, we need to load the 590 // If the argument variable has been assigned a register, we need to load the
599 // value from the stack slot. 591 // value from the stack slot.
600 if (Arg->hasReg()) { 592 if (Arg->hasReg()) {
601 assert(Ty != IceType_i64); 593 assert(Ty != IceType_i64);
602 OperandARM32Mem *Mem = OperandARM32Mem::create( 594 OperandARM32Mem *Mem = OperandARM32Mem::create(
603 Func, Ty, FramePtr, llvm::cast<ConstantInteger32>( 595 Func, Ty, FramePtr, llvm::cast<ConstantInteger32>(
604 Ctx->getConstantInt32(Arg->getStackOffset()))); 596 Ctx->getConstantInt32(Arg->getStackOffset())));
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 MovInst->setDeleted(); 1037 MovInst->setDeleted();
1046 NewBaseReg = LegalVar; 1038 NewBaseReg = LegalVar;
1047 NewBaseOffset = Offset; 1039 NewBaseOffset = Offset;
1048 continue; 1040 continue;
1049 } 1041 }
1050 } 1042 }
1051 } 1043 }
1052 } 1044 }
1053 } 1045 }
1054 1046
1055 void TargetARM32::split64(Variable *Var) {
1056 assert(Var->getType() == IceType_i64);
1057 Variable *Lo = Var->getLo();
1058 Variable *Hi = Var->getHi();
1059 if (Lo) {
1060 assert(Hi);
1061 return;
1062 }
1063 assert(Hi == nullptr);
1064 Lo = Func->makeVariable(IceType_i32);
1065 Hi = Func->makeVariable(IceType_i32);
1066 if (BuildDefs::dump()) {
1067 Lo->setName(Func, Var->getName(Func) + "__lo");
1068 Hi->setName(Func, Var->getName(Func) + "__hi");
1069 }
1070 Var->setLoHi(Lo, Hi);
1071 if (Var->getIsArg()) {
1072 Lo->setIsArg();
1073 Hi->setIsArg();
1074 }
1075 }
1076
1077 Operand *TargetARM32::loOperand(Operand *Operand) { 1047 Operand *TargetARM32::loOperand(Operand *Operand) {
1078 assert(Operand->getType() == IceType_i64); 1048 assert(Operand->getType() == IceType_i64);
1079 if (Operand->getType() != IceType_i64) 1049 if (Operand->getType() != IceType_i64)
1080 return Operand; 1050 return Operand;
1081 if (auto *Var = llvm::dyn_cast<Variable>(Operand)) { 1051 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
1082 split64(Var); 1052 return Var64On32->getLo();
1083 return Var->getLo(); 1053 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand))
1084 }
1085 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1086 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 1054 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue()));
1087 }
1088 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) { 1055 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) {
1089 // Conservatively disallow memory operands with side-effects (pre/post 1056 // Conservatively disallow memory operands with side-effects (pre/post
1090 // increment) in case of duplication. 1057 // increment) in case of duplication.
1091 assert(Mem->getAddrMode() == OperandARM32Mem::Offset || 1058 assert(Mem->getAddrMode() == OperandARM32Mem::Offset ||
1092 Mem->getAddrMode() == OperandARM32Mem::NegOffset); 1059 Mem->getAddrMode() == OperandARM32Mem::NegOffset);
1093 if (Mem->isRegReg()) { 1060 if (Mem->isRegReg()) {
1094 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(), 1061 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(),
1095 Mem->getIndex(), Mem->getShiftOp(), 1062 Mem->getIndex(), Mem->getShiftOp(),
1096 Mem->getShiftAmt(), Mem->getAddrMode()); 1063 Mem->getShiftAmt(), Mem->getAddrMode());
1097 } else { 1064 } else {
1098 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(), 1065 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(),
1099 Mem->getOffset(), Mem->getAddrMode()); 1066 Mem->getOffset(), Mem->getAddrMode());
1100 } 1067 }
1101 } 1068 }
1102 llvm_unreachable("Unsupported operand type"); 1069 llvm_unreachable("Unsupported operand type");
1103 return nullptr; 1070 return nullptr;
1104 } 1071 }
1105 1072
1106 Operand *TargetARM32::hiOperand(Operand *Operand) { 1073 Operand *TargetARM32::hiOperand(Operand *Operand) {
1107 assert(Operand->getType() == IceType_i64); 1074 assert(Operand->getType() == IceType_i64);
1108 if (Operand->getType() != IceType_i64) 1075 if (Operand->getType() != IceType_i64)
1109 return Operand; 1076 return Operand;
1110 if (auto *Var = llvm::dyn_cast<Variable>(Operand)) { 1077 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
1111 split64(Var); 1078 return Var64On32->getHi();
1112 return Var->getHi();
1113 }
1114 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1079 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1115 return Ctx->getConstantInt32( 1080 return Ctx->getConstantInt32(
1116 static_cast<uint32_t>(Const->getValue() >> 32)); 1081 static_cast<uint32_t>(Const->getValue() >> 32));
1117 } 1082 }
1118 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) { 1083 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) {
1119 // Conservatively disallow memory operands with side-effects in case of 1084 // Conservatively disallow memory operands with side-effects in case of
1120 // duplication. 1085 // duplication.
1121 assert(Mem->getAddrMode() == OperandARM32Mem::Offset || 1086 assert(Mem->getAddrMode() == OperandARM32Mem::Offset ||
1122 Mem->getAddrMode() == OperandARM32Mem::NegOffset); 1087 Mem->getAddrMode() == OperandARM32Mem::NegOffset);
1123 const Type SplitType = IceType_i32; 1088 const Type SplitType = IceType_i32;
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); 1893 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg);
1929 Context.insert(FakeUse); 1894 Context.insert(FakeUse);
1930 } 1895 }
1931 1896
1932 if (!Dest) 1897 if (!Dest)
1933 return; 1898 return;
1934 1899
1935 // Assign the result of the call to Dest. 1900 // Assign the result of the call to Dest.
1936 if (ReturnReg) { 1901 if (ReturnReg) {
1937 if (ReturnRegHi) { 1902 if (ReturnRegHi) {
1938 assert(Dest->getType() == IceType_i64); 1903 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
1939 split64(Dest); 1904 Variable *DestLo = Dest64On32->getLo();
1940 Variable *DestLo = Dest->getLo(); 1905 Variable *DestHi = Dest64On32->getHi();
1941 Variable *DestHi = Dest->getHi();
1942 _mov(DestLo, ReturnReg); 1906 _mov(DestLo, ReturnReg);
1943 _mov(DestHi, ReturnRegHi); 1907 _mov(DestHi, ReturnRegHi);
1944 } else { 1908 } else {
1945 if (isFloatingType(Dest->getType()) || isVectorType(Dest->getType())) { 1909 if (isFloatingType(Dest->getType()) || isVectorType(Dest->getType())) {
1946 _vmov(Dest, ReturnReg); 1910 _vmov(Dest, ReturnReg);
1947 } else { 1911 } else {
1948 assert(isIntegerType(Dest->getType()) && 1912 assert(isIntegerType(Dest->getType()) &&
1949 typeWidthInBytes(Dest->getType()) <= 4); 1913 typeWidthInBytes(Dest->getType()) <= 4);
1950 _mov(Dest, ReturnReg); 1914 _mov(Dest, ReturnReg);
1951 } 1915 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 // t1.fp = vcvt src0.fp 2060 // t1.fp = vcvt src0.fp
2097 // t2.i32 = vmov t1.fp 2061 // t2.i32 = vmov t1.fp
2098 // dest.int = conv t2.i32 @ Truncates the result if needed. 2062 // dest.int = conv t2.i32 @ Truncates the result if needed.
2099 // fptoui: 2063 // fptoui:
2100 // t1.fp = vcvt src0.fp 2064 // t1.fp = vcvt src0.fp
2101 // t2.u32 = vmov t1.fp 2065 // t2.u32 = vmov t1.fp
2102 // dest.uint = conv t2.u32 @ Truncates the result if needed. 2066 // dest.uint = conv t2.u32 @ Truncates the result if needed.
2103 if (isVectorType(Dest->getType())) { 2067 if (isVectorType(Dest->getType())) {
2104 UnimplementedError(Func->getContext()->getFlags()); 2068 UnimplementedError(Func->getContext()->getFlags());
2105 break; 2069 break;
2106 } else if (Dest->getType() == IceType_i64) { 2070 }
2107 split64(Dest); 2071 if (auto *Dest64On32 = llvm::dyn_cast<Variable64On32>(Dest)) {
2108 Context.insert(InstFakeDef::create(Func, Dest->getLo())); 2072 Context.insert(InstFakeDef::create(Func, Dest64On32->getLo()));
2109 Context.insert(InstFakeDef::create(Func, Dest->getHi())); 2073 Context.insert(InstFakeDef::create(Func, Dest64On32->getHi()));
2110 UnimplementedError(Func->getContext()->getFlags()); 2074 UnimplementedError(Func->getContext()->getFlags());
2111 break; 2075 break;
2112 } 2076 }
2113 const bool DestIsSigned = CastKind == InstCast::Fptosi; 2077 const bool DestIsSigned = CastKind == InstCast::Fptosi;
2114 Variable *Src0R = legalizeToReg(Src0); 2078 Variable *Src0R = legalizeToReg(Src0);
2115 Variable *T_fp = makeReg(IceType_f32); 2079 Variable *T_fp = makeReg(IceType_f32);
2116 if (isFloat32Asserting32Or64(Src0->getType())) { 2080 if (isFloat32Asserting32Or64(Src0->getType())) {
2117 _vcvt(T_fp, Src0R, 2081 _vcvt(T_fp, Src0R,
2118 DestIsSigned ? InstARM32Vcvt::S2si : InstARM32Vcvt::S2ui); 2082 DestIsSigned ? InstARM32Vcvt::S2si : InstARM32Vcvt::S2ui);
2119 } else { 2083 } else {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 break; 2170 break;
2207 } 2171 }
2208 case IceType_i64: { 2172 case IceType_i64: {
2209 // t0, t1 <- src0 2173 // t0, t1 <- src0
2210 // dest[31..0] = t0 2174 // dest[31..0] = t0
2211 // dest[63..32] = t1 2175 // dest[63..32] = t1
2212 assert(Src0->getType() == IceType_f64); 2176 assert(Src0->getType() == IceType_f64);
2213 Variable *T0 = makeReg(IceType_i32); 2177 Variable *T0 = makeReg(IceType_i32);
2214 Variable *T1 = makeReg(IceType_i32); 2178 Variable *T1 = makeReg(IceType_i32);
2215 Variable *Src0R = legalizeToReg(Src0); 2179 Variable *Src0R = legalizeToReg(Src0);
2216 split64(Dest);
2217 _vmov(InstARM32Vmov::RegisterPair(T0, T1), Src0R); 2180 _vmov(InstARM32Vmov::RegisterPair(T0, T1), Src0R);
2218 lowerAssign(InstAssign::create(Func, Dest->getLo(), T0)); 2181 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
2219 lowerAssign(InstAssign::create(Func, Dest->getHi(), T1)); 2182 lowerAssign(InstAssign::create(Func, Dest64On32->getLo(), T0));
2183 lowerAssign(InstAssign::create(Func, Dest64On32->getHi(), T1));
2220 break; 2184 break;
2221 } 2185 }
2222 case IceType_f64: { 2186 case IceType_f64: {
2223 // T0 <- lo(src) 2187 // T0 <- lo(src)
2224 // T1 <- hi(src) 2188 // T1 <- hi(src)
2225 // vmov T2, T0, T1 2189 // vmov T2, T0, T1
2226 // Dest <- T2 2190 // Dest <- T2
2227 assert(Src0->getType() == IceType_i64); 2191 assert(Src0->getType() == IceType_i64);
2228 Variable *SrcLo = legalizeToReg(loOperand(Src0)); 2192 Variable *SrcLo = legalizeToReg(loOperand(Src0));
2229 Variable *SrcHi = legalizeToReg(hiOperand(Src0)); 2193 Variable *SrcHi = legalizeToReg(hiOperand(Src0));
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 3167 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
3204 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 3168 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
3205 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 3169 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
3206 } 3170 }
3207 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 3171 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
3208 // However, for compatibility with current NaCl LLVM, don't claim that. 3172 // However, for compatibility with current NaCl LLVM, don't claim that.
3209 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 3173 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
3210 } 3174 }
3211 3175
3212 } // end of namespace Ice 3176 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringMIPS32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698