skan updated this revision to Diff 237245. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72227/new/
https://reviews.llvm.org/D72227 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/x86-malign-branch.c
Index: clang/test/Driver/x86-malign-branch.c =================================================================== --- /dev/null +++ clang/test/Driver/x86-malign-branch.c @@ -0,0 +1,43 @@ +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-boundary=32 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDARY +// CHECK-BOUNDARY: "-mllvm" "-x86-align-branch-boundary=32" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jcc -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JCC +// CHECK-JCC: "-mllvm" "-x86-align-branch=jcc" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-FUSED +// CHECK-FUSED: "-mllvm" "-x86-align-branch=fused" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jmp -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JMP +// CHECK-JMP: "-mllvm" "-x86-align-branch=jmp" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=call -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CALL +// CHECK-CALL: "-mllvm" "-x86-align-branch=call" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=ret -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-RET +// CHECK-RET: "-mllvm" "-x86-align-branch=ret" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-INDIRECT +// CHECK-INDIRECT: "-mllvm" "-x86-align-branch=indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused+jcc+jmp+ret+call+indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BRANCH +// CHECK-BRANCH: "-mllvm" "-x86-align-branch=fused+jcc+jmp+ret+call+indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-prefix-size=4 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-PREFIX +// CHECK-PREFIX: "-mllvm" "-x86-align-branch-prefix-size=4" +// +// RUN: %clang -target x86_64-unknown-unknown -mno-branches-within-32B-boundaries -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL1 +// CHECK-TOTAL1: "-mllvm" "-x86-align-branch-boundary=32" "-mllvm" "-x86-align-branch=fused+jcc+jmp" "-mllvm" "-x86-align-branch-prefix-size=5" +// +// RUN: %clang -target x86_64-unknown-unknown -mbranches-within-32B-boundaries -mno-branches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL2 +// CHECK-TOTAL2-NOT: "-mllvm" "-x86-align-branch-boundary=32" "-mllvm" "-x86-align-branch=fused+jcc+jmp" "-mllvm" "-x86-align-branch-prefix-size=5" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-boundary=7 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jump -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-prefix-size=15 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR +// CHECK-ERROR: error: unsupported argument +// +// RUN: %clang -target aarch64-unknown-unknown -malign-branch-boundary=7 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-WARNING +// RUN: %clang -target aarch64-unknown-unknown -malign-branch=jump -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-WARNING +// RUN: %clang -target aarch64-unknown-unknown -malign-branch-prefix-size=15 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-WARNING +// RUN: %clang -target aarch64-unknown-unknown -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-WARNING +// CHECK-WARNING: warning: argument unused Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -2012,8 +2012,64 @@ CmdArgs.push_back("-mpacked-stack"); } +static void alignBranchesOptions(const Driver &D, const ArgList &Args, + ArgStringList &CmdArgs) { + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) { + StringRef Value = A->getValue(); + uint64_t Num; + if (!Value.getAsInteger(10, Num) && Num >= 32 && llvm::isPowerOf2_64(Num)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-x86-align-branch-boundary=" + Value)); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + } + + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) { + StringRef Value = A->getValue(); + SmallVector<StringRef, 6> BranchTypes; + Value.split(BranchTypes, '+', -1, false); + for (auto BranchType : BranchTypes) { + if (BranchType != "fused" && BranchType != "jcc" && BranchType != "jmp" && + BranchType != "call" && BranchType != "ret" && + BranchType != "indirect") + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-x86-align-branch=" + Value)); + } + + if (const Arg *A = + Args.getLastArg(options::OPT_malign_branch_prefix_size_EQ)) { + StringRef Value = A->getValue(); + uint8_t Num; + if (!Value.getAsInteger(10, Num) && Num <= 5) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-x86-align-branch-prefix-size=" + Value)); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + } + + if (Args.hasFlag(options::OPT_mbranches_within_32B_boundaries, + options::OPT_mno_branches_within_32B_boundaries, false)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-x86-align-branch-boundary=32")); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-x86-align-branch=fused+jcc+jmp")); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-x86-align-branch-prefix-size=5")); + } +} + void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + alignBranchesOptions(getToolChain().getDriver(), Args, CmdArgs); if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || Args.hasArg(options::OPT_mkernel) || Args.hasArg(options::OPT_fapple_kext)) @@ -6436,6 +6492,7 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + alignBranchesOptions(getToolChain().getDriver(), Args, CmdArgs); if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) { StringRef Value = A->getValue(); if (Value == "intel" || Value == "att") { Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2191,6 +2191,49 @@ def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group<clang_ignored_m_Group>; def malign_double : Flag<["-"], "malign-double">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Align doubles to two words in structs (x86 only)">; +def malign_branch_boundary_EQ + : Joined<["-"], "malign-branch-boundary=">, + Group<m_Group>, + Flags<[DriverOption, HelpHidden]>, + HelpText<"Specify the boundary's size to align branches">, DocBrief<[{ + Control how the assembler should align branches with NOP or segment + override prefix. If the boundary's size is not 0, it should be a power + of 2 and no less than 32. Branches will be aligned to prevent from + being across or against the boundary of specified size. The default + value 0 does not align branches.}]>; +def malign_branch_EQ + : Joined<["-"], "malign-branch=">, + Group<m_Group>, + Flags<[DriverOption, HelpHidden]>, + HelpText<"Specify types of branches to align (plus separated list of jcc," + " fused, jmp, call, ret, indirect)">, DocBrief<[{Specify types of branches + to align (plus separated list of types). The branches's types are + combination of jcc, fused, jmp, call, ret, indirect. jcc indicates + conditional jumps, fused indicates fused conditional jumps, jmp indicates + unconditional jumps, call indicates direct and indirect calls, ret + indicates rets, indirect indicates indirect jumps.}]>; +def malign_branch_prefix_size_EQ + : Joined<["-"], "malign-branch-prefix-size=">, + Group<m_Group>, + Flags<[DriverOption, CC1Option, HelpHidden]>, + HelpText<"Specify the maximum number(no more than 5) of prefixes on an " + "instruction to align branches">; +def mbranches_within_32B_boundaries + : Flag<["-"], "mbranches-within-32B-boundaries">, + Group<m_Group>, + Flags<[DriverOption]>, + HelpText< + "Aligns conditional jumps, fused conditional jumps, and unconditional" + " jumps within 32 byte boundary with up to 5 segment prefixes on an " + "instruction">, DocBrief<[{Aligns conditional jumps, fused conditional + jumps, and unconditional jumps within 32 byte boundary with up to 5 + segment prefixes on an instruction. It is equivalent to + -malign-branch-boundary=32, -malign-branch=fused+jcc+jmp, + -malign-branch-prefix-size=5.}]>; +def mno_branches_within_32B_boundaries + : Flag<["-"], "mno-branches-within-32B-boundaries">, + Group<m_Group>, + Flags<[DriverOption]>; def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>, Values<"soft,softfp,hard">; def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>; def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits