1 // REQUIRES: aarch64-registered-target 2 3 // RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm -S \ 4 // RUN: -o - %s | FileCheck %s -check-prefix CHECK-ASM 5 6 // RUN: %clang_cc1 -triple arm64-darwin -fms-compatibility -emit-llvm -S \ 7 // RUN: -o - %s | FileCheck %s -check-prefix CHECK-ASM 8 9 // RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm \ 10 // RUN: -o - %s | FileCheck %s -check-prefix CHECK-IR 11 12 // RUN: %clang_cc1 -triple arm64-darwin -fms-compatibility -emit-llvm \ 13 // RUN: -o - %s | FileCheck %s -check-prefix CHECK-IR 14 15 // From winnt.h 16 #define ARM64_SYSREG(op0, op1, crn, crm, op2) \ 17 ( ((op0 & 1) << 14) | \ 18 ((op1 & 7) << 11) | \ 19 ((crn & 15) << 7) | \ 20 ((crm & 15) << 3) | \ 21 ((op2 & 7) << 0) ) 22 23 #define ARM64_CNTVCT ARM64_SYSREG(3,3,14, 0,2) // Generic Timer counter register 24 #define ARM64_PMCCNTR_EL0 ARM64_SYSREG(3,3, 9,13,0) // Cycle Count Register [CP15_PMCCNTR] 25 #define ARM64_PMSELR_EL0 ARM64_SYSREG(3,3, 9,12,5) // Event Counter Selection Register [CP15_PMSELR] 26 #define ARM64_PMXEVCNTR_EL0 ARM64_SYSREG(3,3, 9,13,2) // Event Count Register [CP15_PMXEVCNTR] 27 #define ARM64_PMXEVCNTRn_EL0(n) ARM64_SYSREG(3,3,14, 8+((n)/8), (n)%8) // Direct Event Count Register [n/a] 28 #define ARM64_TPIDR_EL0 ARM64_SYSREG(3,3,13, 0,2) // Thread ID Register, User Read/Write [CP15_TPIDRURW] 29 #define ARM64_TPIDRRO_EL0 ARM64_SYSREG(3,3,13, 0,3) // Thread ID Register, User Read Only [CP15_TPIDRURO] 30 #define ARM64_TPIDR_EL1 ARM64_SYSREG(3,0,13, 0,4) // Thread ID Register, Privileged Only [CP15_TPIDRPRW] 31 32 // From intrin.h 33 __int64 _ReadStatusReg(int); 34 void _WriteStatusReg(int, __int64); 35 36 void check_ReadWriteStatusReg(__int64 v) { 37 __int64 ret; 38 ret = _ReadStatusReg(ARM64_CNTVCT); 39 // CHECK-ASM: mrs x8, CNTVCT_EL0 40 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2:.*]]) 41 // CHECK-IR-NEXT: store i64 %[[VAR]] 42 43 ret = _ReadStatusReg(ARM64_PMCCNTR_EL0); 44 // CHECK-ASM: mrs x8, PMCCNTR_EL0 45 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD3:.*]]) 46 // CHECK-IR-NEXT: store i64 %[[VAR]] 47 48 ret = _ReadStatusReg(ARM64_PMSELR_EL0); 49 // CHECK-ASM: mrs x8, PMSELR_EL0 50 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD4:.*]]) 51 // CHECK-IR-NEXT: store i64 %[[VAR]] 52 53 ret = _ReadStatusReg(ARM64_PMXEVCNTR_EL0); 54 // CHECK-ASM: mrs x8, PMXEVCNTR_EL0 55 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD5:.*]]) 56 // CHECK-IR-NEXT: store i64 %[[VAR]] 57 58 ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(0)); 59 // CHECK-ASM: mrs x8, PMEVCNTR0_EL0 60 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD6:.*]]) 61 // CHECK-IR-NEXT: store i64 %[[VAR]] 62 63 ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(1)); 64 // CHECK-ASM: mrs x8, PMEVCNTR1_EL0 65 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD7:.*]]) 66 // CHECK-IR-NEXT: store i64 %[[VAR]] 67 68 ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(30)); 69 // CHECK-ASM: mrs x8, PMEVCNTR30_EL0 70 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD8:.*]]) 71 // CHECK-IR-NEXT: store i64 %[[VAR]] 72 73 ret = _ReadStatusReg(ARM64_TPIDR_EL0); 74 // CHECK-ASM: mrs x8, TPIDR_EL0 75 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD9:.*]]) 76 // CHECK-IR-NEXT: store i64 %[[VAR]] 77 78 ret = _ReadStatusReg(ARM64_TPIDRRO_EL0); 79 // CHECK-ASM: mrs x8, TPIDRRO_EL0 80 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD10:.*]]) 81 // CHECK-IR-NEXT: store i64 %[[VAR]] 82 83 ret = _ReadStatusReg(ARM64_TPIDR_EL1); 84 // CHECK-ASM: mrs x8, TPIDR_EL1 85 // CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD11:.*]]) 86 // CHECK-IR-NEXT: store i64 %[[VAR]] 87 88 89 _WriteStatusReg(ARM64_CNTVCT, v); 90 // CHECK-ASM: msr S3_3_C14_C0_2, x8 91 // CHECK-IR: %[[VAR:.*]] = load i64, 92 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 %[[VAR]]) 93 94 _WriteStatusReg(ARM64_PMCCNTR_EL0, v); 95 // CHECK-ASM: msr PMCCNTR_EL0, x8 96 // CHECK-IR: %[[VAR:.*]] = load i64, 97 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 %[[VAR]]) 98 99 _WriteStatusReg(ARM64_PMSELR_EL0, v); 100 // CHECK-ASM: msr PMSELR_EL0, x8 101 // CHECK-IR: %[[VAR:.*]] = load i64, 102 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 %[[VAR]]) 103 104 _WriteStatusReg(ARM64_PMXEVCNTR_EL0, v); 105 // CHECK-ASM: msr PMXEVCNTR_EL0, x8 106 // CHECK-IR: %[[VAR:.*]] = load i64, 107 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 %[[VAR]]) 108 109 _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(0), v); 110 // CHECK-ASM: msr PMEVCNTR0_EL0, x8 111 // CHECK-IR: %[[VAR:.*]] = load i64, 112 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 %[[VAR]]) 113 114 _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(1), v); 115 // CHECK-ASM: msr PMEVCNTR1_EL0, x8 116 // CHECK-IR: %[[VAR:.*]] = load i64, 117 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 %[[VAR]]) 118 119 _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(30), v); 120 // CHECK-ASM: msr PMEVCNTR30_EL0, x8 121 // CHECK-IR: %[[VAR:.*]] = load i64, 122 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 %[[VAR]]) 123 124 _WriteStatusReg(ARM64_TPIDR_EL0, v); 125 // CHECK-ASM: msr TPIDR_EL0, x8 126 // CHECK-IR: %[[VAR:.*]] = load i64, 127 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 %[[VAR]]) 128 129 _WriteStatusReg(ARM64_TPIDRRO_EL0, v); 130 // CHECK-ASM: msr TPIDRRO_EL0, x8 131 // CHECK-IR: %[[VAR:.*]] = load i64, 132 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 %[[VAR]]) 133 134 _WriteStatusReg(ARM64_TPIDR_EL1, v); 135 // CHECK-ASM: msr TPIDR_EL1, x8 136 // CHECK-IR: %[[VAR:.*]] = load i64, 137 // CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 %[[VAR]]) 138 } 139 140 // CHECK-IR: ![[MD2]] = !{!"3:3:14:0:2"} 141 // CHECK-IR: ![[MD3]] = !{!"3:3:9:13:0"} 142 // CHECK-IR: ![[MD4]] = !{!"3:3:9:12:5"} 143 // CHECK-IR: ![[MD5]] = !{!"3:3:9:13:2"} 144 // CHECK-IR: ![[MD6]] = !{!"3:3:14:8:0"} 145 // CHECK-IR: ![[MD7]] = !{!"3:3:14:8:1"} 146 // CHECK-IR: ![[MD8]] = !{!"3:3:14:11:6"} 147 // CHECK-IR: ![[MD9]] = !{!"3:3:13:0:2"} 148 // CHECK-IR: ![[MD10]] = !{!"3:3:13:0:3"} 149 // CHECK-IR: ![[MD11]] = !{!"3:0:13:0:4"} 150