Commit cc1aae28 authored by Miran.Karic's avatar Miran.Karic Committed by Commit bot

MIPS64: Add optimizations to li macro.

A number of improvements in mips64 load immediate macro is added per
suggestions from MIPS ART team. Also fix Subu and Dsubu macro, add a
test for Subu and Dsubu and make minor code adjustments.

BUG=
TEST=cctest/test-assembler-mips/li_macro
     cctest/test-assembler-mips/Subu
     cctest/test-assembler-mips/Dsubu

Review-Url: https://codereview.chromium.org/2892163002
Cr-Commit-Position: refs/heads/master@{#45493}
parent 8655861e
...@@ -1406,11 +1406,11 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) { ...@@ -1406,11 +1406,11 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
addiu(rd, zero_reg, j.imm32_); addiu(rd, zero_reg, j.imm32_);
} else if (!(j.imm32_ & kHiMask)) { } else if (!(j.imm32_ & kHiMask)) {
ori(rd, zero_reg, j.imm32_); ori(rd, zero_reg, j.imm32_);
} else if (!(j.imm32_ & kImm16Mask)) {
lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask);
} else { } else {
lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask); lui(rd, (j.imm32_ >> kLuiShift) & kImm16Mask);
ori(rd, rd, (j.imm32_ & kImm16Mask)); if (j.imm32_ & kImm16Mask) {
ori(rd, rd, (j.imm32_ & kImm16Mask));
}
} }
} else { } else {
if (MustUseReg(j.rmode_)) { if (MustUseReg(j.rmode_)) {
......
...@@ -273,19 +273,19 @@ const int kBp3Shift = 6; ...@@ -273,19 +273,19 @@ const int kBp3Shift = 6;
const int kBp3Bits = 3; const int kBp3Bits = 3;
const int kImm16Shift = 0; const int kImm16Shift = 0;
const int kImm16Bits = 16; const int kImm16Bits = 16;
const int kImm18Shift = 0; const int kImm18Shift = 0;
const int kImm18Bits = 18; const int kImm18Bits = 18;
const int kImm19Shift = 0; const int kImm19Shift = 0;
const int kImm19Bits = 19; const int kImm19Bits = 19;
const int kImm21Shift = 0; const int kImm21Shift = 0;
const int kImm21Bits = 21; const int kImm21Bits = 21;
const int kImm26Shift = 0; const int kImm26Shift = 0;
const int kImm26Bits = 26; const int kImm26Bits = 26;
const int kImm28Shift = 0; const int kImm28Shift = 0;
const int kImm28Bits = 28; const int kImm28Bits = 28;
const int kImm32Shift = 0; const int kImm32Shift = 0;
const int kImm32Bits = 32; const int kImm32Bits = 32;
const int kMsaImm8Shift = 16; const int kMsaImm8Shift = 16;
const int kMsaImm8Bits = 8; const int kMsaImm8Bits = 8;
const int kMsaImm5Shift = 16; const int kMsaImm5Shift = 16;
...@@ -322,30 +322,30 @@ const int kWdShift = 6; ...@@ -322,30 +322,30 @@ const int kWdShift = 6;
// ----- Miscellaneous useful masks. // ----- Miscellaneous useful masks.
// Instruction bit masks. // Instruction bit masks.
const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift; const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift;
const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift; const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift;
const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift; const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift;
const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
const int kImm5Mask = ((1 << 5) - 1); const int kImm5Mask = ((1 << 5) - 1);
const int kImm8Mask = ((1 << 8) - 1); const int kImm8Mask = ((1 << 8) - 1);
const int kImm10Mask = ((1 << 10) - 1); const int kImm10Mask = ((1 << 10) - 1);
const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1)); const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1));
const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
// Misc masks. // Misc masks.
const int kHiMask = 0xffff << 16; const int kHiMaskOf32 = 0xffff << 16; // Only to be used with 32-bit values
const int kLoMask = 0xffff; const int kLoMaskOf32 = 0xffff;
const int kSignMask = 0x80000000; const int kSignMaskOf32 = 0x80000000; // Only to be used with 32-bit values
const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
const int64_t kHi16MaskOf64 = (int64_t)0xffff << 48; const int64_t kTop16MaskOf64 = (int64_t)0xffff << 48;
const int64_t kSe16MaskOf64 = (int64_t)0xffff << 32; const int64_t kHigher16MaskOf64 = (int64_t)0xffff << 32;
const int64_t kTh16MaskOf64 = (int64_t)0xffff << 16; const int64_t kUpper16MaskOf64 = (int64_t)0xffff << 16;
const int32_t kJalRawMark = 0x00000000; const int32_t kJalRawMark = 0x00000000;
const int32_t kJRawMark = 0xf0000000; const int32_t kJRawMark = 0xf0000000;
const int32_t kJumpRawMask = 0xf0000000; const int32_t kJumpRawMask = 0xf0000000;
......
This diff is collapsed.
...@@ -78,19 +78,20 @@ enum BranchDelaySlot { ...@@ -78,19 +78,20 @@ enum BranchDelaySlot {
enum LiFlags { enum LiFlags {
// If the constant value can be represented in just 16 bits, then // If the constant value can be represented in just 16 bits, then
// optimize the li to use a single instruction, rather than lui/ori/dsll // optimize the li to use a single instruction, rather than lui/ori/dsll
// sequence. // sequence. A number of other optimizations that emits less than
// maximum number of instructions exists.
OPTIMIZE_SIZE = 0, OPTIMIZE_SIZE = 0,
// Always use 6 instructions (lui/ori/dsll sequence), even if the constant // Always use 6 instructions (lui/ori/dsll sequence) for release 2 or 4
// instructions for release 6 (lui/ori/dahi/dati), even if the constant
// could be loaded with just one, so that this value is patchable later. // could be loaded with just one, so that this value is patchable later.
CONSTANT_SIZE = 1, CONSTANT_SIZE = 1,
// For address loads only 4 instruction are required. Used to mark // For address loads only 4 instruction are required. Used to mark
// constant load that will be used as address without relocation // constant load that will be used as address without relocation
// information. It ensures predictable code size, so specific sites // information. It ensures predictable code size, so specific sites
// in code are patchable. // in code are patchable.
ADDRESS_LOAD = 2 ADDRESS_LOAD = 2
}; };
enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
enum PointersToHereCheck { enum PointersToHereCheck {
...@@ -739,7 +740,7 @@ class MacroAssembler: public Assembler { ...@@ -739,7 +740,7 @@ class MacroAssembler: public Assembler {
// Load int32 in the rd register. // Load int32 in the rd register.
void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE); void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
inline bool LiLower32BitHelper(Register rd, Operand j); inline void LiLower32BitHelper(Register rd, Operand j);
inline void li(Register rd, int64_t j, LiFlags mode = OPTIMIZE_SIZE) { inline void li(Register rd, int64_t j, LiFlags mode = OPTIMIZE_SIZE) {
li(rd, Operand(j), mode); li(rd, Operand(j), mode);
} }
......
...@@ -5555,7 +5555,7 @@ TEST(Subu) { ...@@ -5555,7 +5555,7 @@ TEST(Subu) {
// 0 - imm = expected_res // 0 - imm = expected_res
struct TestCaseSubu tc[] = { struct TestCaseSubu tc[] = {
// imm, expected_res, num_instr // imm, expected_res, num_instr
{0xffff8000, 0x00008000, 2}, // min_int16 {0xffff8000, 0x8000, 2}, // min_int16
// Generates ori + addu // Generates ori + addu
// We can't have just addiu because -min_int16 > max_int16 so use // We can't have just addiu because -min_int16 > max_int16 so use
// register. We can load min_int16 to at register with addiu and then // register. We can load min_int16 to at register with addiu and then
......
This diff is collapsed.
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