MIPS64: Fix 'Fix 'MIPS: use DAHI/DATH for li macro on mips64r6.''

This CL fixes the bugs caused by the following CL:
50a394d -- MIPS64: Fix 'MIPS: use DAHI/DATH for li macro on mips64r6.'
  Port 1f5b84e467
  MIPS: use DAHI/DATH for li macro on mips64r6.

LUI instruction would sign extend into higher 32bits, in that case we might need to use DAHI, DATI to overwrite the extension.

The bug will occur when we are loading some addresses such as 0x00007fffffffxxxx.

BUG=
TEST=test-run-native-calls/Run_Int32_Select_*, test-run-native-calls/Run_Int32_WeightedSum_*, test-run-native-calls/Run_Int32_WeightedSum_*, test-run-native-calls/Run_Int32_Select_*

Review URL: https://codereview.chromium.org/1763733002

Cr-Commit-Position: refs/heads/master@{#34467}
This commit is contained in:
alan.li 2016-03-03 10:53:45 -08:00 committed by Commit bot
parent dbc0f99b94
commit 4c57e05d5f
3 changed files with 20 additions and 10 deletions

View File

@ -1367,17 +1367,25 @@ static inline int64_t ShiftAndFixSignExtension(int64_t imm, int bitnum) {
return imm;
}
void MacroAssembler::LiLower32BitHelper(Register rd, Operand j) {
bool MacroAssembler::LiLower32BitHelper(Register rd, Operand j) {
bool higher_bits_sign_extended = false;
if (is_int16(j.imm64_)) {
daddiu(rd, zero_reg, (j.imm64_ & kImm16Mask));
} else if (!(j.imm64_ & kHiMask)) {
ori(rd, zero_reg, (j.imm64_ & kImm16Mask));
} else if (!(j.imm64_ & kImm16Mask)) {
lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
if ((j.imm64_ >> (kLuiShift + 15)) & 0x1) {
higher_bits_sign_extended = true;
}
} else {
lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
ori(rd, rd, (j.imm64_ & kImm16Mask));
if ((j.imm64_ >> (kLuiShift + 15)) & 0x1) {
higher_bits_sign_extended = true;
}
}
return higher_bits_sign_extended;
}
void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
@ -1390,16 +1398,17 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
} else {
if (kArchVariant == kMips64r6) {
int64_t imm = j.imm64_;
LiLower32BitHelper(rd, j);
bool higher_bits_sign_extended = LiLower32BitHelper(rd, j);
imm = ShiftAndFixSignExtension(imm, 32);
if (imm & kImm16Mask) {
// If LUI writes 1s to higher bits, we need both DAHI/DATI.
if ((imm & kImm16Mask) ||
(higher_bits_sign_extended && (j.imm64_ > 0))) {
dahi(rd, imm & kImm16Mask);
}
if (!is_int48(j.imm64_)) {
imm = ShiftAndFixSignExtension(imm, 16);
if (imm & kImm16Mask) {
dati(rd, imm & kImm16Mask);
}
imm = ShiftAndFixSignExtension(imm, 16);
if ((!is_int48(j.imm64_) && (imm & kImm16Mask)) ||
(higher_bits_sign_extended && (j.imm64_ > 0))) {
dati(rd, imm & kImm16Mask);
}
} else {
if (is_int48(j.imm64_)) {

View File

@ -700,7 +700,7 @@ class MacroAssembler: public Assembler {
// Load int32 in the rd register.
void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
inline void LiLower32BitHelper(Register rd, Operand j);
inline bool LiLower32BitHelper(Register rd, Operand j);
inline void li(Register rd, int64_t j, LiFlags mode = OPTIMIZE_SIZE) {
li(rd, Operand(j), mode);
}

View File

@ -5039,7 +5039,8 @@ TEST(li_macro) {
0x0000000000000000, 0x000000000000ffff, 0x00000000ffffffff,
0x0000ffffffffffff, 0xffffffffffffffff, 0xffff000000000000,
0xffffffff00000000, 0xffffffffffff0000, 0xffff0000ffff0000,
0x0000ffffffff0000, 0x0000ffff0000ffff,
0x0000ffffffff0000, 0x0000ffff0000ffff, 0x00007fffffffffff,
0x7fffffffffffffff, 0x000000007fffffff, 0x00007fff7fffffff,
};
size_t nr_test_cases = sizeof(inputs) / sizeof(inputs[0]);