diff options
-rw-r--r-- | include/llvm/CodeGen/CallingConvLower.h | 14 | ||||
-rw-r--r-- | lib/CodeGen/CallingConvLower.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 26 |
3 files changed, 38 insertions, 3 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 3afe3095d4..59e7520d24 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -164,6 +164,7 @@ private: SmallVector<uint32_t, 16> UsedRegs; unsigned FirstByValReg; bool FirstByValRegValid; + bool HasByValInRegPosition; // @LOCALMOD -- ARM only: see comment below. protected: ParmContext CallOrPrologue; @@ -311,6 +312,19 @@ public: void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } bool isFirstByValRegValid() const { return FirstByValRegValid; } + // @LOCALMOD-BEGIN + // We disabled the splitting of byval between registers and memory. + // This separate flag indicates that a byval existed. We cannot reuse + // isFirstByValRegValid() because that is already used by the broken + // mechanism of splitting between stack and regs. We should check + // again if this mechanism is still broken later, or try to fix that + // mechanism. + // NOTE: this is only for ARM, so should be refactored. + bool hasByValInRegPosition() const { return HasByValInRegPosition; } + void setHasByValInRegPosition() { HasByValInRegPosition = true; } + void clearHasByValInRegPosition() { HasByValInRegPosition = false; } + // @LOCALMOD-END + ParmContext getCallOrPrologue() const { return CallOrPrologue; } private: diff --git a/lib/CodeGen/CallingConvLower.cpp b/lib/CodeGen/CallingConvLower.cpp index b2c976b2a5..81e237effb 100644 --- a/lib/CodeGen/CallingConvLower.cpp +++ b/lib/CodeGen/CallingConvLower.cpp @@ -33,6 +33,7 @@ CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf, StackOffset = 0; clearFirstByValReg(); + clearHasByValInRegPosition(); // @LOCALMOD. UsedRegs.resize((TRI.getNumRegs()+31)/32); } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 89bed8b823..e1c89e0c42 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1704,10 +1704,22 @@ ARMTargetLowering::HandleByVal(CCState *State, unsigned &size) const { "unhandled ParmContext"); // @LOCALMOD-BEGIN - // This mechanism tries to split a byval argument between registers - // and the stack. It doesn't work correctly yet, so disable it. - // This leaves the entire byval argument on the stack. + // The original mechanism tries to split a byval argument between registers + // and the stack. It doesn't work correctly yet, so disable it. + // This leaves the entire byval argument on the stack, and the rest + // of the parameters will need to be on the stack as well, to have + // the correct order for var-args. We remember the fact that there was + // a byval param that forced this, so that we know not to use the + // handle var-args reg-save area. // PR11018. + if ((!State->isFirstByValRegValid()) && + (ARM::R0 <= reg) && (reg <= ARM::R3)) { + State->setHasByValInRegPosition(); + } + // Confiscate any remaining parameter registers to preclude their + // assignment to subsequent parameters. + while (State->AllocateReg(GPRArgRegs, 4)) + ; return; // @LOCALMOD-END @@ -2740,6 +2752,10 @@ ARMTargetLowering::computeRegArea(CCState &CCInfo, MachineFunction &MF, unsigned NumGPRs; if (CCInfo.isFirstByValRegValid()) NumGPRs = ARM::R4 - CCInfo.getFirstByValReg(); + // @LOCALMOD-BEGIN + else if (CCInfo.hasByValInRegPosition()) + NumGPRs = 0; + // @LOCALMOD-END else { unsigned int firstUnalloced; firstUnalloced = CCInfo.getFirstUnallocated(GPRArgRegs, @@ -2770,6 +2786,10 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG, unsigned firstRegToSaveIndex; if (CCInfo.isFirstByValRegValid()) firstRegToSaveIndex = CCInfo.getFirstByValReg() - ARM::R0; + // @LOCALMOD-BEGIN + else if (CCInfo.hasByValInRegPosition()) + firstRegToSaveIndex = 4; // Nothing to save. + // @LOCALMOD-END else { firstRegToSaveIndex = CCInfo.getFirstUnallocated (GPRArgRegs, sizeof(GPRArgRegs) / sizeof(GPRArgRegs[0])); |