diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1b96288ff225892e5ee755fe071ef1db1723f83f..0fe6ba011cf5bd66cc67133bfa988215a5b40f13 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4666,6 +4666,12 @@ def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, def mvzeroupper : Flag<["-"], "mvzeroupper">, Group; def mno_vzeroupper : Flag<["-"], "mno-vzeroupper">, Group; +// OHOS_LOCAL begin +foreach i = {8-15} in + def mfixed_r#i : Flag<["-"], "mfixed-r"#i>, Group, + HelpText<"Reserve the r"#i#" register (x86 only)">; +// OHOS_LOCAL end + // These are legacy user-facing driver-level option spellings. They are always // aliases for options that are spelled using the more common Unix / GNU flag // style of double-dash and equals-joined flags. diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 0f5c366816df9db88b61f0803a5a3acd1ef74c83..9d3e2a2c4bb38d02f785b7ae6c0e4ef0f0e14107 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -341,6 +341,24 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasCRC32 = true; } else if (Feature == "+x87") { HasX87 = true; + // OHOS_LOCAL begin + } else if (Feature == "+fixed-r8") { + ReservedRRegs.insert("r8"); + } else if (Feature == "+fixed-r9") { + ReservedRRegs.insert("r9"); + } else if (Feature == "+fixed-r10") { + ReservedRRegs.insert("r10"); + } else if (Feature == "+fixed-r11") { + ReservedRRegs.insert("r11"); + } else if (Feature == "+fixed-r12") { + ReservedRRegs.insert("r12"); + } else if (Feature == "+fixed-r13") { + ReservedRRegs.insert("r13"); + } else if (Feature == "+fixed-r14") { + ReservedRRegs.insert("r14"); + } else if (Feature == "+fixed-r15") { + ReservedRRegs.insert("r15"); + // OHOS_LOCAL end } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -962,6 +980,16 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("xsavec", true) .Case("xsaves", true) .Case("xsaveopt", true) + // OHOS_LOCAL begin + .Case("fixed-r8", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r9", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r10", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r11", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r12", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r13", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r14", getTriple().getArch() == llvm::Triple::x86_64) + .Case("fixed-r15", getTriple().getArch() == llvm::Triple::x86_64) + // OHOS_LOCAL end .Default(false); } @@ -1061,6 +1089,16 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("xsavec", HasXSAVEC) .Case("xsaves", HasXSAVES) .Case("xsaveopt", HasXSAVEOPT) + // OHOS_LOCAL begin + .Case("fixed-r8", ReservedRRegs.contains("r8")) + .Case("fixed-r9", ReservedRRegs.contains("r9")) + .Case("fixed-r10", ReservedRRegs.contains("r10")) + .Case("fixed-r11", ReservedRRegs.contains("r11")) + .Case("fixed-r12", ReservedRRegs.contains("r12")) + .Case("fixed-r13", ReservedRRegs.contains("r13")) + .Case("fixed-r14", ReservedRRegs.contains("r14")) + .Case("fixed-r15", ReservedRRegs.contains("r15")) + // OHOS_LOCAL end .Default(false); } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 0d5d068741a5d5b7fd689ea93c1a6a66219775bb..ed3fcd5cb6a598b8e67babb4f2fc0e7f64dc0c0b 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -17,6 +17,7 @@ #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/StringSet.h" // OHOS_LOCAL #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/X86TargetParser.h" @@ -153,6 +154,8 @@ protected: enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default; + llvm::StringSet<> ReservedRRegs; // OHOS_LOCAL + public: X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { @@ -769,6 +772,31 @@ public: return true; } + // OHOS_LOCAL begin + // callee saved registers r8-r15 if they are set as reserved + // via -mfixed-r# flag + const StringRef RRegsNames[] = { + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15" + }; + auto IfStartsWith = [RegName](const StringRef str) { + return RegName.startswith(str); + }; + auto End = std::end(RRegsNames); + auto RegIter = std::find_if(std::begin(RRegsNames), End, IfStartsWith); + if (RegIter != E && ReservedRRegs.contains(*RegIter)) { + unsigned ReadedRegSize = + llvm::StringSwitch(RegName.substr(RegIter->size())) + .Case("",64) + .Case("d",32) + .Case("w",16) + .Case("b",8) + .Default(0); + HasSizeMismatch = RegSize != ReadedRegSize; + return true; + } + // OHOS_LOCAL end + // Check if the register is a 32-bit register the backend can handle. return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, HasSizeMismatch); diff --git a/clang/test/CodeGen/X86/fixed-reg-named-reg-global.c b/clang/test/CodeGen/X86/fixed-reg-named-reg-global.c new file mode 100644 index 0000000000000000000000000000000000000000..bc0e1f37d0708475440f151de25fa10e800b6bce --- /dev/null +++ b/clang/test/CodeGen/X86/fixed-reg-named-reg-global.c @@ -0,0 +1,198 @@ +// REQUIRES: x86-registered-target +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r8/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r8 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r8d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r8 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r8w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r8 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r8b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r8 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r9/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r9 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r9d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r9 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r9w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r9 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r9b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r9 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r10/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r10 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r10d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r10 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r10w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r10 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r10b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r10 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r11/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r11 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r11d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r11 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r11w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r11 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r11b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r11 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r12/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r12 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r12d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r12 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r12w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r12 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r12b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r12 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r13/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r13 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r13d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r13 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r13w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r13 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r13b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r13 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r14/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r14 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r14d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r14 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r14w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r14 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r14b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r14 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + + +// RUN: sed 's/_TYPE_/uint64_t/g;s/_REG_/r15/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r15 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint32_t/g;s/_REG_/r15d/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r15 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint16_t/g;s/_REG_/r15w/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r15 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +// RUN: sed 's/_TYPE_/uint8_t/g;s/_REG_/r15b/g' %s > %t +// RUN: %clang -x c - < %t -O0 2> %t1 || echo +// RUN: FileCheck < %t1 %t +// RUN: %clang -x c - < %t -mfixed-r15 -O0 -S -emit-llvm -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +#include + +// CHECK: error: +// CHECK-SAME: register '_REG_' unsuitable for global register variables on this target +// CHECK-HAVE-RESERVATION-NOT: @_REG_ = common global +register _TYPE_ R asm("_REG_"); + +// CHECK-HAVE-RESERVATION: define{{.*}} i[[bits:[0-9]+]] @get_register_value +// CHECK-HAVE-RESERVATION: [[ret:%[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0) +// CHECK-HAVE-RESERVATION: ret i[[bits]] [[ret]] +_TYPE_ get_register_value() { + return R; +} +// CHECK-HAVE-RESERVATION: declare{{.*}} i[[bits]] @llvm.read_register.i[[bits]](metadata) + + +// CHECK-HAVE-RESERVATION: define{{.*}} void @set_register_value +// CHECK-HAVE-RESERVATION: [[sto:%[0-9]+]] = load i[[bits]], ptr % +// CHECK-HAVE-RESERVATION: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] [[sto]]) +// CHECK-HAVE-RESERVATION: ret void +void set_register_value(_TYPE_ value) { + R = value; +} +// CHECK-HAVE-RESERVATION: declare{{.*}} void @llvm.write_register.i[[bits]](metadata, i[[bits]]) + +int main() { + set_register_value(1); + int res = get_register_value(); + set_register_value(2); + return res; +} + +// CHECK-HAVE-RESERVATION: !llvm.named.register._REG_ = !{!0} +// CHECK-HAVE-RESERVATION: !0 = !{!"_REG_"} diff --git a/clang/test/Driver/x86_64-fixed-r-register.c b/clang/test/Driver/x86_64-fixed-r-register.c new file mode 100644 index 0000000000000000000000000000000000000000..7b1e876304e08d3c499f607543f6b8a482297c96 --- /dev/null +++ b/clang/test/Driver/x86_64-fixed-r-register.c @@ -0,0 +1,64 @@ +// RUN: %clang %s -mfixed-r8 -### 2>&1 | FileCheck %s --check-prefix=R8 +// RUN: %clang %s -mfixed-r9 -### 2>&1 | FileCheck %s --check-prefix=R9 +// RUN: %clang %s -mfixed-r10 -### 2>&1 | FileCheck %s --check-prefix=R10 +// RUN: %clang %s -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R11 +// RUN: %clang %s -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R12 +// RUN: %clang %s -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R13 +// RUN: %clang %s -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R14 +// RUN: %clang %s -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R15 + +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 +// RUN: %clang %s -mfixed-r8 -mfixed-r10 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R10 +// RUN: %clang %s -mfixed-r8 -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R11 +// RUN: %clang %s -mfixed-r8 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R12 +// RUN: %clang %s -mfixed-r8 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R13 +// RUN: %clang %s -mfixed-r8 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R14 +// RUN: %clang %s -mfixed-r8 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R15 +// RUN: %clang %s -mfixed-r9 -mfixed-r10 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R10 +// RUN: %clang %s -mfixed-r9 -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R11 +// RUN: %clang %s -mfixed-r9 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R12 +// RUN: %clang %s -mfixed-r9 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R13 +// RUN: %clang %s -mfixed-r9 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R14 +// RUN: %clang %s -mfixed-r9 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R15 +// RUN: %clang %s -mfixed-r10 -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R11 +// RUN: %clang %s -mfixed-r10 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R12 +// RUN: %clang %s -mfixed-r10 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R13 +// RUN: %clang %s -mfixed-r10 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R14 +// RUN: %clang %s -mfixed-r10 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R15 +// RUN: %clang %s -mfixed-r11 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R12 +// RUN: %clang %s -mfixed-r11 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R13 +// RUN: %clang %s -mfixed-r11 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R14 +// RUN: %clang %s -mfixed-r11 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R15 +// RUN: %clang %s -mfixed-r12 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R12 --check-prefix=R13 +// RUN: %clang %s -mfixed-r12 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R12 --check-prefix=R14 +// RUN: %clang %s -mfixed-r12 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R12 --check-prefix=R15 +// RUN: %clang %s -mfixed-r13 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R13 --check-prefix=R14 +// RUN: %clang %s -mfixed-r13 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R13 --check-prefix=R15 +// RUN: %clang %s -mfixed-r14 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R14 --check-prefix=R15 + +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 +// RUN: %clang %s -mfixed-r9 -mfixed-r10 -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 +// RUN: %clang %s -mfixed-r10 -mfixed-r11 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 +// RUN: %clang %s -mfixed-r11 -mfixed-r12 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 +// RUN: %clang %s -mfixed-r12 -mfixed-r13 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R12 --check-prefix=R13 --check-prefix=R14 +// RUN: %clang %s -mfixed-r13 -mfixed-r14 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R13 --check-prefix=R14 --check-prefix=R15 + +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -mfixed-r11 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 +// RUN: %clang %s -mfixed-r9 -mfixed-r10 -mfixed-r11 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 +// RUN: %clang %s -mfixed-r10 -mfixed-r11 -mfixed-r12 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 +// RUN: %clang %s -mfixed-r11 -mfixed-r12 -mfixed-r13 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 --check-prefix=R14 +// RUN: %clang %s -mfixed-r12 -mfixed-r13 -mfixed-r14 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R12 --check-prefix=R13 --check-prefix=R14 --check-prefix=R15 + +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -mfixed-r11 -mfixed-r12 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -mfixed-r11 -mfixed-r12 -mfixed-r13 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -mfixed-r11 -mfixed-r12 -mfixed-r13 -mfixed-r14 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 --check-prefix=R14 +// RUN: %clang %s -mfixed-r8 -mfixed-r9 -mfixed-r10 -mfixed-r11 -mfixed-r12 -mfixed-r13 -mfixed-r14 -mfixed-r15 -### 2>&1 | FileCheck %s --check-prefix=R8 --check-prefix=R9 --check-prefix=R10 --check-prefix=R11 --check-prefix=R12 --check-prefix=R13 --check-prefix=R14 --check-prefix=R15 + +// R8-NOT: error: +// R9-NOT: error: +// R10-NOT: error: +// R11-NOT: error: +// R12-NOT: error: +// R13-NOT: error: +// R14-NOT: error: +// R15-NOT: error: diff --git a/llvm/docs/BitCodeFormat.rst b/llvm/docs/BitCodeFormat.rst index d581e18d6daaa2a1b31ce16aa350ac36d0f1a19b..50c5bf88ec13042745ac75c6ef65fc9166d0dd1c 100644 --- a/llvm/docs/BitCodeFormat.rst +++ b/llvm/docs/BitCodeFormat.rst @@ -799,6 +799,18 @@ function. The operand fields are: * ``tailcc`` : code 18 * ``cfguard_checkcc`` : code 19 * ``swifttailcc`` : code 20 +.. OHOS_LOCAL begin + * ``arkintcc`` : code 21 + * ``arkfast0cc`` : code 22 + * ``arkfast1cc`` : code 23 + * ``arkfast2cc`` : code 24 + * ``arkfast3cc`` : code 25 + * ``arkfast4cc`` : code 26 + * ``arkfast5cc`` : code 27 + * ``arkmethodcc`` : code 28 + * ``arkresolvercc`` : code 29 + * ``arkpltcc`` : code 30 +.. OHOS_LOCAL end * ``x86_stdcallcc``: code 64 * ``x86_fastcallcc``: code 65 * ``arm_apcscc``: code 66 diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index bc1f63f272f3de8e288e74f4b4e32268abbf54e5..e2c7f7d80a834a1919fe2b07771a1e2667ae5805 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -456,6 +456,31 @@ added in the future: - On X86 the target address is passed in ECX. - On ARM the target address is passed in R0. - On AArch64 the target address is passed in X15. +.. OHOS_LOCAL begin +"``arkintcc``" + Ark Irtoc calling convention for Interpreter handlers +"``arkfast0cc``" + Ark Irtoc calling convention for void-return FastPath handlers with zero + arguments +"``arkfast1cc``" + Ark Irtoc calling convention for FastPath handlers with one argument or + no arguments but having a return value +"``arkfast2cc``" + Ark Itroc calling convention for FastPath handlers with two arguments +"``arkfast3cc``" + Ark Itroc calling convention for FastPath handlers with three arguments +"``arkfast4cc``" + Ark Itroc calling convention for FastPath handlers with four arguments +"``arkfast5cc``" + Ark Itroc calling convention for FastPath handlers with five arguments +"``arkmethodcc``" + Ark AOT method calling convention with frame adaptation +"``arkresolvercc``" + Ark AOT calling convention for special class resolvers +"``arkpltcc``" + Ark AOT calling convention for static calls through special PLT resolver +.. OHOS_LOCAL end + "``cc ``" - Numbered convention Any calling convention may be specified by number, allowing target-specific calling conventions to be used. Target specific diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index 04235f0fdc4ef59d03c21b8724a0b9769a728202..a0cb5168ed716d0415f5574e7aff1cece1de5bac 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -171,6 +171,18 @@ enum Kind { kw_amdgpu_kernel, kw_amdgpu_gfx, kw_tailcc, + // OHOS_LOCAL begin + kw_arkintcc, + kw_arkfast0cc, + kw_arkfast1cc, + kw_arkfast2cc, + kw_arkfast3cc, + kw_arkfast4cc, + kw_arkfast5cc, + kw_arkmethodcc, + kw_arkresolvercc, + kw_arkpltcc, + // OHOS_LOCAL end // Attributes: kw_attributes, diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h index 9a8bc4bd517ab8a8cd294a507bc8c321786321b1..46526277448f9bd075035864439d1b2958f4e4c2 100644 --- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h +++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/StackProtectorRetLowering.h" #include "llvm/Support/TypeSize.h" +#include "llvm/IR/CallingConv.h" // OHOS_LOCAL #include namespace llvm { @@ -138,7 +139,11 @@ public: /// getOffsetOfLocalArea - This method returns the offset of the local area /// from the stack pointer on entrance to a function. /// - int getOffsetOfLocalArea() const { return LocalAreaOffset; } + // OHOS_LOCAL begin + virtual int getOffsetOfLocalArea(CallingConv::ID CC = CallingConv::C) const { + return LocalAreaOffset; + } + // OHOS_LOCAL end /// Control the placement of special register scavenging spill slots when /// allocating a stack frame. diff --git a/llvm/include/llvm/IR/CallingConv.h b/llvm/include/llvm/IR/CallingConv.h index fd28542465225c0087dc009c12bb7aaa700fc9d4..3221e5c9541d6e8c7d19d89829288f9053a63c3c 100644 --- a/llvm/include/llvm/IR/CallingConv.h +++ b/llvm/include/llvm/IR/CallingConv.h @@ -91,6 +91,40 @@ namespace CallingConv { /// clean up their stack. SwiftTail = 20, + // OHOS_LOCAL begin + // Ark Irtoc calling convention for Interpreter handlers + ArkInt = 21, + + // Ark Irtoc calling convention for void-return FastPath handlers with + // zero arguments + ArkFast0 = 22, + + // Ark Irtoc calling convention for FastPath handlers with one argument or + // no arguments but having a return value + ArkFast1 = 23, + + // Ark Itroc calling convention for FastPath handlers with two arguments + ArkFast2 = 24, + + // Ark Itroc calling convention for FastPath handlers with three arguments + ArkFast3 = 25, + + // Ark Itroc calling convention for FastPath handlers with four arguments + ArkFast4 = 26, + + // Ark Itroc calling convention for FastPath handlers with five arguments + ArkFast5 = 27, + + // Ark AOT method calling convention with frame adaptation + ArkMethod = 28, + + // Ark AOT calling convention for special class resolvers + ArkResolver = 29, + + // Ark AOT calling convention for static calls through special PLT resolver + ArkPlt = 30, + // OHOS_LOCAL end + // Target - This is the start of the target-specific calling conventions, // e.g. fastcall and thiscall on X86. FirstTargetCC = 64, diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index 91712df153a0b5617742ba631e4680f80ea656d4..35cd963f61f786d7282f7b74ab206c58d75efc95 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -73,6 +73,8 @@ public: LLVMContext &operator=(const LLVMContext &) = delete; ~LLVMContext(); + static const char *getLLVMVersion(); // OHOS_LOCAL + // Pinned metadata names, which always have the same value. This is a // compile-time performance optimization, not a correctness optimization. enum : unsigned { diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 569ee6b3ea86cb81516d1dff511f50fcfb1c5865..342277aeeead7fded7f1ebf9d6c51fdd12f000ae 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6058,6 +6058,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, unsigned Depth) { + bool HasMismatchedZeros = false; if (CmpInst::isFPPredicate(Pred)) { // IEEE-754 ignores the sign of 0.0 in comparisons. So if the select has one // 0.0 operand, set the compare's 0.0 operands to that same value for the @@ -6072,10 +6073,14 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, OutputZeroVal = FalseVal; if (OutputZeroVal) { - if (match(CmpLHS, m_AnyZeroFP())) + if (match(CmpLHS, m_AnyZeroFP()) && CmpLHS != OutputZeroVal) { + HasMismatchedZeros = true; CmpLHS = OutputZeroVal; - if (match(CmpRHS, m_AnyZeroFP())) + } + if (match(CmpRHS, m_AnyZeroFP()) && CmpRHS != OutputZeroVal) { + HasMismatchedZeros = true; CmpRHS = OutputZeroVal; + } } } @@ -6089,7 +6094,11 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, // operands is known to not be zero or if we don't care about signed zero. switch (Pred) { default: break; - // FIXME: Include OGT/OLT/UGT/ULT. + case CmpInst::FCMP_OGT: case CmpInst::FCMP_OLT: + case CmpInst::FCMP_UGT: case CmpInst::FCMP_ULT: + if (!HasMismatchedZeros) + break; + LLVM_FALLTHROUGH; // OHOS_LOCAL case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLE: case CmpInst::FCMP_UGE: case CmpInst::FCMP_ULE: if (!FMF.noSignedZeros() && !isKnownNonZero(CmpLHS) && diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index c9a982693fa75b93a430eff33a2e605d1690bb17..a77f77c8e91ea0d3dd2970087262345f0cf4398c 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -629,6 +629,18 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(amdgpu_kernel); KEYWORD(amdgpu_gfx); KEYWORD(tailcc); + // OHOS_LOCAL begin + KEYWORD(arkintcc); + KEYWORD(arkfast0cc); + KEYWORD(arkfast1cc); + KEYWORD(arkfast2cc); + KEYWORD(arkfast3cc); + KEYWORD(arkfast4cc); + KEYWORD(arkfast5cc); + KEYWORD(arkmethodcc); + KEYWORD(arkresolvercc); + KEYWORD(arkpltcc); + // OHOS_LOCAL end KEYWORD(cc); KEYWORD(c); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fd502eded0a0499e567d4afc21ee3ce2b3b94a1f..6f270e0db471d82dd3677e8ac60cfc6cc54cef26 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1904,6 +1904,18 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'amdgpu_cs' /// ::= 'amdgpu_kernel' /// ::= 'tailcc' +// OHOS_LOCAL begin +/// ::= 'arkintcc' +/// ::= 'arkfast0cc' +/// ::= 'arkfast1cc' +/// ::= 'arkfast2cc' +/// ::= 'arkfast3cc' +/// ::= 'arkfast4cc' +/// ::= 'arkfast5cc' +/// ::= 'arkmethodcc' +/// ::= 'arkresolvercc' +/// ::= 'arkpltcc' +// OHOS_LOCAL end /// ::= 'cc' UINT /// bool LLParser::parseOptionalCallingConv(unsigned &CC) { @@ -1956,6 +1968,18 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) { case lltok::kw_amdgpu_cs: CC = CallingConv::AMDGPU_CS; break; case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break; case lltok::kw_tailcc: CC = CallingConv::Tail; break; + // OHOS_LOCAL begin + case lltok::kw_arkintcc: CC = CallingConv::ArkInt; break; + case lltok::kw_arkfast0cc: CC = CallingConv::ArkFast0; break; + case lltok::kw_arkfast1cc: CC = CallingConv::ArkFast1; break; + case lltok::kw_arkfast2cc: CC = CallingConv::ArkFast2; break; + case lltok::kw_arkfast3cc: CC = CallingConv::ArkFast3; break; + case lltok::kw_arkfast4cc: CC = CallingConv::ArkFast4; break; + case lltok::kw_arkfast5cc: CC = CallingConv::ArkFast5; break; + case lltok::kw_arkmethodcc: CC = CallingConv::ArkMethod; break; + case lltok::kw_arkresolvercc: CC = CallingConv::ArkResolver; break; + case lltok::kw_arkpltcc: CC = CallingConv::ArkPlt; break; + // OHOS_LOCAL end case lltok::kw_cc: { Lex.Lex(); return parseUInt32(CC); diff --git a/llvm/lib/CodeGen/MachineFrameInfo.cpp b/llvm/lib/CodeGen/MachineFrameInfo.cpp index f0190812389f95fa8abe0e43c9dcc167ad9fdd77..eb4a48bac48c14cdf52f8bd3ca3f02b77d061064 100644 --- a/llvm/lib/CodeGen/MachineFrameInfo.cpp +++ b/llvm/lib/CodeGen/MachineFrameInfo.cpp @@ -213,7 +213,10 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ if (Objects.empty()) return; const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering(); - int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0); + // OHOS_LOCAL begin + auto CC = MF.getFunction().getCallingConv(); + int ValOffset = (FI ? FI->getOffsetOfLocalArea(CC) : 0); + // OHOS_LOCAL end OS << "Frame Objects:\n"; diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 2d831819791ef0d08d3770f6d3cbf7d76cbc1835..a1ef8bb320a81265a45b9cdd6540653412978a31 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -842,7 +842,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { // Start at the beginning of the local area. // The Offset is the distance from the stack top in the direction // of stack growth -- so it's always nonnegative. - int LocalAreaOffset = TFI.getOffsetOfLocalArea(); + // OHOS_LOCAL begin + auto CC = MF.getFunction().getCallingConv(); + int LocalAreaOffset = TFI.getOffsetOfLocalArea(CC); + // OHOS_LOCAL end + if (StackGrowsDown) LocalAreaOffset = -LocalAreaOffset; assert(LocalAreaOffset >= 0 diff --git a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp index 9430e86fe44d86e60c54e530ca5b41911a32224a..0007c44b859ca2c94c3ac8c79b8bcb723e71e890 100644 --- a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp +++ b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -57,9 +57,11 @@ TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, // something different. FrameReg = RI->getFrameRegister(MF); + // OHOS_LOCAL begin return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() - - getOffsetOfLocalArea() + + getOffsetOfLocalArea(MF.getFunction().getCallingConv()) + MFI.getOffsetAdjustment()); + // OHOS_LOCAL end } bool TargetFrameLowering::needsFrameIndexResolution( diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index a29040b8c2aa190961e2fd66b95e012ff97ab9c0..4244de9755f878730a33785be43e0dbdd5c5d228 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -297,6 +297,18 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break; case CallingConv::GHC: Out << "ghccc"; break; case CallingConv::Tail: Out << "tailcc"; break; + // OHOS_LOCAL begin + case CallingConv::ArkInt: Out << "arkintcc"; break; + case CallingConv::ArkFast0: Out << "arkfast0cc"; break; + case CallingConv::ArkFast1: Out << "arkfast1cc"; break; + case CallingConv::ArkFast2: Out << "arkfast2cc"; break; + case CallingConv::ArkFast3: Out << "arkfast3cc"; break; + case CallingConv::ArkFast4: Out << "arkfast4cc"; break; + case CallingConv::ArkFast5: Out << "arkfast5cc"; break; + case CallingConv::ArkMethod: Out << "arkmethod"; break; + case CallingConv::ArkResolver: Out << "arkresolvercc"; break; + case CallingConv::ArkPlt: Out << "arkpltcc"; break; + // OHOS_LOCAL end case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break; case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break; case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break; diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 4a1d5d3dcdf6631012761596840545ad157c812b..bf1a809e56336b106b956cf1063ee179c2f61d3e 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -31,6 +31,12 @@ using namespace llvm; +// OHOS_LOCAL begin +const char *LLVMContext::getLLVMVersion() { + return LLVM_VERSION_STRING; +} +// OHOS_LOCAL end + LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { // Create the fixed metadata kinds. This is done in the same order as the // MD_* enum values so that they correspond. diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 8fb5d49e2121f638487a1256231d1d6a80adacbe..1812e1c317a80fa6816f6d87ca8ca4673b625115 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -180,7 +180,7 @@ def FeatureStrictAlign : SubtargetFeature<"strict-align", "Disallow all unaligned memory " "access">; -foreach i = {1-7,9-15,18,20-28,30} in +foreach i = {1-7,9-15,18,20-30} in // OHOS_LOCAL def FeatureReserveX#i : SubtargetFeature<"reserve-x"#i, "ReserveXRegister["#i#"]", "true", "Reserve X"#i#", making it unavailable " "as a GPR">; diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.h b/llvm/lib/Target/AArch64/AArch64CallingConvention.h index 59939e0684ed2cc75d2752f6adc9f9cae8289625..90e8be6eeee02a6cab6c72f11c4955bf0b499944 100644 --- a/llvm/lib/Target/AArch64/AArch64CallingConvention.h +++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.h @@ -37,6 +37,32 @@ bool CC_AArch64_Win64_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, bool CC_AArch64_WebKit_JS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State); +// OHOS_LOCAL begin +bool CC_AArch64_ArkInt(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkResolver(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State); +bool CC_AArch64_ArkFast0(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkFast1(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkFast2(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkFast3(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkFast4(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +bool CC_AArch64_ArkFast5(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); +// OHOS_LOCAL end bool CC_AArch64_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State); @@ -46,6 +72,11 @@ bool RetCC_AArch64_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, bool RetCC_AArch64_WebKit_JS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State); +// OHOS_LOCAL begin +bool RetCC_AArch64_ArkResolver(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State); +// OHOS_LOCAL end } // namespace llvm #endif diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td index c0da242a26de8cb1f3b1a37198fc0ce28fc5a1a4..dbc5b5eb2218b3567778db4d9650506b4d840673 100644 --- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td +++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td @@ -304,6 +304,72 @@ def RetCC_AArch64_WebKit_JS : CallingConv<[ CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>> ]>; +// OHOS_LOCAL begin +// Ark Conventions +let Entry = 1 in +def CC_AArch64_ArkInt : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W20, W21, W22, W23, W24, W25, W26, W28], [X20, X21, X22, X23, X24, X25, X26, X28]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X20, X21, X22, X23, X24, X25, X26, X28], [W20, W21, W22, W23, W24, W25, W26, W28]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast0 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W28, W29], [X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X28, FP], [W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast1 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W0, W28, W29], [X0, X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X0, X28, FP], [W0, W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast2 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W28, W29], [X0, X1, X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X28, FP], [W0, W1, W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast3 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W28, W29], [X0, X1, X2, X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X28, FP], [W0, W1, W2, W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast4 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W28, W29], [X0, X1, X2, X3, X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X28, FP], [W0, W1, W2, W3, W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkFast5 : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W28, W29], [X0, X1, X2, X3, X4, X28, FP]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X28, FP], [W0, W1, W2, W3, W4, W28, W29]>>, +]>; + +let Entry = 1 in +def CC_AArch64_ArkResolver : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W16], [X16]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X16], [W16]>>, +]>; + +let Entry = 1 in +def RetCC_AArch64_ArkResolver : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToRegWithShadow<[W16], [X16]>>, + CCIfType<[i64], CCAssignToRegWithShadow<[X16], [W16]>>, +]>; +// OHOS_LOCAL end + //===----------------------------------------------------------------------===// // ARM64 Calling Convention for GHC //===----------------------------------------------------------------------===// @@ -434,6 +500,30 @@ def CSR_AArch64_StackProbe_Windows (sequence "X%u", 18, 28), FP, SP, (sequence "Q%u", 0, 31))>; +// OHOS_LOCAL begin +def CSR_AArch64_ArkInt : CalleeSavedRegs<(add FP)>; + +def CSR_AArch64_ArkFast5 + : CalleeSavedRegs<(add (sub (sequence "X%u", 5, 27), X16, X17), LR, + (sequence "D%u", 0, 31))>; +def CSR_AArch64_ArkFast4 + : CalleeSavedRegs<(add CSR_AArch64_ArkFast5, X4)>; + +def CSR_AArch64_ArkFast3 + : CalleeSavedRegs<(add CSR_AArch64_ArkFast4, X3)>; + +def CSR_AArch64_ArkFast2 + : CalleeSavedRegs<(add CSR_AArch64_ArkFast3, X2)>; + +def CSR_AArch64_ArkFast1 + : CalleeSavedRegs<(add CSR_AArch64_ArkFast2, X1)>; + +def CSR_AArch64_ArkFast0 + : CalleeSavedRegs<(add CSR_AArch64_ArkFast1, X0)>; + +def CSR_AArch64_ArkMethod : CalleeSavedRegs<(add LR, FP)>; +// OHOS_LOCAL end + // Darwin variants of AAPCS. // Darwin puts the frame-record at the top of the callee-save area. def CSR_Darwin_AArch64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22, diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 49fffa01a974d611ef713694dbe78eec1b9bdd68..6aa0e45eac67f2b1515dd68f49c2e8c7b865e6e0 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -3786,8 +3786,20 @@ bool AArch64FastISel::selectRet(const Instruction *I) { // Analyze operands of the call, assigning locations to each operand. SmallVector ValLocs; CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, I->getContext()); - CCAssignFn *RetCC = CC == CallingConv::WebKit_JS ? RetCC_AArch64_WebKit_JS - : RetCC_AArch64_AAPCS; + // OHOS_LOCAL begin + CCAssignFn *RetCC; + switch (CC) { + default: + RetCC = RetCC_AArch64_AAPCS; + break; + case CallingConv::WebKit_JS: + RetCC = RetCC_AArch64_WebKit_JS; + break; + case CallingConv::ArkResolver: + RetCC = RetCC_AArch64_ArkResolver; + break; + } + // OHOS_LOCAL end CCInfo.AnalyzeReturn(Outs, RetCC); // Only handle a single return value for now. diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index a7a1c969faf5e7d11c7d27b3bf639ff1d840e27f..6042de60bb70704bee174de2e44581796a00be28 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1185,12 +1185,16 @@ static MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec( MachineFunction &MF = *MBB.getParent(); if (MBBI->getOperand(MBBI->getNumOperands() - 1).getImm() != 0 || CSStackSizeInc < MinOffset || CSStackSizeInc > MaxOffset) { - emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, + // OHOS_LOCAL begin + MachineBasicBlock::iterator MBBIn = + FrameFlag == MachineInstr::FrameDestroy ? std::next(MBBI) : MBBI; + emitFrameOffset(MBB, MBBIn, DL, AArch64::SP, AArch64::SP, StackOffset::getFixed(CSStackSizeInc), TII, FrameFlag, false, false, nullptr, EmitCFI, StackOffset::getFixed(CFAOffset)); - return std::prev(MBBI); + return std::prev(MBBIn); + // OHOS_LOCAL end } MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc)); @@ -1473,6 +1477,18 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, if (MF.getFunction().getCallingConv() == CallingConv::GHC) return; + // OHOS_LOCAL begin + if (HasFP && (MF.getFunction().getCallingConv() == CallingConv::ArkFast0 || + MF.getFunction().getCallingConv() == CallingConv::ArkFast1 || + MF.getFunction().getCallingConv() == CallingConv::ArkFast2 || + MF.getFunction().getCallingConv() == CallingConv::ArkFast3 || + MF.getFunction().getCallingConv() == CallingConv::ArkFast4 || + MF.getFunction().getCallingConv() == CallingConv::ArkFast5)) { + report_fatal_error( + "Implicit use of FP is forbidden for ArkFast conventions!"); + } + // OHOS_LOCAL end + // Set tagged base pointer to the requested stack slot. // Ideally it should match SP value after prologue. Optional TBPI = AFI->getTaggedBasePointerIndex(); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 06e21f90ebf13ddc0bafbc43041b3f96dc455700..7c5b5251aed33e833d999ed0053cf90fb74733aa 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5726,6 +5726,7 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC, case CallingConv::Swift: case CallingConv::SwiftTail: case CallingConv::Tail: + case CallingConv::ArkMethod: // OHOS_LOCAL if (Subtarget->isTargetWindows() && IsVarArg) return CC_AArch64_Win64_VarArg; if (!Subtarget->isTargetDarwin()) @@ -5734,6 +5735,24 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC, return CC_AArch64_DarwinPCS; return Subtarget->isTargetILP32() ? CC_AArch64_DarwinPCS_ILP32_VarArg : CC_AArch64_DarwinPCS_VarArg; + // OHOS_LOCAL begin + case CallingConv::ArkInt: + return CC_AArch64_ArkInt; + case CallingConv::ArkFast0: + return CC_AArch64_ArkFast0; + case CallingConv::ArkFast1: + return CC_AArch64_ArkFast1; + case CallingConv::ArkFast2: + return CC_AArch64_ArkFast2; + case CallingConv::ArkFast3: + return CC_AArch64_ArkFast3; + case CallingConv::ArkFast4: + return CC_AArch64_ArkFast4; + case CallingConv::ArkFast5: + return CC_AArch64_ArkFast5; + case CallingConv::ArkResolver: + return CC_AArch64_ArkResolver; + // OHOS_LOCAL end case CallingConv::Win64: return IsVarArg ? CC_AArch64_Win64_VarArg : CC_AArch64_AAPCS; case CallingConv::CFGuard_Check: @@ -5746,8 +5765,16 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC, CCAssignFn * AArch64TargetLowering::CCAssignFnForReturn(CallingConv::ID CC) const { - return CC == CallingConv::WebKit_JS ? RetCC_AArch64_WebKit_JS - : RetCC_AArch64_AAPCS; + // OHOS_LOCAL begin + switch (CC) { + case CallingConv::WebKit_JS: + return RetCC_AArch64_WebKit_JS; + case CallingConv::ArkResolver: + return RetCC_AArch64_ArkResolver; + default: + return RetCC_AArch64_AAPCS; + } + // OHOS_LOCAL end } SDValue AArch64TargetLowering::LowerFormalArguments( @@ -6226,6 +6253,15 @@ static bool mayTailCallThisCC(CallingConv::ID CC) { case CallingConv::SwiftTail: case CallingConv::Tail: case CallingConv::Fast: + // OHOS_LOCAL begin + case CallingConv::ArkInt: + case CallingConv::ArkFast0: + case CallingConv::ArkFast1: + case CallingConv::ArkFast2: + case CallingConv::ArkFast3: + case CallingConv::ArkFast4: + case CallingConv::ArkFast5: + // OHOS_LOCAL end return true; default: return false; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index f7c06b9fb71b324ee732262579ffc6576f5282a7..95294679f3eed1a5a4a3a03af67eacd1b7c1565b 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -74,6 +74,24 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { // GHC set of callee saved regs is empty as all those regs are // used for passing STG regs around return CSR_AArch64_NoRegs_SaveList; + // OHOS_LOCAL begin + if (MF->getFunction().getCallingConv() == CallingConv::ArkInt) + return CSR_AArch64_ArkInt_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast0) + return CSR_AArch64_ArkFast0_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast1) + return CSR_AArch64_ArkFast1_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast2) + return CSR_AArch64_ArkFast2_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast3) + return CSR_AArch64_ArkFast3_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast4) + return CSR_AArch64_ArkFast4_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkFast5) + return CSR_AArch64_ArkFast5_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::ArkMethod) + return CSR_AArch64_ArkMethod_SaveList; + // OHOS_LOCAL end if (MF->getFunction().getCallingConv() == CallingConv::AnyReg) return CSR_AArch64_AllRegs_SaveList; @@ -212,6 +230,24 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF, if (CC == CallingConv::GHC) // This is academic because all GHC calls are (supposed to be) tail calls return SCS ? CSR_AArch64_NoRegs_SCS_RegMask : CSR_AArch64_NoRegs_RegMask; + // OHOS_LOCAL begin + if (CC == CallingConv::ArkInt) + return CSR_AArch64_ArkInt_RegMask; + if (CC == CallingConv::ArkFast0) + return CSR_AArch64_ArkFast0_RegMask; + if (CC == CallingConv::ArkFast1) + return CSR_AArch64_ArkFast1_RegMask; + if (CC == CallingConv::ArkFast2) + return CSR_AArch64_ArkFast2_RegMask; + if (CC == CallingConv::ArkFast3) + return CSR_AArch64_ArkFast3_RegMask; + if (CC == CallingConv::ArkFast4) + return CSR_AArch64_ArkFast4_RegMask; + if (CC == CallingConv::ArkFast5) + return CSR_AArch64_ArkFast5_RegMask; + if (CC == CallingConv::ArkMethod) + return CSR_AArch64_ArkMethod_RegMask; + // OHOS_LOCAL end if (CC == CallingConv::AnyReg) return SCS ? CSR_AArch64_AllRegs_SCS_RegMask : CSR_AArch64_AllRegs_RegMask; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index aaef363e9b8dcb3de0706915d57b95ae7e78a5da..48277a8504115d0c5d02c27c095d8db18fb2453f 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -675,6 +675,15 @@ static bool mayTailCallThisCC(CallingConv::ID CC) { case CallingConv::SwiftTail: case CallingConv::Tail: case CallingConv::Fast: + // OHOS_LOCAL begin + case CallingConv::ArkInt: + case CallingConv::ArkFast0: + case CallingConv::ArkFast1: + case CallingConv::ArkFast2: + case CallingConv::ArkFast3: + case CallingConv::ArkFast4: + case CallingConv::ArkFast5: + // OHOS_LOCAL end return true; default: return false; diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index f98916e81cee9f48383743583357b8d52ccd14f5..1e00d8190534bc7c284b97fa6527074843aa37e3 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -30,6 +30,12 @@ def Is16Bit : SubtargetFeature<"16bit-mode", "Is16Bit", "true", // X86 Subtarget ISA features //===----------------------------------------------------------------------===// +// OHOS_LOCAL begin +foreach i = {8-15} in + def FeatureReserveR#i : SubtargetFeature<"fixed-r"#i, "HasReservedR"#i, "true", + "Reserve r"#i#", making it unavaliable as a GPR">; +// OHOS_LOCAL end + def FeatureX87 : SubtargetFeature<"x87","HasX87", "true", "Enable X87 float instructions">; diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index 4dd8a6cdd8982879a7ca78e808e413ed4eaadc01..10f3ed29105f8c1f9e159d7e667c2dd113ef5ca4 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -440,6 +440,18 @@ def RetCC_X86_64_HHVM: CallingConv<[ RAX, R10, R11, R13, R14, R15]>> ]>; +// OHOS_LOCAL begin +def RetCC_X86_64_ARK_INTERPRETER: CallingConv<[ +]>; +def RetCC_X86_64_ARK_FAST_PATH: CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RAX]>> +]>; +def RetCC_X86_64_ARK_RESOLVER: CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[R12]>> +]>; +// OHOS_LOCAL end defm X86_32_RegCall : X86_RegCall_base; @@ -485,6 +497,17 @@ def RetCC_X86_64 : CallingConv<[ // Handle HHVM calls. CCIfCC<"CallingConv::HHVM", CCDelegateTo>, + // OHOS_LOCAL begin + CCIfCC<"CallingConv::ArkInt", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast0", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast1", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast2", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast3", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast4", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast5", CCDelegateTo>, + CCIfCC<"CallingConv::ArkMethod", CCDelegateTo>, + CCIfCC<"CallingConv::ArkResolver", CCDelegateTo>, + // OHOS_LOCAL end CCIfCC<"CallingConv::X86_RegCall", CCIfSubtarget<"isTargetWin64()", @@ -751,6 +774,43 @@ def CC_X86_64_WebKit_JS : CallingConv<[ CCIfType<[i64, f64], CCAssignToStack<8, 8>> ]>; +// OHOS_LOCAL begin +def CC_X86_64_ARK_INTERPRETER : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[R10, RBX, R11, R9, R8, R15, RBP]>> +]>; + +def CC_X86_64_ARK_FAST_0 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[R15, RBP]>> +]>; +def CC_X86_64_ARK_FAST_1 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RDI, R15, RBP]>> +]>; +def CC_X86_64_ARK_FAST_2 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RDI, RSI, R15, RBP]>> +]>; +def CC_X86_64_ARK_FAST_3 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, R15, RBP]>> +]>; +def CC_X86_64_ARK_FAST_4 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R15, RBP]>> +]>; +def CC_X86_64_ARK_FAST_5 : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8, R15, RBP]>> +]>; + +def CC_X86_64_ARK_RESOLVER : CallingConv<[ + CCIfType<[i1, i8, i16, i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[R12]>> +]>; +// OHOS_LOCAL end + // No explicit register is specified for the AnyReg calling convention. The // register allocator may assign the arguments to any free register. // @@ -1103,6 +1163,17 @@ def CC_X86_64 : CallingConv<[ CCIfSubtarget<"isTargetWin64()", CCDelegateTo>>, CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo>, CCIfCC<"CallingConv::X86_INTR", CCCustom<"CC_X86_Intr">>, + // OHOS_LOCAL begin + CCIfCC<"CallingConv::ArkInt", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast0", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast1", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast2", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast3", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast4", CCDelegateTo>, + CCIfCC<"CallingConv::ArkFast5", CCDelegateTo>, + CCIfCC<"CallingConv::ArkMethod", CCDelegateTo>, + CCIfCC<"CallingConv::ArkResolver", CCDelegateTo>, + // OHOS_LOCAL end // Mingw64 and native Win64 use Win64 CC CCIfSubtarget<"isTargetWin64()", CCDelegateTo>, @@ -1227,3 +1298,17 @@ def CSR_SysV64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP, (sequence "R%u", 12, 15))>; def CSR_SysV64_RegCall : CalleeSavedRegs<(add CSR_SysV64_RegCall_NoSSE, (sequence "XMM%u", 8, 15))>; + +// OHOS_LOCAL begin +def CSR_ArkFast0 : CalleeSavedRegs<(add RAX, RDI, RSI, RDX, RCX, R8, R9, R10, R11)>; +def CSR_ArkFast1 : CalleeSavedRegs<(sub CSR_ArkFast0, RDI)>; +def CSR_ArkFast2 : CalleeSavedRegs<(sub CSR_ArkFast1, RSI)>; +def CSR_ArkFast3 : CalleeSavedRegs<(sub CSR_ArkFast2, RDX)>; +def CSR_ArkFast4 : CalleeSavedRegs<(sub CSR_ArkFast3, RCX)>; +def CSR_ArkFast5 : CalleeSavedRegs<(sub CSR_ArkFast4, R8)>; + +def CSR_ArkMethod : CalleeSavedRegs<(add RBP)>; +// R12, R13, R14 may be used as temp registers. But we tight only really used temps. +def CSR_ArkResolver : CalleeSavedRegs<(sub CSR_64, R12, R13)>; +def CSR_ArkPlt : CalleeSavedRegs<(sub CSR_64, R12)>; +// OHOS_LOCAL end diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index d524090f902e7da00c34e327f79b6a79cb78f768..f006386f7508dfede892ebfd15af3da669fcc967 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2397,7 +2397,10 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, // object. // We need to factor in additional offsets applied during the prologue to the // frame, base, and stack pointer depending on which is used. - int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea(); + // OHOS_LOCAL begin + auto CC = MF.getFunction().getCallingConv(); + int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea(CC); + // OHOS_LOCAL end const X86MachineFunctionInfo *X86FI = MF.getInfo(); unsigned CSSize = X86FI->getCalleeSavedFrameSize(); uint64_t StackSize = MFI.getStackSize(); @@ -2408,10 +2411,11 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, // address from any stack object allocated in the caller's frame. Interrupts // do not have a standard return address. Fixed objects in the current frame, // such as SSE register spills, should not get this treatment. - if (MF.getFunction().getCallingConv() == CallingConv::X86_INTR && - Offset >= 0) { - Offset += getOffsetOfLocalArea(); + // OHOS_LOCAL begin + if (CC == CallingConv::X86_INTR && Offset >= 0) { + Offset += getOffsetOfLocalArea(CC); } + // OHOS_LOCAL end if (IsWin64Prologue) { assert(!MFI.hasCalls() || (StackSize % 16) == 8); @@ -2480,8 +2484,11 @@ X86FrameLowering::getFrameIndexReferenceSP(const MachineFunction &MF, int FI, int Adjustment) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); FrameReg = TRI->getStackRegister(); + // OHOS_LOCAL begin + auto CC = MF.getFunction().getCallingConv(); return StackOffset::getFixed(MFI.getObjectOffset(FI) - - getOffsetOfLocalArea() + Adjustment); + getOffsetOfLocalArea(CC) + Adjustment); + // OHOS_LOCAL end } StackOffset @@ -2576,7 +2583,10 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots( unsigned CalleeSavedFrameSize = 0; unsigned XMMCalleeSavedFrameSize = 0; auto &WinEHXMMSlotInfo = X86FI->getWinEHXMMSlotInfo(); - int SpillSlotOffset = getOffsetOfLocalArea() + X86FI->getTCReturnAddrDelta(); + // OHOS_LOCAL begin + auto CC = MF.getFunction().getCallingConv(); + int SpillSlotOffset = getOffsetOfLocalArea(CC) + X86FI->getTCReturnAddrDelta(); + // OHOS_LOCAL end int64_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); @@ -2846,6 +2856,13 @@ void X86FrameLowering::determineCalleeSaves(MachineFunction &MF, BasePtr = getX86SubSuperRegister(BasePtr, 64); SavedRegs.set(BasePtr); } + + // OHOS_LOCAL begin + if (MF.getSubtarget().is64Bit()) { + for (auto Reg : MF.getSubtarget().getRRegReservation()) + SavedRegs.reset(Reg); + } + // OHOS_LOCAL end } static bool @@ -3868,3 +3885,9 @@ void X86FrameLowering::restoreWinEHStackPointersInParent( /*RestoreSP=*/IsSEH); } } + +// OHOS_LOCAL begin +int X86FrameLowering::getOffsetOfLocalArea(CallingConv::ID CC) const { + return CC == CallingConv::ArkInt ? 0 : TargetFrameLowering::getOffsetOfLocalArea(); +} +// OHOS_LOCAL end diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h index 9b83fe77d50597bf16a31890e1e38000dbb1ff3a..13176a290bbef2527b4fc322cc387fb5919c57cf 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.h +++ b/llvm/lib/Target/X86/X86FrameLowering.h @@ -264,6 +264,10 @@ private: void emitCatchRetReturnValue(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineInstr *CatchRet) const; + + // OHOS_LOCAL begin + int getOffsetOfLocalArea(CallingConv::ID CC = CallingConv::C) const override; + // OHOS_LOCAL end }; } // End llvm namespace diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cd45c48259bbfafb39271c2b7280e0e894472775..a75ee58ad7f75ebaa0df7aaae7b8c877a48bbb6f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3610,6 +3610,16 @@ static bool mayTailCallThisCC(CallingConv::ID CC) { // Swift: case CallingConv::Swift: return true; + // OHOS_LOCAL begin + case CallingConv::ArkInt: + case CallingConv::ArkFast0: + case CallingConv::ArkFast1: + case CallingConv::ArkFast2: + case CallingConv::ArkFast3: + case CallingConv::ArkFast4: + case CallingConv::ArkFast5: + return true; + // OHOS_LOCAL end default: return canGuaranteeTCO(CC); } @@ -3875,7 +3885,10 @@ void VarArgsLoweringHelper::createVarArgAreaAndStoreRegisters( if (isWin64()) { // Get to the caller-allocated home save location. Add 8 to account // for the return address. - int HomeOffset = FrameLowering.getOffsetOfLocalArea() + 8; + // OHOS_LOCAL begin + auto CC = TheMachineFunction.getFunction().getCallingConv(); + int HomeOffset = FrameLowering.getOffsetOfLocalArea(CC) + 8; + // OHOS_LOCAL end FuncInfo->setRegSaveFrameIndex( FrameInfo.CreateFixedObject(1, NumIntRegs * 8 + HomeOffset, false)); // Fixup to set vararg frame on shadow area (4 x i64). @@ -28213,6 +28226,11 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { return FrameAddr; } +// OHOS_LOCAL begin +#define GET_REGISTER_MATCHER +#include "X86GenAsmMatcher.inc" +// OHOS_LOCAL end + // FIXME? Maybe this could be a TableGen attribute on some registers and // this table could be generated automatically from RegInfo. Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT, @@ -28243,6 +28261,13 @@ Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT, if (Reg) return Reg; + // OHOS_LOCAL begin + Reg = MatchRegisterName(RegName); + Register RReg = getX86SubSuperRegisterOrZero(Reg, 64); + if (Subtarget.getRRegReservation().contains(RReg)) + return Reg; + // OHOS_LOCAL end + report_fatal_error("Invalid register name global variable"); } diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index f2658f70434b719e9f746c334a70d8ebc28a8ef0..abde64b61b85ec09ef8464f07128785a36550c32 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -298,6 +298,28 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CSR_NoRegs_SaveList; switch (CC) { + // OHOS_LOCAL begin + case CallingConv::ArkInt: + return CSR_NoRegs_SaveList; + case CallingConv::ArkFast0: + return CSR_ArkFast0_SaveList; + case CallingConv::ArkFast1: + return CSR_ArkFast1_SaveList; + case CallingConv::ArkFast2: + return CSR_ArkFast2_SaveList; + case CallingConv::ArkFast3: + return CSR_ArkFast3_SaveList; + case CallingConv::ArkFast4: + return CSR_ArkFast4_SaveList; + case CallingConv::ArkFast5: + return CSR_ArkFast5_SaveList; + case CallingConv::ArkMethod: + return CSR_ArkMethod_SaveList; + case CallingConv::ArkResolver: + return CSR_ArkResolver_SaveList; + case CallingConv::ArkPlt: + return CSR_ArkPlt_SaveList; + // OHOS_LOCAL end case CallingConv::GHC: case CallingConv::HiPE: return CSR_NoRegs_SaveList; @@ -421,6 +443,28 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, bool HasAVX512 = Subtarget.hasAVX512(); switch (CC) { + // OHOS_LOCAL begin + case CallingConv::ArkInt: + return CSR_NoRegs_RegMask; + case CallingConv::ArkFast0: + return CSR_ArkFast0_RegMask; + case CallingConv::ArkFast1: + return CSR_ArkFast1_RegMask; + case CallingConv::ArkFast2: + return CSR_ArkFast2_RegMask; + case CallingConv::ArkFast3: + return CSR_ArkFast3_RegMask; + case CallingConv::ArkFast4: + return CSR_ArkFast4_RegMask; + case CallingConv::ArkFast5: + return CSR_ArkFast5_RegMask; + case CallingConv::ArkMethod: + return CSR_ArkMethod_RegMask; + case CallingConv::ArkResolver: + return CSR_ArkResolver_RegMask; + case CallingConv::ArkPlt: + return CSR_ArkPlt_RegMask; + // OHOS_LOCAL end case CallingConv::GHC: case CallingConv::HiPE: return CSR_NoRegs_RegMask; @@ -548,6 +592,16 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const { // Set the Shadow Stack Pointer as reserved. Reserved.set(X86::SSP); + // OHOS_LOCAL begin + // Set r# as reserved register if we need it + if (Is64Bit) { + for (auto Reg : MF.getSubtarget().getRRegReservation()) { + for (const MCPhysReg &SubReg : subregs_inclusive(Reg)) + Reserved.set(SubReg); + } + } + // OHOS_LOCAL end + // Set the instruction pointer register and its aliases as reserved. for (const MCPhysReg &SubReg : subregs_inclusive(X86::RIP)) Reserved.set(SubReg); diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 0d091adc8e7768addfc1c76d9ac1924363606f39..a2f2aa2e6c715c6e3b73a7ad52db3788d4447d34 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -254,6 +254,30 @@ bool X86Subtarget::isLegalToCallImmediateAddr() const { return isTargetELF() || TM.getRelocationModel() == Reloc::Static; } +// OHOS_LOCAL begin +// Reserved registers features +SmallSet X86Subtarget::getRRegReservation() const { + SmallSet ReservedRRegs; + if (hasReservedR8()) + ReservedRRegs.insert(X86::R8); + if (hasReservedR9()) + ReservedRRegs.insert(X86::R9); + if (hasReservedR10()) + ReservedRRegs.insert(X86::R10); + if (hasReservedR11()) + ReservedRRegs.insert(X86::R11); + if (hasReservedR12()) + ReservedRRegs.insert(X86::R12); + if (hasReservedR13()) + ReservedRRegs.insert(X86::R13); + if (hasReservedR14()) + ReservedRRegs.insert(X86::R14); + if (hasReservedR15()) + ReservedRRegs.insert(X86::R15); + return ReservedRRegs; +} +// OHOS_LOCAL end + void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS) { if (CPU.empty()) diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 09a8b1f1aafb83703b03d98d2c9f943a67712dc5..4d8209adbcd15743b2c3a9363ba9fca8b6c97263 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -193,6 +193,12 @@ public: // CX16 is just the CPUID bit, instruction requires 64-bit mode too. return hasCX16() && is64Bit(); } + + // OHOS_LOCAL begin + // Reserved registers features + SmallSet getRRegReservation() const; + // OHOS_LOCAL end + // SSE codegen depends on cmovs, and all SSE1+ processors support them. // All 64-bit processors support cmov. bool canUseCMOV() const { return hasCMOV() || hasSSE1() || is64Bit(); } diff --git a/llvm/test/CodeGen/X86/x86_64-named-reg-rregs.ll b/llvm/test/CodeGen/X86/x86_64-named-reg-rregs.ll new file mode 100644 index 0000000000000000000000000000000000000000..347f895777561359051fc0849ba5ed0fd7a0d776 --- /dev/null +++ b/llvm/test/CodeGen/X86/x86_64-named-reg-rregs.ll @@ -0,0 +1,136 @@ + +; RUN: sed 's/_REG_/r8/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r8 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r9/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r9 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r10/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r10 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r11/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r11 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r12/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r12 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r13/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r13 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r14/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r14 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +; RUN: sed 's/_REG_/r15/g' %s > %t +; RUN llc -march=x86-64 %t -O0 -o - 2> %t1 || echo +; RUN FileCheck < %t1 %t --check-prefix=CHECK-NO-RESERVATION +; RUN: llc -march=x86-64 %t -O0 -mattr=+fixed-r15 -o - | FileCheck %t --check-prefix=CHECK-HAVE-RESERVATION + +define i64 @read_reg64() { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_ + %r = call i64 @llvm.read_register.i64(metadata !0) + ret i64 %r + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define i32 @read_reg32() { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_d + %r = call i32 @llvm.read_register.i32(metadata !1) + ret i32 %r + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define i16 @read_reg16() { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_w + %r = call i16 @llvm.read_register.i16(metadata !2) + ret i16 %r + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define i8 @read_reg8() { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_b + %r = call i8 @llvm.read_register.i8(metadata !3) + ret i8 %r + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define void @write_reg64(i64 %val) { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_ + call void @llvm.write_register.i64(metadata !0, i64 %val) + ret void + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define void @write_reg32(i32 %val) { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_d + call void @llvm.write_register.i32(metadata !1, i32 %val) + ret void + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define void @write_reg16(i16 %val) { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_w + call void @llvm.write_register.i16(metadata !2, i16 %val) + ret void + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define void @write_reg8(i8 %val) { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + ; CHECK-HAVE-RESERVATION: %_REG_b + call void @llvm.write_register.i8(metadata !3, i8 %val) + ret void + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +define i64 @main() { + ; CHECK-HAVE-RESERVATION-NOT: push{{[qlwb]}} %_REG_ + + ; CHECK-NO-RESERVATION: LLVM ERROR + ; CHECK-NO-RESERVATION-SAME: Invalid register name global variable + + %r1 = call i64 @read_reg64() + %r2 = call i32 @read_reg32() + %r3 = call i16 @read_reg16() + %r4 = call i8 @read_reg8() + call void @write_reg64(i64 4294967296) + call void @write_reg32(i32 65536) + call void @write_reg16(i16 256) + call void @write_reg8(i8 1) + + ret i64 %r1 + ; CHECK-HAVE-RESERVATION-NOT: pop{{[qlwb]}} %_REG_ +} + +declare i64 @llvm.read_register.i64(metadata) +declare void @llvm.write_register.i64(metadata, i64) +declare i32 @llvm.read_register.i32(metadata) +declare void @llvm.write_register.i32(metadata, i32) +declare i16 @llvm.read_register.i16(metadata) +declare void @llvm.write_register.i16(metadata, i16) +declare i8 @llvm.read_register.i8(metadata) +declare void @llvm.write_register.i8(metadata, i8) +!0 = !{!"_REG_\00"} +!1 = !{!"_REG_d\00"} +!2 = !{!"_REG_w\00"} +!3 = !{!"_REG_b\00"} diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll index a0f09314a47ce1dae1a5cf8b0768457e99beb77a..edb0f341c815214b728dab7c637d44ae986a9067 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fp.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll @@ -57,6 +57,19 @@ define double @t5(float %a) { ret double %3 } +; PR57357 + +define float @not_maxnum(float %x) { +; CHECK-LABEL: @not_maxnum( +; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float -0.000000e+00, float [[X]] +; CHECK-NEXT: ret float [[SEL]] +; + %cmp = fcmp olt float %x, 0.0 + %sel = select i1 %cmp, float -0.0, float %x + ret float %sel +} + ; From IEEE754: "Comparisons shall ignore the sign of zero (so +0 = -0)." ; So the compare constant may be treated as +0.0, and we sink the fpext. @@ -73,15 +86,15 @@ define double @t6(float %a) { ret double %3 } -; From IEEE754: "Comparisons shall ignore the sign of zero (so +0 = -0)." -; So the compare constant may be treated as -0.0, and we sink the fpext. +; TODO: Move the select ahead of the fpext because it's a narrower op. +; This works as long as the wide constant can be represented exactly in the narrow type. define double @t7(float %a) { ; CHECK-LABEL: @t7( -; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00 -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[A]] -; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[TMP1]] to double -; CHECK-NEXT: ret double [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp ult float [[A:%.*]], 0.000000e+00 +; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[A]] to double +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], double [[TMP2]], double -0.000000e+00 +; CHECK-NEXT: ret double [[TMP3]] ; %1 = fcmp ult float %a, 0.0 %2 = fpext float %a to double @@ -93,8 +106,8 @@ define double @t7(float %a) { define float @fmin_fmin_zero_mismatch(float %x) { ; CHECK-LABEL: @fmin_fmin_zero_mismatch( -; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[MIN2:%.*]] = select i1 [[TMP1]], float [[X]], float 0.000000e+00 +; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00 +; CHECK-NEXT: [[MIN2:%.*]] = select i1 [[CMP1]], float [[X]], float 0.000000e+00 ; CHECK-NEXT: ret float [[MIN2]] ; %cmp1 = fcmp olt float %x, -0.0 @@ -104,13 +117,16 @@ define float @fmin_fmin_zero_mismatch(float %x) { ret float %min2 } +; TODO: We do not recognize these as max ops because of the mismatched zeros. ; max(max(x, -0.0), -0.0) --> max(x, -0.0) define float @fmax_fmax_zero_mismatch(float %x) { ; CHECK-LABEL: @fmax_fmax_zero_mismatch( -; CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt float [[X:%.*]], -0.000000e+00 -; CHECK-NEXT: [[MAX11:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00 -; CHECK-NEXT: ret float [[MAX11]] +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00 +; CHECK-NEXT: [[MAX1:%.*]] = select i1 [[CMP1]], float [[X]], float -0.000000e+00 +; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[MAX1]], 0.000000e+00 +; CHECK-NEXT: [[MAX2:%.*]] = select i1 [[CMP2]], float -0.000000e+00, float [[MAX1]] +; CHECK-NEXT: ret float [[MAX2]] ; %cmp1 = fcmp ogt float %x, 0.0 %max1 = select i1 %cmp1, float %x, float -0.0 diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt index 8e2b78f1b85c0f2664f84e24d7588bb60e37fe77..03557154926a641dbb8a915fe808f32676db5455 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -35,6 +35,7 @@ if(LLVM_BUILD_LLVM_DYLIB) list(REMOVE_DUPLICATES LIB_NAMES) if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR (HAIKU) OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") + OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") # OHOS_LOCAL OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD") OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 902107d30082c022eb6647fcd5855340815cc0d7..05e6a099c3a5b2f61240af01255f9067fd71cf1f 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -202,7 +202,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) { @@ -213,7 +213,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) { @@ -224,7 +224,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) { @@ -235,7 +235,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) { @@ -246,7 +246,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) { @@ -257,7 +257,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) { @@ -268,7 +268,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) { @@ -279,7 +279,7 @@ TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) { @@ -290,7 +290,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) { @@ -301,7 +301,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) { @@ -312,7 +312,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) { @@ -323,7 +323,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) { @@ -334,7 +334,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) { @@ -345,7 +345,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) { @@ -356,7 +356,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) { @@ -367,7 +367,7 @@ TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) { " ret float %A\n" "}\n"); // The sign of zero doesn't matter in fcmp. - expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); } TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) { diff --git a/llvm/utils/emacs/llvm-mode.el b/llvm/utils/emacs/llvm-mode.el index c6d594d118d0b053f6696d8cdb7253c3b35b9ca1..c4def25469f21f5f6b81d6b63120868cc0082b94 100644 --- a/llvm/utils/emacs/llvm-mode.el +++ b/llvm/utils/emacs/llvm-mode.el @@ -57,7 +57,11 @@ ;; Calling conventions "ccc" "fastcc" "coldcc" "webkit_jscc" "anyregcc" "preserve_mostcc" "preserve_allcc" - "cxx_fast_tlscc" "swiftcc" "tailcc" "swifttailcc" "cfguard_checkcc" + ;; OHOS_LOCAL begin + "cxx_fast_tlscc" "swiftcc" "tailcc" "swifttailcc" "cfguard_checkcc" "arkintcc" + "arkfast0cc" "arkfast1cc" "arkfast2cc" "arkfast3cc" "arkfast4cc" "arkfast5cc" + "arkmethodcc" "arkresolvercc" "arkpltcc" + ;; OHOS_LOCAL end ;; Visibility styles "default" "hidden" "protected" ;; DLL storages diff --git a/llvm/utils/vim/syntax/llvm.vim b/llvm/utils/vim/syntax/llvm.vim index 9185a029a22e5700e6e2353abf9e59879aa428be..5b333a8b5bbc4542391aea419473969613706201 100644 --- a/llvm/utils/vim/syntax/llvm.vim +++ b/llvm/utils/vim/syntax/llvm.vim @@ -48,6 +48,18 @@ syn keyword llvmKeyword \ alwaysinline \ appending \ argmemonly +" OHOS_LOCAL begin + \ arkfast0cc + \ arkfast1cc + \ arkfast2cc + \ arkfast3cc + \ arkfast4cc + \ arkfast5cc + \ arkintccx + \ arkmethodcc + \ arkpltcc + \ arkresolvercc +" OHOS_LOCAL end \ arm_aapcs_vfpcc \ arm_aapcscc \ arm_apcscc