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.' Port1f5b84e467
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:
parent
dbc0f99b94
commit
4c57e05d5f
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user