Index: lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- lib/Target/AArch64/AArch64SystemOperands.td +++ lib/Target/AArch64/AArch64SystemOperands.td @@ -325,6 +325,9 @@ // v8.5a Spectre Mitigation let Requires = [{ {AArch64::FeatureSpecRestrict} }] in def : PState<"SSBS", 0b11001>; +// v8.5a Memory Tagging Extension +let Requires = [{ {AArch64::FeatureMTE} }] in +def : PState<"TCO", 0b11100>; //===----------------------------------------------------------------------===// // PSB instruction options. @@ -1411,6 +1414,19 @@ let Requires = [{ {AArch64::FeatureSpecRestrict} }] in def : RWSysReg<"SSBS", 0b11, 0b011, 0b0100, 0b0010, 0b110>; +// v8.5a Memory Tagging Extension +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureMTE} }] in { +def : RWSysReg<"TCO", 0b11, 0b011, 0b0100, 0b0010, 0b111>; +def : RWSysReg<"GCR_EL1", 0b11, 0b000, 0b0001, 0b0000, 0b110>; +def : RWSysReg<"RGSR_EL1", 0b11, 0b000, 0b0001, 0b0000, 0b101>; +def : RWSysReg<"TFSR_EL1", 0b11, 0b000, 0b0110, 0b0101, 0b000>; +def : RWSysReg<"TFSR_EL2", 0b11, 0b100, 0b0110, 0b0101, 0b000>; +def : RWSysReg<"TFSR_EL3", 0b11, 0b110, 0b0110, 0b0110, 0b000>; +def : RWSysReg<"TFSR_EL12", 0b11, 0b101, 0b0110, 0b0110, 0b000>; +def : RWSysReg<"TFSRE0_EL1", 0b11, 0b000, 0b0110, 0b0110, 0b001>; +} // HasMTE + // Cyclone specific system registers // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::ProcCyclone} }] in Index: test/MC/AArch64/armv8.5a-mte-error.s =================================================================== --- /dev/null +++ test/MC/AArch64/armv8.5a-mte-error.s @@ -0,0 +1,133 @@ +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+mte < %s 2>&1| FileCheck %s + +mrs tco +mrs gcr_el1 +mrs rgsr_el1 +mrs tfsr_el1 +mrs tfsr_el2 +mrs tfsr_el3 +mrs tfsr_el12 +mrs tfsre0_el1 + +// CHECK: invalid operand for instruction +// CHECK-NEXT: tco +// CHECK: invalid operand for instruction +// CHECK-NEXT: gcr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: rgsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el2 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el3 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el12 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsre0_el1 + +mrs tco, #0 +mrs tco, x0 +mrs gcr_el1, x1 +mrs rgsr_el1, x2 +mrs tfsr_el1, x3 +mrs tfsr_el2, x4 +mrs tfsr_el3, x5 +mrs tfsr_el12, x6 +mrs tfsre0_el1, x7 + +// CHECK: invalid operand for instruction +// CHECK-NEXT: tco, #0 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tco, x0 +// CHECK: invalid operand for instruction +// CHECK-NEXT: gcr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: rgsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el2 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el3 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el12 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsre0_el1 + +msr tco +msr gcr_el1 +msr rgsr_el1 +msr tfsr_el1 +msr tfsr_el2 +msr tfsr_el3 +msr tfsr_el12 +msr tfsre0_el1 + +// CHECK: too few operands for instruction +// CHECK-NEXT: tco +// CHECK: too few operands for instruction +// CHECK-NEXT: gcr_el1 +// CHECK: too few operands for instruction +// CHECK-NEXT: rgsr_el1 +// CHECK: too few operands for instruction +// CHECK-NEXT: tfsr_el1 +// CHECK: too few operands for instruction +// CHECK-NEXT: tfsr_el2 +// CHECK: too few operands for instruction +// CHECK-NEXT: tfsr_el3 +// CHECK: too few operands for instruction +// CHECK-NEXT: tfsr_el12 +// CHECK: too few operands for instruction +// CHECK-NEXT: tfsre0_el1 + +msr x0, tco +msr x1, gcr_el1 +msr x2, rgsr_el1 +msr x3, tfsr_el1 +msr x4, tfsr_el2 +msr x5, tfsr_el3 +msr x6, tfsr_el12 +msr x7, tfsre0_el1 + +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tco +// CHECK: expected writable system register or pstate +// CHECK-NEXT: gcr_el1 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: rgsr_el1 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tfsr_el1 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tfsr_el2 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tfsr_el3 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tfsr_el12 +// CHECK: expected writable system register or pstate +// CHECK-NEXT: tfsre0_el1 + +// Among the system registers added by MTE, only TCO can be used with MSR (imm). +// The rest can only be used with MSR (reg). +msr gcr_el1, #1 +msr rgsr_el1, #2 +msr tfsr_el1, #3 +msr tfsr_el2, #4 +msr tfsr_el3, #5 +msr tfsr_el12, #6 +msr tfsre0_el1, #7 + +// CHECK: invalid operand for instruction +// CHECK-NEXT: gcr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: rgsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el1 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el2 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el3 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsr_el12 +// CHECK: invalid operand for instruction +// CHECK-NEXT: tfsre0_el1 Index: test/MC/AArch64/armv8.5a-mte.s =================================================================== --- test/MC/AArch64/armv8.5a-mte.s +++ test/MC/AArch64/armv8.5a-mte.s @@ -58,3 +58,80 @@ // NOMTE: DC CGDVADP requires mte // NOMTE: DC CIGDVAC requires mte // NOMTE: DC GZVA requires mte + +mrs x0, tco +mrs x1, gcr_el1 +mrs x2, rgsr_el1 +mrs x3, tfsr_el1 +mrs x4, tfsr_el2 +mrs x5, tfsr_el3 +mrs x6, tfsr_el12 +mrs x7, tfsre0_el1 + +// CHECK: mrs x0, TCO // encoding: [0xe0,0x42,0x3b,0xd5] +// CHECK: mrs x1, GCR_EL1 // encoding: [0xc1,0x10,0x38,0xd5] +// CHECK: mrs x2, RGSR_EL1 // encoding: [0xa2,0x10,0x38,0xd5] +// CHECK: mrs x3, TFSR_EL1 // encoding: [0x03,0x65,0x38,0xd5] +// CHECK: mrs x4, TFSR_EL2 // encoding: [0x04,0x65,0x3c,0xd5] +// CHECK: mrs x5, TFSR_EL3 // encoding: [0x05,0x66,0x3e,0xd5] +// CHECK: mrs x6, TFSR_EL12 // encoding: [0x06,0x66,0x3d,0xd5] +// CHECK: mrs x7, TFSRE0_EL1 // encoding: [0x27,0x66,0x38,0xd5] + +// NOMTE: expected readable system register +// NOMTE-NEXT: tco +// NOMTE: expected readable system register +// NOMTE-NEXT: gcr_el1 +// NOMTE: expected readable system register +// NOMTE-NEXT: rgsr_el1 +// NOMTE: expected readable system register +// NOMTE-NEXT: tfsr_el1 +// NOMTE: expected readable system register +// NOMTE-NEXT: tfsr_el2 +// NOMTE: expected readable system register +// NOMTE-NEXT: tfsr_el3 +// NOMTE: expected readable system register +// NOMTE-NEXT: tfsr_el12 +// NOMTE: expected readable system register +// NOMTE-NEXT: tfsre0_el1 + +msr tco, #0 + +// CHECK: msr TCO, #0 // encoding: [0x9f,0x40,0x03,0xd5] + +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tco + +msr tco, x0 +msr gcr_el1, x1 +msr rgsr_el1, x2 +msr tfsr_el1, x3 +msr tfsr_el2, x4 +msr tfsr_el3, x5 +msr tfsr_el12, x6 +msr tfsre0_el1, x7 + +// CHECK: msr TCO, x0 // encoding: [0xe0,0x42,0x1b,0xd5] +// CHECK: msr GCR_EL1, x1 // encoding: [0xc1,0x10,0x18,0xd5] +// CHECK: msr RGSR_EL1, x2 // encoding: [0xa2,0x10,0x18,0xd5] +// CHECK: msr TFSR_EL1, x3 // encoding: [0x03,0x65,0x18,0xd5] +// CHECK: msr TFSR_EL2, x4 // encoding: [0x04,0x65,0x1c,0xd5] +// CHECK: msr TFSR_EL3, x5 // encoding: [0x05,0x66,0x1e,0xd5] +// CHECK: msr TFSR_EL12, x6 // encoding: [0x06,0x66,0x1d,0xd5] +// CHECK: msr TFSRE0_EL1, x7 // encoding: [0x27,0x66,0x18,0xd5] + +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tco +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: gcr_el1 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: rgsr_el1 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tfsr_el1 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tfsr_el2 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tfsr_el3 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tfsr_el12 +// NOMTE: expected writable system register or pstate +// NOMTE-NEXT: tfsre0_el1 Index: test/MC/Disassembler/AArch64/armv8.5a-mte.txt =================================================================== --- test/MC/Disassembler/AArch64/armv8.5a-mte.txt +++ test/MC/Disassembler/AArch64/armv8.5a-mte.txt @@ -1,6 +1,6 @@ -# RUN: llvm-mc -triple=aarch64 -mattr=+mte -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+mte -disassemble < %s | FileCheck %s # RUN: llvm-mc -triple=aarch64 -mattr=+v8.5a -disassemble < %s | FileCheck %s --check-prefix=NOMTE -# RUN: llvm-mc -triple=aarch64 -mattr=-mte -disassemble < %s | FileCheck %s --check-prefix=NOMTE +# RUN: llvm-mc -triple=aarch64 -mattr=-mte -disassemble < %s | FileCheck %s --check-prefix=NOMTE [0x60,0x76,0x08,0xd5] [0x81,0x76,0x08,0xd5] @@ -58,3 +58,43 @@ # NOMTE: sys #3, c7, c13, #5, x15 # NOMTE: sys #3, c7, c14, #5, x16 # NOMTE: sys #3, c7, c4, #4, x17 + +[0xe0,0x42,0x3b,0xd5] +[0xc1,0x10,0x38,0xd5] +[0xa2,0x10,0x38,0xd5] +[0x03,0x65,0x38,0xd5] +[0x04,0x65,0x3c,0xd5] +[0x05,0x66,0x3e,0xd5] +[0x06,0x66,0x3d,0xd5] +[0x27,0x66,0x38,0xd5] + +# CHECK: mrs x0, TCO +# CHECK: mrs x1, GCR_EL1 +# CHECK: mrs x2, RGSR_EL1 +# CHECK: mrs x3, TFSR_EL1 +# CHECK: mrs x4, TFSR_EL2 +# CHECK: mrs x5, TFSR_EL3 +# CHECK: mrs x6, TFSR_EL12 +# CHECK: mrs x7, TFSRE0_EL1 + +[0x9f,0x40,0x03,0xd5] + +# CHECK: msr TCO, #0 + +[0xe0,0x42,0x1b,0xd5] +[0xc1,0x10,0x18,0xd5] +[0xa2,0x10,0x18,0xd5] +[0x03,0x65,0x18,0xd5] +[0x04,0x65,0x1c,0xd5] +[0x05,0x66,0x1e,0xd5] +[0x06,0x66,0x1d,0xd5] +[0x27,0x66,0x18,0xd5] + +# CHECK: msr TCO, x0 +# CHECK: msr GCR_EL1, x1 +# CHECK: msr RGSR_EL1, x2 +# CHECK: msr TFSR_EL1, x3 +# CHECK: msr TFSR_EL2, x4 +# CHECK: msr TFSR_EL3, x5 +# CHECK: msr TFSR_EL12, x6 +# CHECK: msr TFSRE0_EL1, x7