mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01: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:
parent
5df33b90f1
commit
009fdea45c
@ -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)>{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
17
test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll
Normal file
17
test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user