Skip to content

Instantly share code, notes, and snippets.

@xorgy
Last active February 22, 2018 01:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xorgy/46fc236a7b23945e45da47380d6f6e65 to your computer and use it in GitHub Desktop.
Save xorgy/46fc236a7b23945e45da47380d6f6e65 to your computer and use it in GitHub Desktop.
void TurboAssembler::li_smallest(Register rd, int64_t j) {
BlockTrampolinePoolScope block_trampoline_pool(this);
unsigned trailing = CountTrailingZeros(j);
unsigned leading = CountLeadingZeros(j);
unsigned solid = 64 - trailing - leading;
if (solid <= 12) {
if (leading >= 44) {
emit(ORI, rd, zero_reg, j);
} else if (leading >= 32 && trailing >= 12) {
emit(LUI, rd, j >> 44);
} else {
emit(ORI, rd, zero_reg, j >> trailing);
emit(SLLI, rd, rd, trailing);
}
} else if (solid <= 20) {
if (leading >= 32) {
li_smallest(rd, reinterpret_cast<int32_t>(j));
} else {
emit(LUI, rd, j >> trailing);
emit(SLLI, rd, rd, trailing);
}
} else if (solid <= 32) {
if (leading >= 32) {
li_smallest(rd, reinterpret_cast<int32_t>(j));
} else {
li_smallest(rd, reinterpret_cast<int32_t>(j >> trailing));
emit(SLLI, rd, rd, trailing);
}
} else if (solid <= 44) {
if (leading >= 20) {
li_smallest(rd, reinterpret_cast<int32_t>(j >> 12 & 0xFFFFFFFF));
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j & 0xFFF);
} else {
li_smallest(rd,
reinterpret_cast<int32_t>(j >> (12 + trailing) & 0xFFFFFFFF));
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j >> trailing & 0xFFF);
emit(SLLI, rd, rd, trailing);
}
} else if (solid <= 56) {
if (leading >= 8) {
li_smallest(rd, reinterpret_cast<int32_t>(j >> 24 & 0xFFFFFFFF));
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j >> 12 & 0xFFF);
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j & 0xFFF);
} else {
li_smallest(rd,
reinterpret_cast<int32_t>(j >> (24 + trailing) & 0xFFFFFFFF));
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j >> (12 + trailing) & 0xFFF);
emit(SLLI, rd, rd, 12);
emit(ORI, rd, rd, j >> trailing & 0xFFF);
emit(SLLI, rd, rd, trailing);
}
} else {
li(rd, j);
}
}
void TurboAssembler::li_smallest(Register rd, int32_t j) {
BlockTrampolinePoolScope block_trampoline_pool(this);
bool initialized = false;
if (j & 0xFFFFF000) {
emit(LUI, rd, (j & 0xFFFFF000) >> 12);
initialized = true;
}
if (j & 0xFFF) {
emit(ORI, rd, initialized? rd: zero_reg, j & 0x00000FFF);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment