8
8
9
9
#include " AsmMigration.h"
10
10
#include " AnalysisInfo.h"
11
+ #include " Diagnostics/Diagnostics.h"
12
+ #include " ErrorHandle/CrashRecovery.h"
13
+ #include " RuleInfra/MapNames.h"
11
14
#include " RulesAsm/Parser/AsmNodes.h"
12
15
#include " RulesAsm/Parser/AsmParser.h"
13
16
#include " RulesAsm/Parser/AsmTokenKinds.h"
14
- #include " ErrorHandle/CrashRecovery.h"
15
- #include " Diagnostics/Diagnostics.h"
16
- #include " RuleInfra/MapNames.h"
17
17
#include " TextModification.h"
18
18
#include " Utility.h"
19
19
#include " clang/AST/Expr.h"
@@ -609,7 +609,7 @@ bool SYCLGenBase::emitAddressExpr(const InlineAsmAddressExpr *Dst) {
609
609
return false ;
610
610
};
611
611
612
- if (CurrInst->is (asmtok::op_st, asmtok:: op_ld, asmtok::op_red))
612
+ if (CurrInst->is (asmtok::op_ld, asmtok::op_red))
613
613
OS () << " *" ;
614
614
switch (Dst->getMemoryOpKind ()) {
615
615
case InlineAsmAddressExpr::Imm:
@@ -632,8 +632,12 @@ bool SYCLGenBase::emitAddressExpr(const InlineAsmAddressExpr *Dst) {
632
632
std::string Reg;
633
633
if (tryEmitStmt (Reg, Dst->getSymbol ()))
634
634
return SYCLGenSuccess ();
635
- OS () << llvm::formatv (" (({0} *)((uintptr_t){1} + {2}))" , Type, Reg,
636
- Dst->getImmAddr ()->getValue ().getZExtValue ());
635
+
636
+ if (CurrInst->is (asmtok::op_st))
637
+ OS () << llvm::formatv (" (uintptr_t){0}" , Reg);
638
+ else
639
+ OS () << llvm::formatv (" (({0} *)((uintptr_t){1} + {2}))" , Type, Reg,
640
+ Dst->getImmAddr ()->getValue ().getZExtValue ());
637
641
break ;
638
642
}
639
643
case InlineAsmAddressExpr::Var: {
@@ -2690,24 +2694,98 @@ class SYCLGen : public SYCLGenBase {
2690
2694
return SYCLGenSuccess ();
2691
2695
}
2692
2696
2697
+ bool HandleStVec (const InlineAsmInstruction *Inst, int VecNum) {
2698
+ std::string Ops;
2699
+ if (tryEmitStmt (Ops, Inst->getInputOperand (0 )))
2700
+ return SYCLGenError ();
2701
+
2702
+ // To extract the values from the string like "{x, y, z, w}" and store them
2703
+ // int Values vector
2704
+ std::vector<std::string> Values;
2705
+ size_t start = 1 ; // Skip the '{' character
2706
+ size_t end = Ops.find (' ,' , start); // Find the first comma
2707
+
2708
+ while (end != std::string::npos) {
2709
+ std::string Token = Ops.substr (start, end - start);
2710
+ size_t First = Token.find_first_not_of (' ' );
2711
+ size_t Last = Token.find_last_not_of (' ' );
2712
+ if (First != std::string::npos && Last != std::string::npos) {
2713
+ Values.push_back (Token.substr (First, Last - First + 1 ));
2714
+ }
2715
+ start = end + 1 ;
2716
+ end = Ops.find (' ,' , start);
2717
+ }
2718
+
2719
+ // Extract the last value after the last comma
2720
+ std::string token = Ops.substr (start, Ops.size () - start - 1 );
2721
+ size_t first = token.find_first_not_of (' ' );
2722
+ size_t last = token.find_last_not_of (' ' );
2723
+
2724
+ if (first != std::string::npos && last != std::string::npos) {
2725
+ Values.push_back (token.substr (first, last - first + 1 ));
2726
+ }
2727
+
2728
+ std::string Output;
2729
+ if (tryEmitStmt (Output, Inst->getOutputOperand ()))
2730
+ return SYCLGenError ();
2731
+
2732
+ std::string Type;
2733
+ if (tryEmitType (Type, Inst->getType (0 )))
2734
+ return SYCLGenError ();
2735
+
2736
+ const auto *Dst =
2737
+ dyn_cast_or_null<InlineAsmAddressExpr>(Inst->getOutputOperand ());
2738
+ if (!Dst)
2739
+ return SYCLGenError ();
2740
+
2741
+ for (int Index = 0 ; Index < VecNum; Index++) {
2742
+ OS () << llvm::formatv (" *(({0} *)({1}) + {2}) = {3}{4}" , Type, Output,
2743
+ Index, Values[Index],
2744
+ Index == VecNum - 1 ? " " : " ;\n " );
2745
+ }
2746
+
2747
+ endstmt ();
2748
+ return SYCLGenSuccess ();
2749
+ }
2750
+
2693
2751
bool handle_st (const InlineAsmInstruction *Inst) override {
2694
2752
if (Inst->getNumInputOperands () != 1 )
2695
2753
return SYCLGenError ();
2696
- llvm::SaveAndRestore<const InlineAsmInstruction *> Store (CurrInst);
2697
- CurrInst = Inst;
2754
+
2755
+ llvm::SaveAndRestore<const InlineAsmInstruction *> Store (CurrInst, Inst);
2756
+
2757
+ if (Inst->hasAttr (InstAttr::cs)) {
2758
+ if (Inst->hasAttr (InstAttr::v4))
2759
+ return HandleStVec (Inst, 4 );
2760
+ if (Inst->hasAttr (InstAttr::v2))
2761
+ return HandleStVec (Inst, 2 );
2762
+ }
2763
+
2698
2764
const auto *Src = Inst->getInputOperand (0 );
2699
2765
const auto *Dst =
2700
2766
dyn_cast_or_null<InlineAsmAddressExpr>(Inst->getOutputOperand ());
2701
2767
if (!Dst)
2702
- return false ;
2768
+ return SYCLGenError ();
2769
+
2703
2770
std::string Type;
2704
2771
if (tryEmitType (Type, Inst->getType (0 )))
2705
2772
return SYCLGenError ();
2706
- if (emitStmt (Dst))
2773
+
2774
+ std::string OutOp;
2775
+ if (tryEmitStmt (OutOp, Inst->getOutputOperand ()))
2707
2776
return SYCLGenError ();
2777
+
2778
+ if (Dst->getMemoryOpKind () == InlineAsmAddressExpr::RegImm) {
2779
+ OS () << llvm::formatv (" *(({0} *)({1} + {2}))" , Type, OutOp,
2780
+ Dst->getImmAddr ()->getValue ().getZExtValue ());
2781
+ } else {
2782
+ OS () << " *" << OutOp;
2783
+ }
2784
+
2708
2785
OS () << " = " ;
2709
2786
if (emitStmt (Src))
2710
2787
return SYCLGenError ();
2788
+
2711
2789
endstmt ();
2712
2790
return SYCLGenSuccess ();
2713
2791
}
@@ -2722,7 +2800,7 @@ class SYCLGen : public SYCLGenBase {
2722
2800
const auto *Dst = Inst->getOutputOperand ();
2723
2801
2724
2802
if (!Src)
2725
- return false ;
2803
+ return SYCLGenError () ;
2726
2804
std::string Type;
2727
2805
if (tryEmitType (Type, Inst->getType (0 )))
2728
2806
return SYCLGenError ();
0 commit comments