Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,41 @@ public void EmitLDR(Register destination, Register source)
// ldr.w reg, [reg, #offset]
// reg range: [0..PC]
// offset range: [-255..4095]
//
// for offset >= 4096 we do an expansion into:
// add.w destination, source, #const
// ldr.w destination, [destination, #offset]
public void EmitLDR(Register destination, Register source, int offset)
{
Debug.Assert(IsValidReg(destination) && IsValidReg(source));

if (offset >= 0x1000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be ever called with large negative offset?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the call sites and the only negative values seemed to be in the -PointerSize range.

{
uint constVal = (uint)offset & ~0xfffu;
uint mask32 = 0xff;
uint imm8 = 0;
int encode = 31; // 11111

do
{
mask32 <<= 1;
if ((constVal & ~mask32) == 0)
{
imm8 = (constVal & mask32) >> (32 - encode);
break;
}
encode--;
} while (encode >= 8);
Comment on lines +134 to +148
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case you are wondering, this part is shamelessly copied from the JIT:

mask32 = 0x00000ff;
encode = 31; /* 11111 */
do
{
mask32 <<= 1;
temp = uval32 & ~mask32;
if (temp == 0)
{
imm8 = (uval32 & mask32) >> (32 - encode);
assert((imm8 & 0x80) != 0);
goto DONE;
}
encode--;
} while (encode >= 8);
assert(!"encodeModImmConst failed!");
return BAD_CODE;

The instruction encoding has several forms. We want to use the one where we produce an immediate value and rotate it using the barrel shifter into the right position to get the right constant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not look like that it can.


Debug.Assert(encode >= 8);
Debug.Assert((imm8 & 0x80) > 0);
Builder.EmitShort((short)(0xF100 + (byte)source + (((byte)encode & 0x10) << 6)));
Builder.EmitShort((short)((((byte)encode & 0xE) << 11) + ((byte)destination << 8) + (((byte)encode & 1) << 7) + (imm8 & 0x7f)));

offset = (int)(offset & 0xfffu);
source = destination;
}

Debug.Assert(offset >= -255 && offset <= 4095);
if (offset >= 0)
{
Expand Down