From 6b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1 Mon Sep 17 00:00:00 2001 From: Wesley Peck Date: Wed, 22 Dec 2010 01:15:01 +0000 Subject: [PATCH] Add support for some of the LLVM atomic operations to the MBlaze backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122384 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MBlaze/MBlazeISelLowering.cpp | 492 ++++++++++++++++------- lib/Target/MBlaze/MBlazeISelLowering.h | 9 + lib/Target/MBlaze/MBlazeInstrInfo.td | 41 ++ 3 files changed, 386 insertions(+), 156 deletions(-) diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp index df5c416573b..5338fb742e4 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -175,7 +175,6 @@ MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM) // Use the default for now setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); // MBlaze doesn't have extending float->double load/store setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); @@ -213,172 +212,353 @@ SDValue MBlazeTargetLowering::LowerOperation(SDValue Op, //===----------------------------------------------------------------------===// MachineBasicBlock* MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - DebugLoc dl = MI->getDebugLoc(); - + MachineBasicBlock *MBB) + const { switch (MI->getOpcode()) { default: assert(false && "Unexpected instr type to insert"); + case MBlaze::ShiftRL: case MBlaze::ShiftRA: - case MBlaze::ShiftL: { - // To "insert" a shift left instruction, we actually have to insert a - // simple loop. The incoming instruction knows the destination vreg to - // set, the source vreg to operate over and the shift amount. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // start: - // andi samt, samt, 31 - // beqid samt, finish - // add dst, src, r0 - // loop: - // addik samt, samt, -1 - // sra dst, dst - // bneid samt, loop - // nop - // finish: - MachineFunction *F = BB->getParent(); - MachineRegisterInfo &R = F->getRegInfo(); - MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB); - F->insert(It, loop); - F->insert(It, finish); - - // Update machine-CFG edges by transfering adding all successors and - // remaining instructions from the current block to the new block which - // will contain the Phi node for the select. - finish->splice(finish->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - finish->transferSuccessorsAndUpdatePHIs(BB); - - // Add the true and fallthrough blocks as its successors. - BB->addSuccessor(loop); - BB->addSuccessor(finish); - - // Next, add the finish block as a successor of the loop block - loop->addSuccessor(finish); - loop->addSuccessor(loop); - - unsigned IAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(BB, dl, TII->get(MBlaze::ANDI), IAMT) - .addReg(MI->getOperand(2).getReg()) - .addImm(31); - - unsigned IVAL = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(BB, dl, TII->get(MBlaze::ADDIK), IVAL) - .addReg(MI->getOperand(1).getReg()) - .addImm(0); - - BuildMI(BB, dl, TII->get(MBlaze::BEQID)) - .addReg(IAMT) - .addMBB(finish); - - unsigned DST = R.createVirtualRegister(MBlaze::GPRRegisterClass); - unsigned NDST = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(loop, dl, TII->get(MBlaze::PHI), DST) - .addReg(IVAL).addMBB(BB) - .addReg(NDST).addMBB(loop); - - unsigned SAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - unsigned NAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT) - .addReg(IAMT).addMBB(BB) - .addReg(NAMT).addMBB(loop); - - if (MI->getOpcode() == MBlaze::ShiftL) - BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST); - else if (MI->getOpcode() == MBlaze::ShiftRA) - BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST); - else if (MI->getOpcode() == MBlaze::ShiftRL) - BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); - else - llvm_unreachable("Cannot lower unknown shift instruction"); - - BuildMI(loop, dl, TII->get(MBlaze::ADDIK), NAMT) - .addReg(SAMT) - .addImm(-1); - - BuildMI(loop, dl, TII->get(MBlaze::BNEID)) - .addReg(NAMT) - .addMBB(loop); - - BuildMI(*finish, finish->begin(), dl, - TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - .addReg(IVAL).addMBB(BB) - .addReg(NDST).addMBB(loop); - - // The pseudo instruction is no longer needed so remove it + case MBlaze::ShiftL: + return EmitCustomShift(MI, MBB); + + case MBlaze::Select_FCC: + case MBlaze::Select_CC: + return EmitCustomSelect(MI, MBB); + + case MBlaze::CAS32: + case MBlaze::SWP32: + case MBlaze::LAA32: + case MBlaze::LAS32: + case MBlaze::LAD32: + case MBlaze::LAO32: + case MBlaze::LAX32: + case MBlaze::LAN32: + return EmitCustomAtomic(MI, MBB); + + case MBlaze::MEMBARRIER: + // The Microblaze does not need memory barriers. Just delete the pseudo + // instruction and finish. MI->eraseFromParent(); - return finish; + return MBB; + } +} + +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomShift(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // To "insert" a shift left instruction, we actually have to insert a + // simple loop. The incoming instruction knows the destination vreg to + // set, the source vreg to operate over and the shift amount. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // start: + // andi samt, samt, 31 + // beqid samt, finish + // add dst, src, r0 + // loop: + // addik samt, samt, -1 + // sra dst, dst + // bneid samt, loop + // nop + // finish: + MachineFunction *F = MBB->getParent(); + MachineRegisterInfo &R = F->getRegInfo(); + MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, loop); + F->insert(It, finish); + + // Update machine-CFG edges by transfering adding all successors and + // remaining instructions from the current block to the new block which + // will contain the Phi node for the select. + finish->splice(finish->begin(), MBB, + llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + finish->transferSuccessorsAndUpdatePHIs(MBB); + + // Add the true and fallthrough blocks as its successors. + MBB->addSuccessor(loop); + MBB->addSuccessor(finish); + + // Next, add the finish block as a successor of the loop block + loop->addSuccessor(finish); + loop->addSuccessor(loop); + + unsigned IAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(MBB, dl, TII->get(MBlaze::ANDI), IAMT) + .addReg(MI->getOperand(2).getReg()) + .addImm(31); + + unsigned IVAL = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(MBB, dl, TII->get(MBlaze::ADDIK), IVAL) + .addReg(MI->getOperand(1).getReg()) + .addImm(0); + + BuildMI(MBB, dl, TII->get(MBlaze::BEQID)) + .addReg(IAMT) + .addMBB(finish); + + unsigned DST = R.createVirtualRegister(MBlaze::GPRRegisterClass); + unsigned NDST = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(loop, dl, TII->get(MBlaze::PHI), DST) + .addReg(IVAL).addMBB(MBB) + .addReg(NDST).addMBB(loop); + + unsigned SAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + unsigned NAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT) + .addReg(IAMT).addMBB(MBB) + .addReg(NAMT).addMBB(loop); + + if (MI->getOpcode() == MBlaze::ShiftL) + BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST); + else if (MI->getOpcode() == MBlaze::ShiftRA) + BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST); + else if (MI->getOpcode() == MBlaze::ShiftRL) + BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); + else + llvm_unreachable("Cannot lower unknown shift instruction"); + + BuildMI(loop, dl, TII->get(MBlaze::ADDIK), NAMT) + .addReg(SAMT) + .addImm(-1); + + BuildMI(loop, dl, TII->get(MBlaze::BNEID)) + .addReg(NAMT) + .addMBB(loop); + + BuildMI(*finish, finish->begin(), dl, + TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + .addReg(IVAL).addMBB(MBB) + .addReg(NDST).addMBB(loop); + + // The pseudo instruction is no longer needed so remove it + MI->eraseFromParent(); + return finish; +} + +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomSelect(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // To "insert" a SELECT_CC instruction, we actually have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // setcc r1, r2, r3 + // bNE r1, r0, copy1MBB + // fallthrough --> copy0MBB + MachineFunction *F = MBB->getParent(); + MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB); + + unsigned Opc; + switch (MI->getOperand(4).getImm()) { + default: llvm_unreachable("Unknown branch condition"); + case MBlazeCC::EQ: Opc = MBlaze::BEQID; break; + case MBlazeCC::NE: Opc = MBlaze::BNEID; break; + case MBlazeCC::GT: Opc = MBlaze::BGTID; break; + case MBlazeCC::LT: Opc = MBlaze::BLTID; break; + case MBlazeCC::GE: Opc = MBlaze::BGEID; break; + case MBlazeCC::LE: Opc = MBlaze::BLEID; break; + } + + F->insert(It, flsBB); + F->insert(It, dneBB); + + // Transfer the remainder of MBB and its successor edges to dneBB. + dneBB->splice(dneBB->begin(), MBB, + llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + dneBB->transferSuccessorsAndUpdatePHIs(MBB); + + MBB->addSuccessor(flsBB); + MBB->addSuccessor(dneBB); + flsBB->addSuccessor(dneBB); + + BuildMI(MBB, dl, TII->get(Opc)) + .addReg(MI->getOperand(3).getReg()) + .addMBB(dneBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB) + // .addReg(MI->getOperand(2).getReg()).addMBB(BB); + + BuildMI(*dneBB, dneBB->begin(), dl, + TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()).addMBB(flsBB) + .addReg(MI->getOperand(1).getReg()).addMBB(MBB); + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return dneBB; +} + +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomAtomic(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // All atomic instructions on the Microblaze are implemented using the + // load-linked / store-conditional style atomic instruction sequences. + // Thus, all operations will look something like the following: + // + // start: + // lwx RV, RP, 0 + // + // swx RV, RP, 0 + // addic RC, R0, 0 + // bneid RC, start + // + // exit: + // + // To "insert" a shift left instruction, we actually have to insert a + // simple loop. The incoming instruction knows the destination vreg to + // set, the source vreg to operate over and the shift amount. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // start: + // andi samt, samt, 31 + // beqid samt, finish + // add dst, src, r0 + // loop: + // addik samt, samt, -1 + // sra dst, dst + // bneid samt, loop + // nop + // finish: + MachineFunction *F = MBB->getParent(); + MachineRegisterInfo &R = F->getRegInfo(); + + // Create the start and exit basic blocks for the atomic operation + MachineBasicBlock *start = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exit = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, start); + F->insert(It, exit); + + // Update machine-CFG edges by transfering adding all successors and + // remaining instructions from the current block to the new block which + // will contain the Phi node for the select. + exit->splice(exit->begin(), MBB, llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + exit->transferSuccessorsAndUpdatePHIs(MBB); + + // Add the fallthrough block as its successors. + MBB->addSuccessor(start); + + BuildMI(start, dl, TII->get(MBlaze::LWX), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addReg(MBlaze::R0); + + MachineBasicBlock *final = start; + unsigned finalReg = 0; + + switch (MI->getOpcode()) { + default: llvm_unreachable("Cannot lower unknown atomic instruction!"); + + case MBlaze::SWP32: + finalReg = MI->getOperand(2).getReg(); + start->addSuccessor(exit); + start->addSuccessor(start); + break; + + case MBlaze::LAN32: + case MBlaze::LAX32: + case MBlaze::LAO32: + case MBlaze::LAD32: + case MBlaze::LAS32: + case MBlaze::LAA32: { + unsigned opcode = 0; + switch (MI->getOpcode()) { + default: llvm_unreachable("Cannot lower unknown atomic load!"); + case MBlaze::LAA32: opcode = MBlaze::ADDIK; break; + case MBlaze::LAS32: opcode = MBlaze::RSUBIK; break; + case MBlaze::LAD32: opcode = MBlaze::AND; break; + case MBlaze::LAO32: opcode = MBlaze::OR; break; + case MBlaze::LAX32: opcode = MBlaze::XOR; break; + case MBlaze::LAN32: opcode = MBlaze::AND; break; } - case MBlaze::Select_FCC: - case MBlaze::Select_CC: { - // To "insert" a SELECT_CC instruction, we actually have to insert the - // diamond control-flow pattern. The incoming instruction knows the - // destination vreg to set, the condition code register to branch on, the - // true/false values to select between, and a branch opcode to use. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // setcc r1, r2, r3 - // bNE r1, r0, copy1MBB - // fallthrough --> copy0MBB - MachineFunction *F = BB->getParent(); - MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB); - - unsigned Opc; - switch (MI->getOperand(4).getImm()) { - default: llvm_unreachable("Unknown branch condition"); - case MBlazeCC::EQ: Opc = MBlaze::BEQID; break; - case MBlazeCC::NE: Opc = MBlaze::BNEID; break; - case MBlazeCC::GT: Opc = MBlaze::BGTID; break; - case MBlazeCC::LT: Opc = MBlaze::BLTID; break; - case MBlazeCC::GE: Opc = MBlaze::BGEID; break; - case MBlazeCC::LE: Opc = MBlaze::BLEID; break; + finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass); + start->addSuccessor(exit); + start->addSuccessor(start); + + BuildMI(start, dl, TII->get(opcode), finalReg) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()); + + if (MI->getOpcode() == MBlaze::LAN32) { + unsigned tmp = finalReg; + finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(start, dl, TII->get(MBlaze::XORI), finalReg) + .addReg(tmp) + .addImm(-1); } + break; + } + + case MBlaze::CAS32: { + finalReg = MI->getOperand(3).getReg(); + final = F->CreateMachineBasicBlock(LLVM_BB); + + F->insert(It, final); + start->addSuccessor(exit); + start->addSuccessor(final); + final->addSuccessor(exit); + final->addSuccessor(start); + + unsigned CMP = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(start, dl, TII->get(MBlaze::CMP), CMP) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()); - F->insert(It, flsBB); - F->insert(It, dneBB); - - // Transfer the remainder of BB and its successor edges to dneBB. - dneBB->splice(dneBB->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - dneBB->transferSuccessorsAndUpdatePHIs(BB); - - BB->addSuccessor(flsBB); - BB->addSuccessor(dneBB); - flsBB->addSuccessor(dneBB); - - BuildMI(BB, dl, TII->get(Opc)) - .addReg(MI->getOperand(3).getReg()) - .addMBB(dneBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB) - // .addReg(MI->getOperand(2).getReg()).addMBB(BB); - - BuildMI(*dneBB, dneBB->begin(), dl, - TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - .addReg(MI->getOperand(2).getReg()).addMBB(flsBB) - .addReg(MI->getOperand(1).getReg()).addMBB(BB); - - MI->eraseFromParent(); // The pseudo instruction is gone now. - return dneBB; + BuildMI(start, dl, TII->get(MBlaze::BNEID)) + .addReg(CMP) + .addMBB(exit); + + final->moveAfter(start); + exit->moveAfter(final); + break; } } + + unsigned CHK = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(final, dl, TII->get(MBlaze::SWX)) + .addReg(finalReg) + .addReg(MI->getOperand(1).getReg()) + .addReg(MBlaze::R0); + + BuildMI(final, dl, TII->get(MBlaze::ADDIC), CHK) + .addReg(MBlaze::R0) + .addImm(0); + + BuildMI(final, dl, TII->get(MBlaze::BNEID)) + .addReg(CHK) + .addMBB(start); + + // The pseudo instruction is no longer needed so remove it + MI->eraseFromParent(); + return exit; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeISelLowering.h b/lib/Target/MBlaze/MBlazeISelLowering.h index aa1c9aa3aa5..91649bc6db0 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.h +++ b/lib/Target/MBlaze/MBlazeISelLowering.h @@ -149,6 +149,15 @@ namespace llvm { const SmallVectorImpl &OutVals, DebugLoc dl, SelectionDAG &DAG) const; + virtual MachineBasicBlock* + EmitCustomShift(MachineInstr *MI, MachineBasicBlock *MBB) const; + + virtual MachineBasicBlock* + EmitCustomSelect(MachineInstr *MI, MachineBasicBlock *MBB) const; + + virtual MachineBasicBlock* + EmitCustomAtomic(MachineInstr *MI, MachineBasicBlock *MBB) const; + virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index a75e1664da1..990b95da31b 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -668,6 +668,47 @@ def BRKI : BranchLI<0x2E, 0x0C, "brki ">; def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), "imm $imm", [], IIAlu>; +//===----------------------------------------------------------------------===// +// Pseudo instructions for atomic operations +//===----------------------------------------------------------------------===// +let usesCustomInserter=1 in { + def CAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$cmp, GPR:$swp), + "# atomic compare and swap", + [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$cmp, GPR:$swp))]>; + + def SWP32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$swp), + "# atomic swap", + [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$swp))]>; + + def LAA32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and add", + [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$val))]>; + + def LAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and sub", + [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$val))]>; + + def LAD32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and and", + [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$val))]>; + + def LAO32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and or", + [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$val))]>; + + def LAX32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and xor", + [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$val))]>; + + def LAN32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and nand", + [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$val))]>; + + def MEMBARRIER : MBlazePseudo<(outs), (ins), + "# memory barrier", + [(membarrier (i32 imm), (i32 imm), (i32 imm), (i32 imm), (i32 imm))]>; +} + //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// -- 2.34.1