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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1348393002: Subzero. Fixes ARM32 VFP calling convention. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: 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
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
11 /// This file implements the TargetLoweringARM32 class, which consists almost 11 /// This file implements the TargetLoweringARM32 class, which consists almost
12 /// entirely of the lowering sequence for each high-level instruction. 12 /// entirely of the lowering sequence for each high-level instruction.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15
16 #include "IceTargetLoweringARM32.h" 15 #include "IceTargetLoweringARM32.h"
17 16
18 #include "IceCfg.h" 17 #include "IceCfg.h"
19 #include "IceCfgNode.h" 18 #include "IceCfgNode.h"
20 #include "IceClFlags.h" 19 #include "IceClFlags.h"
21 #include "IceDefs.h" 20 #include "IceDefs.h"
22 #include "IceELFObjectWriter.h" 21 #include "IceELFObjectWriter.h"
23 #include "IceGlobalInits.h" 22 #include "IceGlobalInits.h"
24 #include "IceInstARM32.h" 23 #include "IceInstARM32.h"
25 #include "IceLiveness.h" 24 #include "IceLiveness.h"
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 462
464 bool TargetARM32::CallingConv::I32InReg(int32_t *Reg) { 463 bool TargetARM32::CallingConv::I32InReg(int32_t *Reg) {
465 if (NumGPRRegsUsed >= ARM32_MAX_GPR_ARG) 464 if (NumGPRRegsUsed >= ARM32_MAX_GPR_ARG)
466 return false; 465 return false;
467 *Reg = RegARM32::Reg_r0 + NumGPRRegsUsed; 466 *Reg = RegARM32::Reg_r0 + NumGPRRegsUsed;
468 ++NumGPRRegsUsed; 467 ++NumGPRRegsUsed;
469 return true; 468 return true;
470 } 469 }
471 470
472 bool TargetARM32::CallingConv::FPInReg(Type Ty, int32_t *Reg) { 471 bool TargetARM32::CallingConv::FPInReg(Type Ty, int32_t *Reg) {
473 if (NumFPRegUnits >= ARM32_MAX_FP_REG_UNITS) 472 if (!VFPRegsFree.any()) {
474 return false; 473 return false;
474 }
475
475 if (isVectorType(Ty)) { 476 if (isVectorType(Ty)) {
476 NumFPRegUnits = Utils::applyAlignment(NumFPRegUnits, 4);
477 // Q registers are declared in reverse order, so 477 // Q registers are declared in reverse order, so
478 // RegARM32::Reg_q0 > RegARM32::Reg_q1. Therefore, we need to subtract 478 // RegARM32::Reg_q0 > RegARM32::Reg_q1. Therefore, we need to subtract
479 // NumFPRegUnits from Reg_q0. Same thing goes for D registers. 479 // NumFPRegUnits from Reg_q0. Same thing goes for D registers.
480 static_assert(RegARM32::Reg_q0 > RegARM32::Reg_q1, 480 static_assert(RegARM32::Reg_q0 > RegARM32::Reg_q1,
481 "ARM32 Q registers are possibly declared incorrectly."); 481 "ARM32 Q registers are possibly declared incorrectly.");
482 *Reg = RegARM32::Reg_q0 - (NumFPRegUnits / 4); 482
483 NumFPRegUnits += 4; 483 int32_t QRegStart = (VFPRegsFree & ValidV128Regs).find_first();
484 // If this bumps us past the boundary, don't allocate to a register 484 if (QRegStart >= 0) {
485 // and leave any previously speculatively consumed registers as consumed. 485 VFPRegsFree.reset(QRegStart, QRegStart + 4);
486 if (NumFPRegUnits > ARM32_MAX_FP_REG_UNITS) 486 *Reg = RegARM32::Reg_q0 - (QRegStart / 4);
487 return false; 487 return true;
488 }
488 } else if (Ty == IceType_f64) { 489 } else if (Ty == IceType_f64) {
489 static_assert(RegARM32::Reg_d0 > RegARM32::Reg_d1, 490 static_assert(RegARM32::Reg_d0 > RegARM32::Reg_d1,
490 "ARM32 D registers are possibly declared incorrectly."); 491 "ARM32 D registers are possibly declared incorrectly.");
491 NumFPRegUnits = Utils::applyAlignment(NumFPRegUnits, 2); 492
492 *Reg = RegARM32::Reg_d0 - (NumFPRegUnits / 2); 493 int32_t DRegStart = (VFPRegsFree & ValidF64Regs).find_first();
493 NumFPRegUnits += 2; 494 if (DRegStart >= 0) {
494 // If this bumps us past the boundary, don't allocate to a register 495 VFPRegsFree.reset(DRegStart, DRegStart + 2);
495 // and leave any previously speculatively consumed registers as consumed. 496 *Reg = RegARM32::Reg_d0 - (DRegStart / 2);
496 if (NumFPRegUnits > ARM32_MAX_FP_REG_UNITS) 497 return true;
497 return false; 498 }
498 } else { 499 } else {
499 static_assert(RegARM32::Reg_s0 < RegARM32::Reg_s1, 500 static_assert(RegARM32::Reg_s0 < RegARM32::Reg_s1,
500 "ARM32 S registers are possibly declared incorrectly."); 501 "ARM32 S registers are possibly declared incorrectly.");
502
501 assert(Ty == IceType_f32); 503 assert(Ty == IceType_f32);
502 *Reg = RegARM32::Reg_s0 + NumFPRegUnits; 504 int32_t SReg = VFPRegsFree.find_first();
503 ++NumFPRegUnits; 505 assert(SReg >= 0);
506 VFPRegsFree.reset(SReg);
507 *Reg = RegARM32::Reg_s0 + SReg;
508 return true;
504 } 509 }
505 return true; 510
511 // Parameter allocation failed. From now on, every fp register must be placed
512 // on the stack. We clear VFRegsFree in case there are any "holes" from S and
513 // D registers.
514 VFPRegsFree.clear();
515 return false;
506 } 516 }
507 517
508 void TargetARM32::lowerArguments() { 518 void TargetARM32::lowerArguments() {
509 VarList &Args = Func->getArgs(); 519 VarList &Args = Func->getArgs();
510 TargetARM32::CallingConv CC; 520 TargetARM32::CallingConv CC;
511 521
512 // For each register argument, replace Arg in the argument list with the 522 // For each register argument, replace Arg in the argument list with the
513 // home register. Then generate an instruction in the prolog to copy the 523 // home register. Then generate an instruction in the prolog to copy the
514 // home register to the assigned location of Arg. 524 // home register to the assigned location of Arg.
515 Context.init(Func->getEntryNode()); 525 Context.init(Func->getEntryNode());
(...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 case IceType_v16i1: 2252 case IceType_v16i1:
2243 UnimplementedError(Func->getContext()->getFlags()); 2253 UnimplementedError(Func->getContext()->getFlags());
2244 break; 2254 break;
2245 case IceType_v8i16: 2255 case IceType_v8i16:
2246 UnimplementedError(Func->getContext()->getFlags()); 2256 UnimplementedError(Func->getContext()->getFlags());
2247 break; 2257 break;
2248 case IceType_v16i8: 2258 case IceType_v16i8:
2249 UnimplementedError(Func->getContext()->getFlags()); 2259 UnimplementedError(Func->getContext()->getFlags());
2250 break; 2260 break;
2251 case IceType_v4i32: 2261 case IceType_v4i32:
2262 // avoid cryptic liveness errors
2263 Context.insert(InstFakeDef::create(Func, Dest));
2252 UnimplementedError(Func->getContext()->getFlags()); 2264 UnimplementedError(Func->getContext()->getFlags());
2253 break; 2265 break;
2254 case IceType_v4f32: 2266 case IceType_v4f32:
2255 UnimplementedError(Func->getContext()->getFlags()); 2267 UnimplementedError(Func->getContext()->getFlags());
2256 break; 2268 break;
2257 } 2269 }
2258 break; 2270 break;
2259 } 2271 }
2260 } 2272 }
2261 } 2273 }
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 Operand *Addr = Inst->getAddr(); 2790 Operand *Addr = Inst->getAddr();
2779 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); 2791 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
2780 Type Ty = NewAddr->getType(); 2792 Type Ty = NewAddr->getType();
2781 2793
2782 if (Ty == IceType_i64) { 2794 if (Ty == IceType_i64) {
2783 Value = legalizeUndef(Value); 2795 Value = legalizeUndef(Value);
2784 Variable *ValueHi = legalizeToReg(hiOperand(Value)); 2796 Variable *ValueHi = legalizeToReg(hiOperand(Value));
2785 Variable *ValueLo = legalizeToReg(loOperand(Value)); 2797 Variable *ValueLo = legalizeToReg(loOperand(Value));
2786 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); 2798 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr)));
2787 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); 2799 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr)));
2788 } else if (isVectorType(Ty)) {
2789 UnimplementedError(Func->getContext()->getFlags());
2790 } else { 2800 } else {
2801 if (isVectorType(Ty)) {
2802 UnimplementedError(Func->getContext()->getFlags());
2803 }
2791 Variable *ValueR = legalizeToReg(Value); 2804 Variable *ValueR = legalizeToReg(Value);
2792 _str(ValueR, NewAddr); 2805 _str(ValueR, NewAddr);
2793 } 2806 }
2794 } 2807 }
2795 2808
2796 void TargetARM32::doAddressOptStore() { 2809 void TargetARM32::doAddressOptStore() {
2797 UnimplementedError(Func->getContext()->getFlags()); 2810 UnimplementedError(Func->getContext()->getFlags());
2798 } 2811 }
2799 2812
2800 void TargetARM32::lowerSwitch(const InstSwitch *Inst) { 2813 void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2842 Variable *Reg = makeReg(Ty, RegNum); 2855 Variable *Reg = makeReg(Ty, RegNum);
2843 UnimplementedError(Func->getContext()->getFlags()); 2856 UnimplementedError(Func->getContext()->getFlags());
2844 return Reg; 2857 return Reg;
2845 } 2858 }
2846 2859
2847 // Helper for legalize() to emit the right code to lower an operand to a 2860 // Helper for legalize() to emit the right code to lower an operand to a
2848 // register of the appropriate type. 2861 // register of the appropriate type.
2849 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { 2862 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) {
2850 Type Ty = Src->getType(); 2863 Type Ty = Src->getType();
2851 Variable *Reg = makeReg(Ty, RegNum); 2864 Variable *Reg = makeReg(Ty, RegNum);
2852 if (isVectorType(Ty) || isFloatingType(Ty)) { 2865 if (isVectorType(Ty)) {
2866 // TODO(jpp): Src must be a register, or an address with base register.
2867 _vmov(Reg, Src);
2868 } else if (isFloatingType(Ty)) {
2853 _vmov(Reg, Src); 2869 _vmov(Reg, Src);
2854 } else { 2870 } else {
2855 // Mov's Src operand can really only be the flexible second operand type 2871 // Mov's Src operand can really only be the flexible second operand type
2856 // or a register. Users should guarantee that. 2872 // or a register. Users should guarantee that.
2857 _mov(Reg, Src); 2873 _mov(Reg, Src);
2858 } 2874 }
2859 return Reg; 2875 return Reg;
2860 } 2876 }
2861 2877
2862 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, 2878 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
3205 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 3221 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
3206 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 3222 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
3207 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 3223 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
3208 } 3224 }
3209 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 3225 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
3210 // However, for compatibility with current NaCl LLVM, don't claim that. 3226 // However, for compatibility with current NaCl LLVM, don't claim that.
3211 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 3227 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
3212 } 3228 }
3213 3229
3214 } // end of namespace Ice 3230 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698