diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2016-08-29 22:25:36 +0000 | 
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2016-08-29 22:25:36 +0000 | 
| commit | 3d70a9dbb7d39e0e1ebf453153135f698bd201a4 (patch) | |
| tree | 1573b066cccc4e1cbcf625630f74f9a9dc10b972 /llvm/lib/Target | |
| parent | 8223a1d09f6bce6a31ae88efce44a72e394018f4 (diff) | |
| download | bcm5719-llvm-3d70a9dbb7d39e0e1ebf453153135f698bd201a4.tar.gz bcm5719-llvm-3d70a9dbb7d39e0e1ebf453153135f698bd201a4.zip | |
[PowerPC] Fix i8/i16 atomics for little-Endian targets without partword atomics
For little-Endian PowerPC, we generally target only P8 and later by default.
However, generic (older) 64-bit configurations are still an option, and in that
case, partword atomics are not available (e.g. stbcx.). To lower i8/i16 atomics
without true i8/i16 atomic operations, we emulate using i32 atomics in
combination with a bunch of shifting and masking, etc. The amount by which to
shift in little-Endian mode is different from the amount in big-Endian mode (it
is inverted -- meaning we can leave off the xor when computing the amount).
Fixes PR22923.
llvm-svn: 280022
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 18 | 
1 files changed, 12 insertions, 6 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index e89b6caa527..f895b06ac68 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -8513,6 +8513,7 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI,    // registers without caring whether they're 32 or 64, but here we're    // doing actual arithmetic on the addresses.    bool is64bit = Subtarget.isPPC64(); +  bool isLittleEndian = Subtarget.isLittleEndian();    unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;    const BasicBlock *LLVM_BB = BB->getBasicBlock(); @@ -8542,7 +8543,8 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI,                                            : &PPC::GPRCRegClass;    unsigned PtrReg = RegInfo.createVirtualRegister(RC);    unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); -  unsigned ShiftReg = RegInfo.createVirtualRegister(RC); +  unsigned ShiftReg = +    isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC);    unsigned Incr2Reg = RegInfo.createVirtualRegister(RC);    unsigned MaskReg = RegInfo.createVirtualRegister(RC);    unsigned Mask2Reg = RegInfo.createVirtualRegister(RC); @@ -8587,8 +8589,9 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI,    }    BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg)        .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); -  BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -      .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); +  if (!isLittleEndian) +    BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) +        .addReg(Shift1Reg).addImm(is8bit ? 24 : 16);    if (is64bit)      BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg)        .addReg(Ptr1Reg).addImm(0).addImm(61); @@ -9293,6 +9296,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,      // since we're actually doing arithmetic on them.  Other registers      // can be 32-bit.      bool is64bit = Subtarget.isPPC64(); +    bool isLittleEndian = Subtarget.isLittleEndian();      bool is8bit = MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;      unsigned dest = MI.getOperand(0).getReg(); @@ -9319,7 +9323,8 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,                                              : &PPC::GPRCRegClass;      unsigned PtrReg = RegInfo.createVirtualRegister(RC);      unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); -    unsigned ShiftReg = RegInfo.createVirtualRegister(RC); +    unsigned ShiftReg = +      isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC);      unsigned NewVal2Reg = RegInfo.createVirtualRegister(RC);      unsigned NewVal3Reg = RegInfo.createVirtualRegister(RC);      unsigned OldVal2Reg = RegInfo.createVirtualRegister(RC); @@ -9374,8 +9379,9 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,      }      BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg)          .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); -    BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) -        .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); +    if (!isLittleEndian) +      BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) +          .addReg(Shift1Reg).addImm(is8bit ? 24 : 16);      if (is64bit)        BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg)          .addReg(Ptr1Reg).addImm(0).addImm(61); | 

