Skip to content

Commit 44e5879

Browse files
committed
AArch64: add arm64_32 support to Clang.
1 parent 77cc246 commit 44e5879

24 files changed

+372
-30
lines changed

clang/lib/Basic/Targets.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
122122
case llvm::Triple::lanai:
123123
return new LanaiTargetInfo(Triple, Opts);
124124

125+
case llvm::Triple::aarch64_32:
126+
if (Triple.isOSDarwin())
127+
return new DarwinAArch64TargetInfo(Triple, Opts);
128+
129+
return nullptr;
125130
case llvm::Triple::aarch64:
126131
if (Triple.isOSDarwin())
127132
return new DarwinAArch64TargetInfo(Triple, Opts);

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
5151
HasLegalHalfType = true;
5252
HasFloat16 = true;
5353

54-
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
54+
if (Triple.isArch64Bit())
55+
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
56+
else
57+
LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
58+
5559
MaxVectorAlign = 128;
5660
MaxAtomicInlineWidth = 128;
5761
MaxAtomicPromoteWidth = 128;
@@ -160,7 +164,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
160164
Builder.defineMacro("__ELF__");
161165

162166
// Target properties.
163-
if (!getTriple().isOSWindows()) {
167+
if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
164168
Builder.defineMacro("_LP64");
165169
Builder.defineMacro("__LP64__");
166170
}
@@ -506,14 +510,19 @@ int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
506510
return -1;
507511
}
508512

513+
bool AArch64TargetInfo::hasInt128Type() const { return true; }
514+
509515
AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
510516
const TargetOptions &Opts)
511517
: AArch64TargetInfo(Triple, Opts) {}
512518

513519
void AArch64leTargetInfo::setDataLayout() {
514-
if (getTriple().isOSBinFormatMachO())
515-
resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
516-
else
520+
if (getTriple().isOSBinFormatMachO()) {
521+
if(getTriple().isArch32Bit())
522+
resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
523+
else
524+
resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
525+
} else
517526
resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
518527
}
519528

@@ -631,19 +640,34 @@ DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
631640
const TargetOptions &Opts)
632641
: DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
633642
Int64Type = SignedLongLong;
643+
if (getTriple().isArch32Bit())
644+
IntMaxType = SignedLongLong;
645+
646+
WCharType = SignedInt;
634647
UseSignedCharForObjCBool = false;
635648

636649
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
637650
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
638651

639-
TheCXXABI.set(TargetCXXABI::iOS64);
652+
UseZeroLengthBitfieldAlignment = false;
653+
654+
if (getTriple().isArch32Bit()) {
655+
UseBitFieldTypeAlignment = false;
656+
ZeroLengthBitfieldBoundary = 32;
657+
UseZeroLengthBitfieldAlignment = true;
658+
TheCXXABI.set(TargetCXXABI::WatchOS);
659+
} else
660+
TheCXXABI.set(TargetCXXABI::iOS64);
640661
}
641662

642663
void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
643664
const llvm::Triple &Triple,
644665
MacroBuilder &Builder) const {
645666
Builder.defineMacro("__AARCH64_SIMD__");
646-
Builder.defineMacro("__ARM64_ARCH_8__");
667+
if (Triple.isArch32Bit())
668+
Builder.defineMacro("__ARM64_ARCH_8_32__");
669+
else
670+
Builder.defineMacro("__ARM64_ARCH_8__");
647671
Builder.defineMacro("__ARM_NEON__");
648672
Builder.defineMacro("__LITTLE_ENDIAN__");
649673
Builder.defineMacro("__REGISTER_PREFIX__", "");

clang/lib/Basic/Targets/AArch64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
9797
}
9898

9999
int getEHDataRegisterNumber(unsigned RegNo) const override;
100+
101+
bool hasInt128Type() const override;
100102
};
101103

102104
class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4238,6 +4238,7 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
42384238
case llvm::Triple::thumbeb:
42394239
return CGF->EmitARMBuiltinExpr(BuiltinID, E, ReturnValue, Arch);
42404240
case llvm::Triple::aarch64:
4241+
case llvm::Triple::aarch64_32:
42414242
case llvm::Triple::aarch64_be:
42424243
return CGF->EmitAArch64BuiltinExpr(BuiltinID, E, Arch);
42434244
case llvm::Triple::bpfeb:
@@ -5670,7 +5671,8 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
56705671
llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
56715672
// TODO: Currently in AArch32 mode the pointer operand comes first, whereas
56725673
// in AArch64 it comes last. We may want to stick to one or another.
5673-
if (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be) {
5674+
if (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be ||
5675+
Arch == llvm::Triple::aarch64_32) {
56745676
llvm::Type *Tys[2] = { VTy, PTy };
56755677
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
56765678
return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "");

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4991,7 +4991,7 @@ class AArch64ABIInfo : public SwiftABIInfo {
49914991
ABIKind getABIKind() const { return Kind; }
49924992
bool isDarwinPCS() const { return Kind == DarwinPCS; }
49934993

4994-
ABIArgInfo classifyReturnType(QualType RetTy) const;
4994+
ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadic) const;
49954995
ABIArgInfo classifyArgumentType(QualType RetTy) const;
49964996
bool isHomogeneousAggregateBaseType(QualType Ty) const override;
49974997
bool isHomogeneousAggregateSmallEnough(const Type *Ty,
@@ -5001,7 +5001,8 @@ class AArch64ABIInfo : public SwiftABIInfo {
50015001

50025002
void computeInfo(CGFunctionInfo &FI) const override {
50035003
if (!::classifyReturnType(getCXXABI(), FI, *this))
5004-
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
5004+
FI.getReturnInfo() =
5005+
classifyReturnType(FI.getReturnType(), FI.isVariadic());
50055006

50065007
for (auto &it : FI.arguments())
50075008
it.info = classifyArgumentType(it.type);
@@ -5184,23 +5185,24 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
51845185
Alignment = getContext().getTypeUnadjustedAlign(Ty);
51855186
Alignment = Alignment < 128 ? 64 : 128;
51865187
} else {
5187-
Alignment = getContext().getTypeAlign(Ty);
5188+
Alignment = std::max(getContext().getTypeAlign(Ty),
5189+
(unsigned)getTarget().getPointerWidth(0));
51885190
}
5189-
Size = llvm::alignTo(Size, 64); // round up to multiple of 8 bytes
5191+
Size = llvm::alignTo(Size, Alignment);
51905192

51915193
// We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
51925194
// For aggregates with 16-byte alignment, we use i128.
5193-
if (Alignment < 128 && Size == 128) {
5194-
llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
5195-
return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64));
5196-
}
5197-
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
5195+
llvm::Type *BaseTy = llvm::Type::getIntNTy(getVMContext(), Alignment);
5196+
return ABIArgInfo::getDirect(
5197+
Size == Alignment ? BaseTy
5198+
: llvm::ArrayType::get(BaseTy, Size / Alignment));
51985199
}
51995200

52005201
return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
52015202
}
52025203

5203-
ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
5204+
ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
5205+
bool IsVariadic) const {
52045206
if (RetTy->isVoidType())
52055207
return ABIArgInfo::getIgnore();
52065208

@@ -5224,7 +5226,9 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
52245226

52255227
const Type *Base = nullptr;
52265228
uint64_t Members = 0;
5227-
if (isHomogeneousAggregate(RetTy, Base, Members))
5229+
if (isHomogeneousAggregate(RetTy, Base, Members) &&
5230+
!(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32 &&
5231+
IsVariadic))
52285232
// Homogeneous Floating-point Aggregates (HFAs) are returned directly.
52295233
return ABIArgInfo::getDirect();
52305234

@@ -5259,6 +5263,14 @@ bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const {
52595263
// NumElements should be power of 2.
52605264
if (!llvm::isPowerOf2_32(NumElements))
52615265
return true;
5266+
5267+
// arm64_32 has to be compatible with the ARM logic here, which allows huge
5268+
// vectors for some reason.
5269+
llvm::Triple Triple = getTarget().getTriple();
5270+
if (Triple.getArch() == llvm::Triple::aarch64_32 &&
5271+
Triple.isOSBinFormatMachO())
5272+
return Size <= 32;
5273+
52625274
return Size != 64 && (Size != 128 || NumElements == 1);
52635275
}
52645276
return false;
@@ -5550,7 +5562,8 @@ Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
55505562
if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
55515563
return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
55525564

5553-
CharUnits SlotSize = CharUnits::fromQuantity(8);
5565+
uint64_t PointerSize = getTarget().getPointerWidth(0) / 8;
5566+
CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
55545567

55555568
// Empty records are ignored for parameter passing purposes.
55565569
if (isEmptyRecord(getContext(), Ty, true)) {
@@ -9773,6 +9786,7 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
97739786
return SetCGInfo(new AVRTargetCodeGenInfo(Types));
97749787

97759788
case llvm::Triple::aarch64:
9789+
case llvm::Triple::aarch64_32:
97769790
case llvm::Triple::aarch64_be: {
97779791
AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
97789792
if (getTarget().getABI() == "darwinpcs")

clang/lib/Driver/ToolChain.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
637637
Triple.setArchName("arm64");
638638
return Triple.getTriple();
639639
}
640+
case llvm::Triple::aarch64_32:
641+
return getTripleString();
640642
case llvm::Triple::arm:
641643
case llvm::Triple::armeb:
642644
case llvm::Triple::thumb:

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
342342
systemz::getSystemZTargetFeatures(Args, Features);
343343
break;
344344
case llvm::Triple::aarch64:
345+
case llvm::Triple::aarch64_32:
345346
case llvm::Triple::aarch64_be:
346347
aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
347348
break;
@@ -1351,6 +1352,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
13511352
return true;
13521353

13531354
case llvm::Triple::aarch64:
1355+
case llvm::Triple::aarch64_32:
13541356
case llvm::Triple::aarch64_be:
13551357
case llvm::Triple::arm:
13561358
case llvm::Triple::armeb:
@@ -1473,6 +1475,7 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
14731475
break;
14741476

14751477
case llvm::Triple::aarch64:
1478+
case llvm::Triple::aarch64_32:
14761479
case llvm::Triple::aarch64_be:
14771480
AddAArch64TargetArgs(Args, CmdArgs);
14781481
CmdArgs.push_back("-fallow-half-arguments-and-returns");
@@ -4032,6 +4035,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40324035
RenderARMABI(Triple, Args, CmdArgs);
40334036
break;
40344037
case llvm::Triple::aarch64:
4038+
case llvm::Triple::aarch64_32:
40354039
case llvm::Triple::aarch64_be:
40364040
RenderAArch64ABI(Triple, Args, CmdArgs);
40374041
break;
@@ -5789,11 +5793,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
57895793
// We only support -moutline in AArch64 right now. If we're not compiling
57905794
// for AArch64, emit a warning and ignore the flag. Otherwise, add the
57915795
// proper mllvm flags.
5792-
if (Triple.getArch() != llvm::Triple::aarch64) {
5796+
if (Triple.getArch() != llvm::Triple::aarch64 &&
5797+
Triple.getArch() != llvm::Triple::aarch64_32) {
57935798
D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
57945799
} else {
5795-
CmdArgs.push_back("-mllvm");
5796-
CmdArgs.push_back("-enable-machine-outliner");
5800+
CmdArgs.push_back("-mllvm");
5801+
CmdArgs.push_back("-enable-machine-outliner");
57975802
}
57985803
} else {
57995804
// Disable all outlining behaviour.

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
253253
return "";
254254

255255
case llvm::Triple::aarch64:
256+
case llvm::Triple::aarch64_32:
256257
case llvm::Triple::aarch64_be:
257258
return aarch64::getAArch64TargetCPU(Args, T, A);
258259

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
5858
.Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
5959
.Cases("armv7s", "xscale", llvm::Triple::arm)
6060
.Case("arm64", llvm::Triple::aarch64)
61+
.Case("arm64_32", llvm::Triple::aarch64_32)
6162
.Case("r600", llvm::Triple::r600)
6263
.Case("amdgcn", llvm::Triple::amdgcn)
6364
.Case("nvptx", llvm::Triple::nvptx)
@@ -832,6 +833,9 @@ StringRef MachO::getMachOArchName(const ArgList &Args) const {
832833
default:
833834
return getDefaultUniversalArchName();
834835

836+
case llvm::Triple::aarch64_32:
837+
return "arm64_32";
838+
835839
case llvm::Triple::aarch64:
836840
return "arm64";
837841

@@ -1640,7 +1644,7 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
16401644
if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
16411645
MachOArchName == "arm64")
16421646
OSTy = llvm::Triple::IOS;
1643-
else if (MachOArchName == "armv7k")
1647+
else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32")
16441648
OSTy = llvm::Triple::WatchOS;
16451649
else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
16461650
MachOArchName != "armv7em")

clang/lib/Sema/SemaChecking.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
15361536
return ExprError();
15371537
break;
15381538
case llvm::Triple::aarch64:
1539+
case llvm::Triple::aarch64_32:
15391540
case llvm::Triple::aarch64_be:
15401541
if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall))
15411542
return ExprError();
@@ -1685,6 +1686,7 @@ bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
16851686

16861687
llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
16871688
bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 ||
1689+
Arch == llvm::Triple::aarch64_32 ||
16881690
Arch == llvm::Triple::aarch64_be;
16891691
bool IsInt64Long =
16901692
Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong;
@@ -5516,7 +5518,8 @@ ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) {
55165518
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {
55175519
const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();
55185520
bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5519-
bool IsAArch64 = TT.getArch() == llvm::Triple::aarch64;
5521+
bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5522+
TT.getArch() == llvm::Triple::aarch64_32);
55205523
bool IsWindows = TT.isOSWindows();
55215524
bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
55225525
if (IsX64 || IsAArch64) {

clang/lib/Sema/SemaType.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7215,6 +7215,7 @@ static bool isPermittedNeonBaseType(QualType &Ty,
72157215
// Signed poly is mathematically wrong, but has been baked into some ABIs by
72167216
// now.
72177217
bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 ||
7218+
Triple.getArch() == llvm::Triple::aarch64_32 ||
72187219
Triple.getArch() == llvm::Triple::aarch64_be;
72197220
if (VecKind == VectorType::NeonPolyVector) {
72207221
if (IsPolyUnsigned) {
@@ -7232,10 +7233,8 @@ static bool isPermittedNeonBaseType(QualType &Ty,
72327233

72337234
// Non-polynomial vector types: the usual suspects are allowed, as well as
72347235
// float64_t on AArch64.
7235-
bool Is64Bit = Triple.getArch() == llvm::Triple::aarch64 ||
7236-
Triple.getArch() == llvm::Triple::aarch64_be;
7237-
7238-
if (Is64Bit && BTy->getKind() == BuiltinType::Double)
7236+
if ((Triple.isArch64Bit() || Triple.getArch() == llvm::Triple::aarch64_32) &&
7237+
BTy->getKind() == BuiltinType::Double)
72397238
return true;
72407239

72417240
return BTy->getKind() == BuiltinType::SChar ||

0 commit comments

Comments
 (0)