LoongArch: Optimize the loading of immediate numbers with the same high and low 32-bit values
For the following immediate load operation in gcc/testsuite/gcc.target/loongarch/imm-load1.c: long long r = 0x0101010101010101; Before this patch: lu12i.w $r15,16842752>>12 ori $r15,$r15,257 lu32i.d $r15,0x1010100000000>>32 lu52i.d $r15,$r15,0x100000000000000>>52 After this patch: lu12i.w $r15,16842752>>12 ori $r15,$r15,257 bstrins.d $r15,$r15,63,32 gcc/ChangeLog: * config/loongarch/loongarch.cc (enum loongarch_load_imm_method): Add new method. (loongarch_build_integer): Add relevant implementations for new method. (loongarch_move_integer): Ditto. gcc/testsuite/ChangeLog: * gcc.target/loongarch/imm-load1.c: Change old check.
This commit is contained in:
parent
df8dfd7837
commit
96577dfae9
2 changed files with 23 additions and 2 deletions
|
@ -142,12 +142,16 @@ struct loongarch_address_info
|
|||
|
||||
METHOD_LU52I:
|
||||
Load 52-63 bit of the immediate number.
|
||||
|
||||
METHOD_MIRROR:
|
||||
Copy 0-31 bit of the immediate number to 32-63bit.
|
||||
*/
|
||||
enum loongarch_load_imm_method
|
||||
{
|
||||
METHOD_NORMAL,
|
||||
METHOD_LU32I,
|
||||
METHOD_LU52I
|
||||
METHOD_LU52I,
|
||||
METHOD_MIRROR
|
||||
};
|
||||
|
||||
struct loongarch_integer_op
|
||||
|
@ -1556,11 +1560,23 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
|
|||
|
||||
int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
|
||||
int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
|
||||
|
||||
uint32_t hival = (uint32_t) (value >> 32);
|
||||
uint32_t loval = (uint32_t) value;
|
||||
|
||||
/* Determine whether the upper 32 bits are sign-extended from the lower
|
||||
32 bits. If it is, the instructions to load the high order can be
|
||||
ommitted. */
|
||||
if (lu32i[sign31] && lu52i[sign31])
|
||||
return cost;
|
||||
/* If the lower 32 bits are the same as the upper 32 bits, just copy
|
||||
the lower 32 bits to the upper 32 bits. */
|
||||
else if (loval == hival)
|
||||
{
|
||||
codes[cost].method = METHOD_MIRROR;
|
||||
codes[cost].curr_value = value;
|
||||
return cost + 1;
|
||||
}
|
||||
/* Determine whether bits 32-51 are sign-extended from the lower 32
|
||||
bits. If so, directly load 52-63 bits. */
|
||||
else if (lu32i[sign31])
|
||||
|
@ -3234,6 +3250,10 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
|
|||
gen_rtx_AND (DImode, x, GEN_INT (0xfffffffffffff)),
|
||||
GEN_INT (codes[i].value));
|
||||
break;
|
||||
case METHOD_MIRROR:
|
||||
gcc_assert (mode == DImode);
|
||||
emit_insn (gen_insvdi (x, GEN_INT (32), GEN_INT (32), x));
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O2" } */
|
||||
/* { dg-final { scan-assembler "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
|
||||
/* { dg-final { scan-assembler-not "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
|
||||
/* { dg-final { scan-assembler "test:.*lu12i\.w.*\n\tbstrins\.d.*\n\.L2:" } } */
|
||||
|
||||
|
||||
extern long long b[10];
|
||||
|
|
Loading…
Add table
Reference in a new issue