[llvm] r233191 - [ARM] Rewrite .save/.vsave emission with bit math
Benjamin Kramer
benny.kra at googlemail.com
Wed Mar 25 08:27:58 PDT 2015
Author: d0k
Date: Wed Mar 25 10:27:58 2015
New Revision: 233191
URL: http://llvm.org/viewvc/llvm-project?rev=233191&view=rev
Log:
[ARM] Rewrite .save/.vsave emission with bit math
Hopefully makes it a bit easier to understand what's going on.
No functional change intended.
Modified:
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp?rev=233191&r1=233190&r2=233191&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp Wed Mar 25 10:27:58 2015
@@ -72,14 +72,10 @@ void UnwindOpcodeAssembler::EmitRegSave(
// opcode when r4 is not in .save directive.
// Compute the consecutive registers from r4 to r11.
- uint32_t Range = 0;
- uint32_t Mask = (1u << 4);
- for (uint32_t Bit = (1u << 5); Bit < (1u << 12); Bit <<= 1) {
- if ((RegSave & Bit) == 0u)
- break;
- ++Range;
- Mask |= Bit;
- }
+ uint32_t Mask = RegSave & 0xff0u;
+ uint32_t Range = countTrailingOnes(Mask >> 5); // Exclude r4.
+ // Mask off non-consecutive registers. Keep r4.
+ Mask &= ~(0xffffffe0u << Range);
// Emit this opcode when the mask covers every registers.
uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
@@ -105,50 +101,24 @@ void UnwindOpcodeAssembler::EmitRegSave(
/// Emit unwind opcodes for .vsave directives
void UnwindOpcodeAssembler::EmitVFPRegSave(uint32_t VFPRegSave) {
- size_t i = 32;
-
- while (i > 16) {
- uint32_t Bit = 1u << (i - 1);
- if ((VFPRegSave & Bit) == 0u) {
- --i;
- continue;
- }
-
- uint32_t Range = 0;
+ // We only have 4 bits to save the offset in the opcode so look at the lower
+ // and upper 16 bits separately.
+ for (uint32_t Regs : {VFPRegSave & 0xffff0000u, VFPRegSave & 0x0000ffffu}) {
+ while (Regs) {
+ // Now look for a run of set bits. Remember the MSB and LSB of the run.
+ auto RangeMSB = 32 - countLeadingZeros(Regs);
+ auto RangeLen = countLeadingOnes(Regs << (32 - RangeMSB));
+ auto RangeLSB = RangeMSB - RangeLen;
+
+ int Opcode = RangeLSB >= 16
+ ? ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16
+ : ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD;
- --i;
- Bit >>= 1;
+ EmitInt16(Opcode | ((RangeLSB % 16) << 4) | (RangeLen - 1));
- while (i > 16 && (VFPRegSave & Bit)) {
- --i;
- ++Range;
- Bit >>= 1;
+ // Zero out bits we're done with.
+ Regs &= ~(-1u << RangeLSB);
}
-
- EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 |
- ((i - 16) << 4) | Range);
- }
-
- while (i > 0) {
- uint32_t Bit = 1u << (i - 1);
- if ((VFPRegSave & Bit) == 0u) {
- --i;
- continue;
- }
-
- uint32_t Range = 0;
-
- --i;
- Bit >>= 1;
-
- while (i > 0 && (VFPRegSave & Bit)) {
- --i;
- ++Range;
- Bit >>= 1;
- }
-
- EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD | (i << 4) |
- Range);
}
}
More information about the llvm-commits
mailing list