@@ -34,6 +34,19 @@ PrimType getIntPrimType(const InterpState &S) {
34
34
llvm_unreachable (" Int isn't 16 or 32 bit?" );
35
35
}
36
36
37
+ PrimType getLongPrimType (const InterpState &S) {
38
+ const TargetInfo &TI = S.getCtx ().getTargetInfo ();
39
+ unsigned LongWidth = TI.getLongWidth ();
40
+
41
+ if (LongWidth == 64 )
42
+ return PT_Sint64;
43
+ else if (LongWidth == 32 )
44
+ return PT_Sint32;
45
+ else if (LongWidth == 16 )
46
+ return PT_Sint16;
47
+ llvm_unreachable (" long isn't 16, 32 or 64 bit?" );
48
+ }
49
+
37
50
// / Peek an integer value from the stack into an APSInt.
38
51
static APSInt peekToAPSInt (InterpStack &Stk, PrimType T, size_t Offset = 0 ) {
39
52
if (Offset == 0 )
@@ -110,6 +123,19 @@ static void pushAPSInt(InterpState &S, const APSInt &Val) {
110
123
}
111
124
}
112
125
126
+ // / Pushes \p Val to the stack, as a target-dependent 'long'.
127
+ static void pushLong (InterpState &S, int64_t Val) {
128
+ PrimType LongType = getLongPrimType (S);
129
+ if (LongType == PT_Sint64)
130
+ S.Stk .push <Integral<64 , true >>(Integral<64 , true >::from (Val));
131
+ else if (LongType == PT_Sint32)
132
+ S.Stk .push <Integral<32 , true >>(Integral<32 , true >::from (Val));
133
+ else if (LongType == PT_Sint16)
134
+ S.Stk .push <Integral<16 , true >>(Integral<16 , true >::from (Val));
135
+ else
136
+ llvm_unreachable (" Long isn't 16, 32 or 64 bit?" );
137
+ }
138
+
113
139
static void pushSizeT (InterpState &S, uint64_t Val) {
114
140
const TargetInfo &TI = S.getCtx ().getTargetInfo ();
115
141
unsigned SizeTWidth = TI.getTypeWidth (TI.getSizeType ());
@@ -533,6 +559,26 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
533
559
return true ;
534
560
}
535
561
562
+ // __builtin_expect(long, long)
563
+ // __builtin_expect_with_probability(long, long, double)
564
+ static bool interp__builtin_expect (InterpState &S, CodePtr OpPC,
565
+ const InterpFrame *Frame,
566
+ const Function *Func, const CallExpr *Call) {
567
+ // The return value is simply the value of the first parameter.
568
+ // We ignore the probability.
569
+ unsigned NumArgs = Call->getNumArgs ();
570
+ assert (NumArgs == 2 || NumArgs == 3 );
571
+
572
+ PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
573
+ unsigned Offset = align (primSize (getLongPrimType (S))) * 2 ;
574
+ if (NumArgs == 3 )
575
+ Offset += align (primSize (PT_Float));
576
+
577
+ APSInt Val = peekToAPSInt (S.Stk , ArgT, Offset);
578
+ pushLong (S, Val.getSExtValue ());
579
+ return true ;
580
+ }
581
+
536
582
bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
537
583
const CallExpr *Call) {
538
584
InterpFrame *Frame = S.Current ;
@@ -702,6 +748,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
702
748
return false ;
703
749
break ;
704
750
751
+ case Builtin::BI__builtin_expect:
752
+ case Builtin::BI__builtin_expect_with_probability:
753
+ if (!interp__builtin_expect (S, OpPC, Frame, F, Call))
754
+ return false ;
755
+ break ;
756
+
705
757
default :
706
758
return false ;
707
759
}
0 commit comments