1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

AArch64: enforce even/odd register pairs for CASP instructions.

ARMv8.1a CASP instructions need the first of the pair to be an even register
(otherwise the encoding is unallocated). We enforced this during assembly, but
not CodeGen before.

llvm-svn: 353308
This commit is contained in:
Tim Northover 2019-02-06 15:26:35 +00:00
parent 5df33b90f1
commit 009fdea45c
3 changed files with 25 additions and 6 deletions

View File

@ -653,10 +653,12 @@ def FPR128Op : RegisterOperand<FPR128, "printOperand"> {
// ARMv8.1a atomic CASP register operands
def WSeqPairs : RegisterTuples<[sube32, subo32],
[(rotl GPR32, 0), (rotl GPR32, 1)]>;
def XSeqPairs : RegisterTuples<[sube64, subo64],
[(rotl GPR64, 0), (rotl GPR64, 1)]>;
def WSeqPairs : RegisterTuples<[sube32, subo32],
[(decimate (rotl GPR32, 0), 2),
(decimate (rotl GPR32, 1), 2)]>;
def XSeqPairs : RegisterTuples<[sube64, subo64],
[(decimate (rotl GPR64, 0), 2),
(decimate (rotl GPR64, 1), 2)]>;
def WSeqPairsClass : RegisterClass<"AArch64", [untyped], 32,
(add WSeqPairs)>{

View File

@ -1778,8 +1778,8 @@ static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst,
if (RegNo & 0x1)
return Fail;
unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo);
Inst.addOperand(MCOperand::createReg(Register));
unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
Inst.addOperand(MCOperand::createReg(Reg));
return Success;
}

View File

@ -0,0 +1,17 @@
; RUN: llc -mtriple arm64-apple-ios -mattr=+lse %s -o - | FileCheck %s
; Only "even,even+1" pairs are valid for CASP instructions. Make sure LLVM
; doesn't allocate odd ones and that it can copy them around properly. N.b. we
; don't actually check that they're sequential because FileCheck can't; odd/even
; will have to be good enough.
define void @test_atomic_cmpxchg_i128_register_shuffling(i128* %addr, i128 %desired, i128 %new) nounwind {
; CHECK-LABEL: test_atomic_cmpxchg_i128_register_shuffling:
; CHECK-DAG: mov [[DESIRED_LO:x[0-9]*[02468]]], x1
; CHECK-DAG: mov [[DESIRED_HI:x[0-9]*[13579]]], x2
; CHECK-DAG: mov [[NEW_LO:x[0-9]*[02468]]], x3
; CHECK-DAG: mov [[NEW_HI:x[0-9]*[13579]]], x4
; CHECK: caspal [[DESIRED_LO]], [[DESIRED_HI]], [[NEW_LO]], [[NEW_HI]], [x0]
%res = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
ret void
}