@@ -519,6 +519,42 @@ class MCCFIInstruction {
519519 OpGnuArgsSize,
520520 OpLabel,
521521 OpValOffset,
522+ OpLLVMRegisterPair,
523+ OpLLVMVectorRegisters,
524+ OpLLVMVectorOffset,
525+ OpLLVMVectorRegisterMask,
526+ };
527+
528+ // / Some extra fields used when Operation is OpLLVMRegisterPair.
529+ struct RegisterPairExtraFields {
530+ unsigned Reg1, Reg2;
531+ unsigned Reg1SizeInBits, Reg2SizeInBits;
532+ };
533+
534+ struct VectorRegisterWithLane {
535+ unsigned Register;
536+ unsigned Lane;
537+ unsigned SizeInBits;
538+ };
539+
540+ // / Some extra fields used when Operation is OpLLVMVectorRegisters.
541+ struct VectorRegistersExtraFields {
542+ std::vector<VectorRegisterWithLane> VectorRegisters;
543+ };
544+
545+ // / Some extra fields used when Operation is OpLLVMVectorOffset.
546+ struct VectorOffsetExtraFields {
547+ unsigned MaskRegister;
548+ unsigned MaskRegisterSizeInBits;
549+ unsigned RegisterSizeInBits;
550+ };
551+
552+ // / Some extra fields used when Operation is OpLLVMVectorRegisterMask.
553+ struct VectorRegisterMaskExtraFields {
554+ unsigned SpillRegister;
555+ unsigned SpillRegisterLaneSizeInBits;
556+ unsigned MaskRegister;
557+ unsigned MaskRegisterSizeInBits;
522558 };
523559
524560private:
@@ -544,6 +580,14 @@ class MCCFIInstruction {
544580 std::vector<char > Values;
545581 std::string Comment;
546582
583+ // FIXME: We could probably save some space and complexity by moving all
584+ // Operation-specific fields to this variant. Leaving them as-is for now to
585+ // avoid a diff with upstream.
586+ std::variant<std::monostate, RegisterPairExtraFields,
587+ VectorRegistersExtraFields, VectorOffsetExtraFields,
588+ VectorRegisterMaskExtraFields>
589+ ExtraFields;
590+
547591 MCCFIInstruction (OpType Op, MCSymbol *L, unsigned R, int64_t O, SMLoc Loc,
548592 StringRef V = " " , StringRef Comment = " " )
549593 : Label(L), Operation(Op), Loc(Loc), Values(V.begin(), V.end()),
@@ -563,6 +607,14 @@ class MCCFIInstruction {
563607 U.RIA = {R, O, AS};
564608 }
565609
610+ template <class ExtraFieldsTy >
611+ MCCFIInstruction (OpType Op, MCSymbol *L, unsigned R, int O,
612+ ExtraFieldsTy &&ExtraFields, SMLoc Loc)
613+ : Label(L), Operation(Op), Loc(Loc),
614+ ExtraFields(std::forward<ExtraFieldsTy>(ExtraFields)) {
615+ U.RI = {R, O};
616+ }
617+
566618 MCCFIInstruction (OpType Op, MCSymbol *L, MCSymbol *CfiLabel, SMLoc Loc)
567619 : Label(L), Operation(Op), Loc(Loc) {
568620 assert (Op == OpLabel);
@@ -700,6 +752,62 @@ class MCCFIInstruction {
700752 return MCCFIInstruction (OpLabel, L, CfiLabel, Loc);
701753 }
702754
755+ // / .cfi_llvm_register_pair Previous value of Register is saved in R1:R2.
756+ static MCCFIInstruction
757+ createLLVMRegisterPair (MCSymbol *L, unsigned Register, unsigned R1,
758+ unsigned R1SizeInBits, unsigned R2,
759+ unsigned R2SizeInBits, SMLoc Loc = {}) {
760+ RegisterPairExtraFields Extra{R1, R2, R1SizeInBits, R2SizeInBits};
761+ return MCCFIInstruction (OpLLVMRegisterPair, L, Register, 0 , Extra, Loc);
762+ }
763+
764+ // / .cfi_llvm_vector_registers Previous value of Register is saved in lanes of
765+ // / vector registers.
766+ static MCCFIInstruction
767+ createLLVMVectorRegisters (MCSymbol *L, unsigned Register,
768+ std::vector<VectorRegisterWithLane> VectorRegisters,
769+ SMLoc Loc = {}) {
770+ VectorRegistersExtraFields Extra{std::move (VectorRegisters)};
771+ return MCCFIInstruction (OpLLVMVectorRegisters, L, Register, 0 ,
772+ std::move (Extra), Loc);
773+ }
774+
775+ // / .cfi_llvm_vector_offset Previous value of Register is saved at Offset from
776+ // / CFA. MaskRegister specifies the active lanes of register.
777+ static MCCFIInstruction
778+ createLLVMVectorOffset (MCSymbol *L, unsigned Register,
779+ unsigned RegisterSizeInBits, unsigned MaskRegister,
780+ unsigned MaskRegisterSizeInBits, int Offset,
781+ SMLoc Loc = {}) {
782+ VectorOffsetExtraFields Extra{MaskRegister, MaskRegisterSizeInBits,
783+ RegisterSizeInBits};
784+ return MCCFIInstruction (OpLLVMVectorOffset, L, Register, Offset, Extra,
785+ Loc);
786+ }
787+
788+ // / .cfi_llvm_vector_register_mask Previous value of Register is saved in
789+ // / SpillRegister, predicated on the value of MaskRegister.
790+ static MCCFIInstruction createLLVMVectorRegisterMask (
791+ MCSymbol *L, unsigned Register, unsigned SpillRegister,
792+ unsigned SpillRegisterLaneSizeInBits, unsigned MaskRegister,
793+ unsigned MaskRegisterSizeInBits, SMLoc Loc = {}) {
794+ VectorRegisterMaskExtraFields Extra{
795+ SpillRegister,
796+ SpillRegisterLaneSizeInBits,
797+ MaskRegister,
798+ MaskRegisterSizeInBits,
799+ };
800+ return MCCFIInstruction (OpLLVMVectorRegisterMask, L, Register, 0 ,
801+ std::move (Extra), Loc);
802+ }
803+
804+ template <class ExtraFieldsTy > ExtraFieldsTy &getExtraFields () {
805+ return std::get<ExtraFieldsTy>(ExtraFields);
806+ }
807+
808+ template <class ExtraFieldsTy > const ExtraFieldsTy &getExtraFields () const {
809+ return std::get<ExtraFieldsTy>(ExtraFields);
810+ }
703811 // / .cfi_val_offset Previous value of Register is offset Offset from the
704812 // / current CFA register.
705813 static MCCFIInstruction createValOffset (MCSymbol *L, unsigned Register,
@@ -718,6 +826,9 @@ class MCCFIInstruction {
718826 assert (Operation == OpDefCfa || Operation == OpOffset ||
719827 Operation == OpRestore || Operation == OpUndefined ||
720828 Operation == OpSameValue || Operation == OpDefCfaRegister ||
829+ Operation == OpLLVMVectorRegisters ||
830+ Operation == OpLLVMRegisterPair || Operation == OpLLVMVectorOffset ||
831+ Operation == OpLLVMVectorRegisterMask ||
721832 Operation == OpRelOffset || Operation == OpValOffset);
722833 return U.RI .Register ;
723834 }
@@ -738,6 +849,7 @@ class MCCFIInstruction {
738849 assert (Operation == OpDefCfa || Operation == OpOffset ||
739850 Operation == OpRelOffset || Operation == OpDefCfaOffset ||
740851 Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize ||
852+ Operation == OpLLVMVectorOffset ||
741853 Operation == OpValOffset);
742854 return U.RI .Offset ;
743855 }
@@ -754,6 +866,9 @@ class MCCFIInstruction {
754866
755867 StringRef getComment () const { return Comment; }
756868 SMLoc getLoc () const { return Loc; }
869+
870+ // / Replaces in place all references to FromReg with ToReg.
871+ void replaceRegister (unsigned FromReg, unsigned ToReg);
757872};
758873
759874struct MCDwarfFrameInfo {
0 commit comments