diff options
author | Jun Sha (Joshua) <cooper.joshua@linux.alibaba.com> | 2024-01-12 16:44:20 +0800 |
---|---|---|
committer | Christoph Müllner <christoph.muellner@vrull.eu> | 2024-01-18 15:40:07 +0100 |
commit | 9e1b554cc75e25fe96baf9b8d7963b932cb2c36d (patch) | |
tree | 9ad7b736df0397e1c2b4e1bbe91688a58ac74deb | |
parent | cdf4729f0889501c622cc1ad2df9377f2819cc07 (diff) | |
download | gcc-9e1b554cc75e25fe96baf9b8d7963b932cb2c36d.zip gcc-9e1b554cc75e25fe96baf9b8d7963b932cb2c36d.tar.gz gcc-9e1b554cc75e25fe96baf9b8d7963b932cb2c36d.tar.bz2 |
RISC-V: Rewrite some instructions using ASM targethook
There are some xtheadvector instructions that differ from RVV1.0
apart from simply adding "th." prefix. For example, RVV1.0
load/store instructions will have SEW while xtheadvector not;
RVV1.0 will have "o" for indexed-ordered store instructions while
xtheadvecotr not; xtheadvector and RVV1.0 have different
vnsrl/vnsra/vfncvt suffix (vv/vx/vi vs wv/wx/wi).
To address this issue without duplicating patterns, we use ASM
targethook to rewrite the whole string of the instructions. We
identify different instructions from the corresponding attribute.
gcc/ChangeLog:
* config/riscv/thead.cc
(th_asm_output_opcode): Rewrite some instructions.
Co-authored-by: Jin Ma <jinma@linux.alibaba.com>
Co-authored-by: Xianmiao Qu <cooper.qu@linux.alibaba.com>
Co-authored-by: Christoph Müllner <christoph.muellner@vrull.eu>
-rw-r--r-- | gcc/config/riscv/thead.cc | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index 85250f7..2955bc5 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -908,6 +908,213 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p) } } + if (get_attr_type (current_output_insn) == TYPE_VLDE || + get_attr_type (current_output_insn) == TYPE_VSTE || + get_attr_type (current_output_insn) == TYPE_VLDFF) + { + if (strstr (p, "e8") || strstr (p, "e16") || + strstr (p, "e32") || strstr (p, "e64")) + { + get_attr_type (current_output_insn) == TYPE_VSTE + ? fputs ("th.vse", asm_out_file) + : fputs ("th.vle", asm_out_file); + if (strstr (p, "e8")) + return p+4; + else + return p+5; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VLDS || + get_attr_type (current_output_insn) == TYPE_VSTS) + { + if (strstr (p, "vle8") || strstr (p, "vse8") || + strstr (p, "vle16") || strstr (p, "vse16") || + strstr (p, "vle32") || strstr (p, "vse32") || + strstr (p, "vle64") || strstr (p, "vse64")) + { + get_attr_type (current_output_insn) == TYPE_VSTS + ? fputs ("th.vse", asm_out_file) + : fputs ("th.vle", asm_out_file); + if (strstr (p, "e8")) + return p+4; + else + return p+5; + } + else if (strstr (p, "vlse8") || strstr (p, "vsse8") || + strstr (p, "vlse16") || strstr (p, "vsse16") || + strstr (p, "vlse32") || strstr (p, "vsse32") || + strstr (p, "vlse64") || strstr (p, "vsse64")) + { + get_attr_type (current_output_insn) == TYPE_VSTS + ? fputs ("th.vsse", asm_out_file) + : fputs ("th.vlse", asm_out_file); + if (strstr (p, "e8")) + return p+5; + else + return p+6; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VLDUX || + get_attr_type (current_output_insn) == TYPE_VLDOX) + { + if (strstr (p, "ei")) + { + fputs ("th.vlxe", asm_out_file); + if (strstr (p, "ei8")) + return p+7; + else + return p+8; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VSTUX || + get_attr_type (current_output_insn) == TYPE_VSTOX) + { + if (strstr (p, "ei")) + { + get_attr_type (current_output_insn) == TYPE_VSTUX + ? fputs ("th.vsuxe", asm_out_file) + : fputs ("th.vsxe", asm_out_file); + if (strstr (p, "ei8")) + return p+7; + else + return p+8; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VLSEGDE || + get_attr_type (current_output_insn) == TYPE_VSSEGTE || + get_attr_type (current_output_insn) == TYPE_VLSEGDFF) + { + get_attr_type (current_output_insn) == TYPE_VSSEGTE + ? fputs ("th.vsseg", asm_out_file) + : fputs ("th.vlseg", asm_out_file); + asm_fprintf (asm_out_file, "%c", p[5]); + fputs ("e", asm_out_file); + if (strstr (p, "e8")) + return p+8; + else + return p+9; + } + + if (get_attr_type (current_output_insn) == TYPE_VLSEGDS || + get_attr_type (current_output_insn) == TYPE_VSSEGTS) + { + get_attr_type (current_output_insn) == TYPE_VSSEGTS + ? fputs ("th.vssseg", asm_out_file) + : fputs ("th.vlsseg", asm_out_file); + asm_fprintf (asm_out_file, "%c", p[6]); + fputs ("e", asm_out_file); + if (strstr (p, "e8")) + return p+9; + else + return p+10; + } + + if (get_attr_type (current_output_insn) == TYPE_VLSEGDUX || + get_attr_type (current_output_insn) == TYPE_VLSEGDOX) + { + fputs ("th.vlxseg", asm_out_file); + asm_fprintf (asm_out_file, "%c", p[7]); + fputs ("e", asm_out_file); + if (strstr (p, "ei8")) + return p+11; + else + return p+12; + } + + if (get_attr_type (current_output_insn) == TYPE_VSSEGTUX || + get_attr_type (current_output_insn) == TYPE_VSSEGTOX) + { + fputs ("th.vsxseg", asm_out_file); + asm_fprintf (asm_out_file, "%c", p[7]); + fputs ("e", asm_out_file); + if (strstr (p, "ei8")) + return p+11; + else + return p+12; + } + + if (get_attr_type (current_output_insn) == TYPE_VNSHIFT) + { + if (strstr (p, "vncvt")) + { + fputs ("th.vncvt.x.x.v", asm_out_file); + return p+11; + } + + strstr (p, "vnsrl") ? fputs ("th.vnsrl.v", asm_out_file) + : fputs ("th.vnsra.v", asm_out_file); + return p+7; + } + + if (get_attr_type (current_output_insn) == TYPE_VNCLIP) + { + if (strstr (p, "vnclipu")) + { + fputs ("th.vnclipu.v", asm_out_file); + return p+9; + } + else + { + fputs ("th.vnclip.v", asm_out_file); + return p+8; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VMPOP) + { + fputs ("th.vmpopc", asm_out_file); + return p+5; + } + + if (get_attr_type (current_output_insn) == TYPE_VMFFS) + { + fputs ("th.vmfirst", asm_out_file); + return p+6; + } + + if (get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI || + get_attr_type (current_output_insn) == TYPE_VFNCVTITOF) + { + if (strstr (p, "xu")) + { + get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI + ? fputs ("th.vfncvt.xu.f.v", asm_out_file) + : fputs ("th.vfncvt.f.xu.v", asm_out_file); + return p+13; + } + else + { + get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI + ? fputs ("th.vfncvt.x.f.v", asm_out_file) + : fputs ("th.vfncvt.f.x.v", asm_out_file); + return p+12; + } + } + + if (get_attr_type (current_output_insn) == TYPE_VFNCVTFTOF) + { + fputs ("th.vfncvt.f.f.v", asm_out_file); + return p+12; + } + + if (get_attr_type (current_output_insn) == TYPE_VFREDU + && strstr (p, "sum")) + { + fputs ("th.vfredsum", asm_out_file); + return p+9; + } + + if (get_attr_type (current_output_insn) == TYPE_VFWREDU + && strstr (p, "sum")) + { + fputs ("th.vfwredsum", asm_out_file); + return p+10; + } + if (p[0] == 'v') fputs ("th.", asm_out_file); } |