Commit 4c57e05d authored by alan.li's avatar alan.li Committed by Commit bot

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

This CL fixes the bugs caused by the following CL:
50a394df -- MIPS64: Fix 'MIPS: use DAHI/DATH for li macro on mips64r6.'
  Port 1f5b84e4
  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}
parent dbc0f99b
......@@ -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_)) {
......
......@@ -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);
}
......
......@@ -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]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment