diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86MCInstLower.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 6ed9a533d51..9de2d18e0be 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -1680,6 +1680,77 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { case X86::TLS_base_addr64: return LowerTlsAddr(MCInstLowering, *MI); + // Loading/storing mask pairs requires two kmov operations. The second one of these + // needs a 2 byte displacement relative to the specified address (with 32 bit spill + // size). The pairs of 1bit masks up to 16 bit masks all use the same spill size, + // they all are stored using MASKPAIR16STORE, loaded using MASKPAIR16LOAD. + // + // The displacement value might wrap around in theory, thus the asserts in both + // cases. + case X86::MASKPAIR16LOAD: { + int64_t Disp = MI->getOperand(1 + X86::AddrDisp).getImm(); + assert(Disp >= 0 && Disp <= INT32_MAX - 2 && "Unexpected displacement"); + const X86RegisterInfo *RI = + MF->getSubtarget<X86Subtarget>().getRegisterInfo(); + unsigned Reg = MI->getOperand(0).getReg(); + unsigned Reg0 = RI->getSubReg(Reg, X86::sub_mask_0); + unsigned Reg1 = RI->getSubReg(Reg, X86::sub_mask_1); + + // Load the first mask register + MCInstBuilder MIB = MCInstBuilder(X86::KMOVWkm); + MIB.addReg(Reg0); + for (int i = 0; i < X86::AddrNumOperands; ++i) { + auto Op = MCInstLowering.LowerMachineOperand(MI, MI->getOperand(1 + i)); + MIB.addOperand(Op.getValue()); + } + EmitAndCountInstruction(MIB); + + // Load the second mask register of the pair + MIB = MCInstBuilder(X86::KMOVWkm); + MIB.addReg(Reg1); + for (int i = 0; i < X86::AddrNumOperands; ++i) { + if (i == X86::AddrDisp) { + MIB.addImm(Disp + 2); + } else { + auto Op = MCInstLowering.LowerMachineOperand(MI, MI->getOperand(1 + i)); + MIB.addOperand(Op.getValue()); + } + } + EmitAndCountInstruction(MIB); + return; + } + + case X86::MASKPAIR16STORE: { + int64_t Disp = MI->getOperand(X86::AddrDisp).getImm(); + assert(Disp >= 0 && Disp <= INT32_MAX - 2 && "Unexpected displacement"); + const X86RegisterInfo *RI = + MF->getSubtarget<X86Subtarget>().getRegisterInfo(); + unsigned Reg = MI->getOperand(X86::AddrNumOperands).getReg(); + unsigned Reg0 = RI->getSubReg(Reg, X86::sub_mask_0); + unsigned Reg1 = RI->getSubReg(Reg, X86::sub_mask_1); + + // Store the first mask register + MCInstBuilder MIB = MCInstBuilder(X86::KMOVWmk); + for (int i = 0; i < X86::AddrNumOperands; ++i) + MIB.addOperand(MCInstLowering.LowerMachineOperand(MI, MI->getOperand(i)).getValue()); + MIB.addReg(Reg0); + EmitAndCountInstruction(MIB); + + // Store the second mask register of the pair + MIB = MCInstBuilder(X86::KMOVWmk); + for (int i = 0; i < X86::AddrNumOperands; ++i) { + if (i == X86::AddrDisp) { + MIB.addImm(Disp + 2); + } else { + auto Op = MCInstLowering.LowerMachineOperand(MI, MI->getOperand(0 + i)); + MIB.addOperand(Op.getValue()); + } + } + MIB.addReg(Reg1); + EmitAndCountInstruction(MIB); + return; + } + case X86::MOVPC32r: { // This is a pseudo op for a two instruction sequence with a label, which // looks like: |

