From 0f6702a3c6d413ff523fa339999e637721d24010 Mon Sep 17 00:00:00 2001 From: tyfkda Date: Tue, 23 Apr 2024 06:46:26 +0900 Subject: [PATCH] Use sext, zext instructions --- src/cc/arch/riscv64/ir_riscv64.c | 20 +++++++++++--------- src/cc/arch/riscv64/riscv64.h | 8 +++++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/cc/arch/riscv64/ir_riscv64.c b/src/cc/arch/riscv64/ir_riscv64.c index ab70f3b0b..360064a0f 100644 --- a/src/cc/arch/riscv64/ir_riscv64.c +++ b/src/cc/arch/riscv64/ir_riscv64.c @@ -796,16 +796,18 @@ static void ei_cast(IR *ir) { const char *dst = kReg64s[ir->dst->phys], *src = kReg64s[ir->opr1->phys]; if (ir->flag & IRF_UNSIGNED) { - const char *shift = IM((8 - (1 << pow)) * TARGET_CHAR_BIT); - SLLI(dst, src, shift); - SRLI(dst, dst, shift); + switch (pow) { + case 0: ZEXT_B(dst, src); break; + case 1: ZEXT_H(dst, src); break; + case 2: ZEXT_W(dst, src); break; + default: assert(false); break; + } } else { - if (pow < 2) { - const char *shift = IM((4 - (1 << pows)) * TARGET_CHAR_BIT); - SLLIW(dst, src, shift); - SRAI(dst, dst, shift); - } else { - SEXTW(dst, src); + switch (pow) { + case 0: SEXT_B(dst, src); break; + case 1: SEXT_H(dst, src); break; + case 2: SEXT_W(dst, src); break; + default: assert(false); break; } } } diff --git a/src/cc/arch/riscv64/riscv64.h b/src/cc/arch/riscv64/riscv64.h index b7a2c378e..b823607a1 100644 --- a/src/cc/arch/riscv64/riscv64.h +++ b/src/cc/arch/riscv64/riscv64.h @@ -116,6 +116,7 @@ #define SLLIW(o1, o2, o3) EMIT_ASM("slliw", o1, o2, o3) // Logical left shift, 32bit #define SRL(o1, o2, o3) EMIT_ASM("srl", o1, o2, o3) // Logical right shift #define SRLI(o1, o2, o3) EMIT_ASM("srli", o1, o2, o3) // Logical right shift +#define SRLIW(o1, o2, o3) EMIT_ASM("srliw", o1, o2, o3) // Logical right shift #define SRA(o1, o2, o3) EMIT_ASM("sra", o1, o2, o3) // Arithmetic right shift #define SRAI(o1, o2, o3) EMIT_ASM("srai", o1, o2, o3) // Arithmetic right shift #define J(o1) EMIT_ASM("j", o1) // => jal zero, o1 @@ -140,7 +141,12 @@ #define MV(o1, o2) EMIT_ASM("mv", o1, o2) // => addi o1, o2, 0 #define NEG(o1, o2) EMIT_ASM("neg", o1, o2) // => sub o1, zero, o2 #define NOT(o1, o2) EMIT_ASM("not", o1, o2) // => xori o1, o2, -1 -#define SEXTW(o1, o2) EMIT_ASM("sext.w", o1, o2) // => addiw o1, o2, 0 +#define SEXT_B(o1, o2) EMIT_ASM("sext.b", o1, o2) // => slli & srai 48 +#define SEXT_H(o1, o2) EMIT_ASM("sext.h", o1, o2) // => slli & srai 56 +#define SEXT_W(o1, o2) EMIT_ASM("sext.w", o1, o2) // => addiw o1, o2, 0 +#define ZEXT_B(o1, o2) EMIT_ASM("zext.b", o1, o2) +#define ZEXT_H(o1, o2) EMIT_ASM("zext.h", o1, o2) +#define ZEXT_W(o1, o2) EMIT_ASM("zext.w", o1, o2) #define SEQZ(o1, o2) EMIT_ASM("seqz", o1, o2) #define SNEZ(o1, o2) EMIT_ASM("snez", o1, o2)