Message ID | 20210920080451.408655-10-git@xen0n.name (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | 64-bit LoongArch port of QEMU TCG | expand |
On 9/20/21 1:04 AM, WANG Xuerui wrote: > +static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, > + tcg_target_long val) > +{ > + tcg_target_long low, upper, higher, top; > + > + if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { > + val = (int32_t)val; > + } > + > + /* Single-instruction cases. */ > + low = sextreg(val, 0, 12); > + if (low == val) { > + /* val fits in simm12: addi.w rd, zero, val */ > + tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); > + return; > + } > + if (0x800 <= val && val <= 0xfff) { > + /* val fits in uimm12: ori rd, zero, val */ > + tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); > + return; > + } > + > + /* Chop upper bits into 3 immediate-field-sized segments respectively. */ > + upper = (val >> 12) & 0xfffff; > + higher = (val >> 32) & 0xfffff; > + top = val >> 52; > + > + tcg_out_opc_lu12i_w(s, rd, upper); > + if (low != 0) { > + tcg_out_opc_ori(s, rd, rd, low); > + } > + > + if (sextreg(val, 0, 32) == val) { > + /* > + * Fits in 32-bits, upper bits are already properly sign-extended by > + * lu12i.w. > + */ > + return; > + } > + tcg_out_opc_cu32i_d(s, rd, higher); > + > + if (sextreg(val, 0, 52) == val) { > + /* > + * Fits in 52-bits, upper bits are already properly sign-extended by > + * cu32i.d. > + */ > + return; > + } > + tcg_out_opc_cu52i_d(s, rd, rd, top); Looks ok. You'll want to check for small to medium pc-relative addresses. Almost every TB will load the address of TB+C (0 <= C <= 3) at the end, and the TB structure immediately precedes the code. Because of the odd values, you'll sometimes need two instructions. But that will still be less than the 3-4 for a 52/64-bit address constant. r~
diff --git a/tcg/loongarch/tcg-target.c.inc b/tcg/loongarch/tcg-target.c.inc index 71564e3246..60783d7ddc 100644 --- a/tcg/loongarch/tcg-target.c.inc +++ b/tcg/loongarch/tcg-target.c.inc @@ -261,6 +261,77 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0) tcg_out_opc_dbar(s, 0); } +static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) +{ + if (ret == arg) { + return true; + } + switch (type) { + case TCG_TYPE_I32: + case TCG_TYPE_I64: + /* + * Conventional register-register move used in LoongArch is + * `or dst, src, zero`. + */ + tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); + break; + default: + g_assert_not_reached(); + } + return true; +} + +static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, + tcg_target_long val) +{ + tcg_target_long low, upper, higher, top; + + if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { + val = (int32_t)val; + } + + /* Single-instruction cases. */ + low = sextreg(val, 0, 12); + if (low == val) { + /* val fits in simm12: addi.w rd, zero, val */ + tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); + return; + } + if (0x800 <= val && val <= 0xfff) { + /* val fits in uimm12: ori rd, zero, val */ + tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); + return; + } + + /* Chop upper bits into 3 immediate-field-sized segments respectively. */ + upper = (val >> 12) & 0xfffff; + higher = (val >> 32) & 0xfffff; + top = val >> 52; + + tcg_out_opc_lu12i_w(s, rd, upper); + if (low != 0) { + tcg_out_opc_ori(s, rd, rd, low); + } + + if (sextreg(val, 0, 32) == val) { + /* + * Fits in 32-bits, upper bits are already properly sign-extended by + * lu12i.w. + */ + return; + } + tcg_out_opc_cu32i_d(s, rd, higher); + + if (sextreg(val, 0, 52) == val) { + /* + * Fits in 52-bits, upper bits are already properly sign-extended by + * cu32i.d. + */ + return; + } + tcg_out_opc_cu52i_d(s, rd, rd, top); +} + /* * Entry-points */ @@ -276,6 +347,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_mb(s, a0); break; + case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ + case INDEX_op_mov_i64: default: g_assert_not_reached(); }
Signed-off-by: WANG Xuerui <git@xen0n.name> --- tcg/loongarch/tcg-target.c.inc | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)