https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/111671
None >From 73aec534d3b1b320855a08638ce5ef410a5de11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 9 Oct 2024 14:55:12 +0200 Subject: [PATCH] [clang][bytecode] Implement __builtin_ai32_addcarryx* --- clang/lib/AST/ByteCode/Function.h | 4 ++ clang/lib/AST/ByteCode/InterpBuiltin.cpp | 50 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h index 640bfa65644f0f..7fe9aeb1101204 100644 --- a/clang/lib/AST/ByteCode/Function.h +++ b/clang/lib/AST/ByteCode/Function.h @@ -222,6 +222,10 @@ class Function final { return ParamOffsets[ParamIndex]; } + PrimType getParamType(unsigned ParamIndex) const { + return ParamTypes[ParamIndex]; + } + private: /// Construct a function representing an actual function. Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 98381254886e29..7d811b7baea7ce 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -38,6 +38,15 @@ static T getParam(const InterpFrame *Frame, unsigned Index) { return Frame->getParam<T>(Offset); } +// static APSInt getAPSIntParam(InterpStack &Stk, size_t Offset = 0) { +static APSInt getAPSIntParam(const InterpFrame *Frame, unsigned Index) { + APSInt R; + unsigned Offset = Frame->getFunction()->getParamOffset(Index); + INT_TYPE_SWITCH(Frame->getFunction()->getParamType(Index), + R = Frame->getParam<T>(Offset).toAPSInt()); + return R; +} + PrimType getIntPrimType(const InterpState &S) { const TargetInfo &TI = S.getASTContext().getTargetInfo(); unsigned IntWidth = TI.getIntWidth(); @@ -1273,6 +1282,39 @@ static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, + CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, + const CallExpr *Call) { + unsigned BuiltinOp = Func->getBuiltinID(); + APSInt CarryIn = getAPSIntParam(Frame, 0); + APSInt LHS = getAPSIntParam(Frame, 1); + APSInt RHS = getAPSIntParam(Frame, 2); + + bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 || + BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64; + + unsigned BitWidth = LHS.getBitWidth(); + unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0; + APInt ExResult = + IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit)) + : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit)); + + APInt Result = ExResult.extractBits(BitWidth, 0); + APSInt CarryOut = + APSInt(ExResult.extractBits(1, BitWidth), /*IsUnsigned=*/true); + + Pointer &CarryOutPtr = S.Stk.peek<Pointer>(); + QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); + PrimType CarryOutT = *S.getContext().classify(CarryOutType); + assignInteger(CarryOutPtr, CarryOutT, APSInt(Result, true)); + + pushInteger(S, CarryOut, Call->getType()); + + return true; +} + static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, @@ -1898,6 +1940,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case clang::X86::BI__builtin_ia32_addcarryx_u32: + case clang::X86::BI__builtin_ia32_addcarryx_u64: + case clang::X86::BI__builtin_ia32_subborrow_u32: + case clang::X86::BI__builtin_ia32_subborrow_u64: + if (!interp__builtin_ia32_addcarry_subborrow(S, OpPC, Frame, F, Call)) + return false; + break; + case Builtin::BI__builtin_os_log_format_buffer_size: if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call)) return false; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits