From: Jie Mei Date: Mon, 19 Jun 2023 08:29:55 +0000 (+0800) Subject: MIPS: Add load/store word left/right instructions for mips16e2 X-Git-Tag: basepoints/gcc-15~7889 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95c6fb6a841989c47213fedca689de1d50658ecf;p=thirdparty%2Fgcc.git MIPS: Add load/store word left/right instructions for mips16e2 This patch adds LWL/LWR, SWL/SWR instructions with their corresponding tests. gcc/ChangeLog: * config/mips/mips.cc(mips_expand_ins_as_unaligned_store): Add logics for generating instruction. * config/mips/mips.h(ISA_HAS_LWL_LWR): Add clause for ISA_HAS_MIPS16E2. * config/mips/mips.md(mov_l): Generates instructions. (mov_r): Same as above. (mov_l): Adjusted for the conditions above. (mov_r): Same as above. (mov_l_mips16e2): Add machine description for `define_insn mov_l_mips16e2`. (mov_r_mips16e2): Add machine description for `define_insn mov_r_mips16e2`. gcc/testsuite/ChangeLog: * gcc.target/mips/mips16e2.c: New tests for mips16e2. --- diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 8da4d1212317..78f368f68039 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -8701,12 +8701,25 @@ mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width, return false; mode = int_mode_for_size (width, 0).require (); - src = gen_lowpart (mode, src); + if (TARGET_MIPS16 + && src == const0_rtx) + src = force_reg (mode, src); + else + src = gen_lowpart (mode, src); + if (mode == DImode) { + if (TARGET_MIPS16) + gcc_unreachable (); emit_insn (gen_mov_sdl (dest, src, left)); emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right)); } + else if (TARGET_MIPS16) + { + emit_insn (gen_mov_swl_mips16e2 (dest, src, left)); + emit_insn (gen_mov_swr_mips16e2 (copy_rtx (dest), copy_rtx (src), + right)); + } else { emit_insn (gen_mov_swl (dest, src, left)); diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index eefe2aa09100..e09a6c601575 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1180,7 +1180,8 @@ struct mips_cpu_info { && (MODE) == V2SFmode)) \ && !TARGET_MIPS16) -#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 && !TARGET_MIPS16) +#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 \ + && (!TARGET_MIPS16 || ISA_HAS_MIPS16E2)) #define ISA_HAS_IEEE_754_LEGACY (mips_isa_rev <= 5) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 1dd995e14456..eec167a1aa8b 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4490,10 +4490,12 @@ (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") (match_operand:QI 2 "memory_operand" "ZC")] UNSPEC_LOAD_LEFT))] - "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[1])" + "(!TARGET_MIPS16 || ISA_HAS_MIPS16E2) + && mips_mem_fits_mode_p (mode, operands[1])" "l\t%0,%2" [(set_attr "move_type" "load") - (set_attr "mode" "")]) + (set_attr "mode" "") + (set_attr "extended_mips16" "yes")]) (define_insn "mov_r" [(set (match_operand:GPR 0 "register_operand" "=d") @@ -4501,17 +4503,20 @@ (match_operand:QI 2 "memory_operand" "ZC") (match_operand:GPR 3 "register_operand" "0")] UNSPEC_LOAD_RIGHT))] - "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[1])" + "(!TARGET_MIPS16 || ISA_HAS_MIPS16E2) + && mips_mem_fits_mode_p (mode, operands[1])" "r\t%0,%2" [(set_attr "move_type" "load") - (set_attr "mode" "")]) + (set_attr "mode" "") + (set_attr "extended_mips16" "yes")]) (define_insn "mov_l" [(set (match_operand:BLK 0 "memory_operand" "=m") (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") (match_operand:QI 2 "memory_operand" "ZC")] UNSPEC_STORE_LEFT))] - "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[0])" + "!TARGET_MIPS16 + && mips_mem_fits_mode_p (mode, operands[0])" "l\t%z1,%2" [(set_attr "move_type" "store") (set_attr "mode" "")]) @@ -4522,11 +4527,37 @@ (match_operand:QI 2 "memory_operand" "ZC") (match_dup 0)] UNSPEC_STORE_RIGHT))] - "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[0])" + "!TARGET_MIPS16 + && mips_mem_fits_mode_p (mode, operands[0])" "r\t%z1,%2" [(set_attr "move_type" "store") (set_attr "mode" "")]) +(define_insn "mov_l_mips16e2" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec:BLK [(match_operand:GPR 1 "register_operand" "d") + (match_operand:QI 2 "memory_operand" "ZC")] + UNSPEC_STORE_LEFT))] + "TARGET_MIPS16 && ISA_HAS_MIPS16E2 + && mips_mem_fits_mode_p (mode, operands[0])" + "l\t%1,%2" + [(set_attr "move_type" "store") + (set_attr "mode" "") + (set_attr "extended_mips16" "yes")]) + +(define_insn "mov_r_mips16e2" + [(set (match_operand:BLK 0 "memory_operand" "+m") + (unspec:BLK [(match_operand:GPR 1 "register_operand" "d") + (match_operand:QI 2 "memory_operand" "ZC") + (match_dup 0)] + UNSPEC_STORE_RIGHT))] + "TARGET_MIPS16 && ISA_HAS_MIPS16E2 + && mips_mem_fits_mode_p (mode, operands[0])" + "r\t%1,%2" + [(set_attr "move_type" "store") + (set_attr "mode" "") + (set_attr "extended_mips16" "yes")]) + ;; Unaligned direct access (define_expand "movmisalign" [(set (match_operand:JOIN_MODE 0) diff --git a/gcc/testsuite/gcc.target/mips/mips16e2.c b/gcc/testsuite/gcc.target/mips/mips16e2.c index 780891b40565..166aa7422687 100644 --- a/gcc/testsuite/gcc.target/mips/mips16e2.c +++ b/gcc/testsuite/gcc.target/mips/mips16e2.c @@ -122,3 +122,119 @@ test10 (int i) return i; } +/* Test 32bit unaligned load. */ + +/* { dg-final { scan-assembler "test11:.*\tlwl\t.*test11\n" } } */ +/* { dg-final { scan-assembler "test11:.*\tlwr\t.*test11\n" } } */ +struct node11 +{ + char c; + int i; +} __attribute__ ((packed)) obj11 __attribute__((aligned(1))); + +int +test11 (void) +{ + return obj11.i; +} + +/* Test 32bit unaligned load. */ + +/* { dg-final { scan-assembler "test12:.*\tlwl\t.*test12\n" } } */ +/* { dg-final { scan-assembler "test12:.*\tlwr\t.*test12\n" } } */ +struct node12 +{ + unsigned int i : 8; + unsigned int j : 32; +} __attribute__ ((packed)) obj12 __attribute__((aligned(16))); + +int +test12 (void) +{ + return obj12.j; +} + +/* Test 32bit unaligned store with non-zero constant */ + +/* { dg-final { scan-assembler "test13:.*\tswl\t.*test13\n" } } */ +/* { dg-final { scan-assembler "test13:.*\tswr\t.*test13\n" } } */ +struct node13 +{ + char c; + int i; +} __attribute__ ((packed)) obj13 __attribute__((aligned(1))); + +void +test13 (void) +{ + obj13.i = 1234; +} + +/* Test 32bit unaligned store with zero constant. */ + +/* { dg-final { scan-assembler "test14:.*\tswl\t.*test14\n" } } */ +/* { dg-final { scan-assembler "test14:.*\tswr\t.*test14\n" } } */ +/* { dg-final { scan-assembler-not "test14:.*\tswl\t\\\$0,.*test14\n" } } */ +/* { dg-final { scan-assembler-not "test14:.*\tswr\t\\\$0,.*test14\n" } } */ +struct node14 +{ + char c; + int i; +} __attribute__ ((packed)) obj14 __attribute__((aligned(1))); + +void +test14 (void) +{ + obj14.i = 0; +} + +/* Test 32bit unaligned store with non-constant. */ + +/* { dg-final { scan-assembler "test15:.*\tswl\t.*test15\n" } } */ +/* { dg-final { scan-assembler "test15:.*\tswr\t.*test15\n" } } */ +struct node15 +{ + char c; + int i; +} __attribute__ ((packed)) obj15 __attribute__((aligned(1))); + +int i15 = 1234; + +void +test15 (void) +{ + obj15.i = i15; +} + +/* Test 32bit unaligned store with non-constant */ + +/* { dg-final { scan-assembler "test16:.*\tswl\t.*test16\n" } } */ +/* { dg-final { scan-assembler "test16:.*\tswr\t.*test16\n" } } */ +struct node16 +{ + char c; + int i; +} __attribute__ ((packed)) obj16 __attribute__((aligned(1))); + +void +test16 (int i) +{ + obj16.i = i; +} + +/* Test 32bit unaligned store with non-constant. */ + +/* { dg-final { scan-assembler "test17:.*\tswl\t.*test17\n" } } */ +/* { dg-final { scan-assembler "test17:.*\tswr\t.*test17\n" } } */ +struct node17 +{ + unsigned int i : 8; + unsigned int j : 32; +} __attribute__ ((packed)) obj17 __attribute__((aligned(16))); + +void +test17 (int i) +{ + obj17.j = i; +} +