Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/lib/Basic/Targets/Sparc.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
PtrDiffType = SignedLong;
break;
}

// The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
// aligned.
LongDoubleWidth = 128;
LongDoubleAlign = 64;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably also need to fix the datalayout

LongDoubleFormat = &llvm::APFloat::IEEEquad();

// Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're
// willing to do atomic ops on up to 64 bits.
MaxAtomicPromoteWidth = 64;
Expand Down
30 changes: 26 additions & 4 deletions clang/lib/CodeGen/Targets/Sparc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,41 @@ class SparcV8ABIInfo : public DefaultABIInfo {

private:
ABIArgInfo classifyReturnType(QualType RetTy) const;
ABIArgInfo classifyArgumentType(QualType Ty) const;
void computeInfo(CGFunctionInfo &FI) const override;
};
} // end anonymous namespace


ABIArgInfo
SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());

if (Ty->isAnyComplexType()) {
return ABIArgInfo::getDirect();
}
else {
return DefaultABIInfo::classifyReturnType(Ty);
auto AI = ABIArgInfo::getDirect();
AI.setInReg(true);
return AI;
}

return DefaultABIInfo::classifyReturnType(Ty);
}

ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
const BuiltinType *BT = Ty->getAs<BuiltinType>();
bool IsF128 = false;

if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
IsF128 = true;

// FIXME not sure if redundant
if (BT && BT->getKind() == BuiltinType::LongDouble)
IsF128 = true;

if (IsF128)
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());

return DefaultABIInfo::classifyArgumentType(Ty);
}

void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -960,9 +960,9 @@ else ()
list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
endif()

# For RISCV32, we must force enable int128 for compiling long
# For RISCV32 and 32-bit SPARC, we must force enable int128 for compiling long
# double routines.
if(COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" STREQUAL "riscv32")
if(COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
list(APPEND BUILTIN_CFLAGS_${arch} -fforce-enable-int128)
endif()

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ foreach(arch ${BUILTIN_TEST_ARCH})
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
endif()

if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR ${arch} STREQUAL "riscv32")
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128)
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
endif()
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/Sparc/SparcCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def CC_Sparc32 : CallingConv<[
// As are v2i32 arguments (this would be the default behavior for
// v2i32 if it wasn't allocated to the IntPair register-class)
CCIfType<[v2i32], CCCustom<"CC_Sparc_Assign_Split_64">>,


// f128 arguments are passed indirectly.
CCIfType<[f128], CCPassIndirect<i32>>,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, am I doing this right @efriedma-quic? The argument to CCPassIndirect is the type of the pointer right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks right, I think.

// Alternatively, they are assigned to the stack in 4-byte aligned units.
CCAssignToStack<4, 4>
]>;
Expand Down
19 changes: 10 additions & 9 deletions llvm/lib/Target/Sparc/SparcISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,20 +554,19 @@ SDValue SparcTargetLowering::LowerFormalArguments_32(
continue;
}

int FI = MF.getFrameInfo().CreateFixedObject(4,
Offset,
true);
SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
SDValue Load ;
int FI;
if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
FI = MF.getFrameInfo().CreateFixedObject(4, Offset, true);
} else if (VA.getValVT() == MVT::f128) {
report_fatal_error("SPARCv8 does not handle f128 in calls; "
"pass indirectly");
FI = MF.getFrameInfo().CreateFixedObject(16, Offset, false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right.

If the value is passed indirectly, that's encoded in VA: call getLocInfo(), check for CCValAssign::Indirect. If it's indirect, the argument is a pointer, so you need to load the pointer, then load the underlying value from that pointer.

} else {
// We shouldn't see any other value types here.
llvm_unreachable("Unexpected ValVT encountered in frame lowering.");
}

SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
SDValue Load =
DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
InVals.push_back(Load);
}

Expand Down Expand Up @@ -913,7 +912,9 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
// Promote the value if needed.
switch (VA.getLocInfo()) {
default: llvm_unreachable("Unknown loc info!");
case CCValAssign::Full: break;
case CCValAssign::Full:
case CCValAssign::Indirect:
break;
case CCValAssign::SExt:
Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
break;
Expand Down
Loading