diff options
author | John Brawn <john.brawn@arm.com> | 2024-06-07 10:38:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-07 10:38:23 +0100 |
commit | 1721c14e8e0d75cc611067b6f4e84028ea7c47d5 (patch) | |
tree | 36e3b7daa4327c02b7a0352310532c59ef258829 /llvm/lib/CodeGen | |
parent | 0d1b3671a91c3929fc3e3613491ff4b57f1adcc3 (diff) | |
download | llvm-1721c14e8e0d75cc611067b6f4e84028ea7c47d5.zip llvm-1721c14e8e0d75cc611067b6f4e84028ea7c47d5.tar.gz llvm-1721c14e8e0d75cc611067b6f4e84028ea7c47d5.tar.bz2 |
[DebugInfo] Add DW_OP_LLVM_extract_bits (#93990)
This operation extracts a number of bits at a given offset and sign or
zero extends them, which is done by emitting it as a left shift followed
by a right shift.
This is being added for use in clang for C++ structured bindings of
bitfields that have offset or size that aren't a byte multiple. A new
operation is being added, instead of shifts being used directly, as it
makes correctly handling it in optimisations (which will be done in a
later patch) much easier.
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index a74d438..cc96d3c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/Register.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/DataLayout.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -546,6 +547,37 @@ bool DwarfExpression::addExpression( LocationKind = Unknown; return true; } + case dwarf::DW_OP_LLVM_extract_bits_sext: + case dwarf::DW_OP_LLVM_extract_bits_zext: { + unsigned SizeInBits = Op->getArg(1); + unsigned BitOffset = Op->getArg(0); + + // If we have a memory location then dereference to get the value + if (isMemoryLocation()) + emitOp(dwarf::DW_OP_deref); + + // Extract the bits by a shift left (to shift out the bits after what we + // want to extract) followed by shift right (to shift the bits to position + // 0 and also sign/zero extend). These operations are done in the DWARF + // "generic type" whose size is the size of a pointer. + unsigned PtrSizeInBytes = CU.getAsmPrinter()->MAI->getCodePointerSize(); + unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset); + unsigned RightShift = LeftShift + BitOffset; + if (LeftShift) { + emitOp(dwarf::DW_OP_constu); + emitUnsigned(LeftShift); + emitOp(dwarf::DW_OP_shl); + } + emitOp(dwarf::DW_OP_constu); + emitUnsigned(RightShift); + emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra + : dwarf::DW_OP_shr); + + // The value is now at the top of the stack, so set the location to + // implicit so that we get a stack_value at the end. + LocationKind = Implicit; + break; + } case dwarf::DW_OP_plus_uconst: assert(!isRegisterLocation()); emitOp(dwarf::DW_OP_plus_uconst); |