Re: [Qemu-devel] [PATCH 09/10 v12] target-tilegx: Generate tcg instructions to finish Hello world
On 6/13/15 21:21, Chen Gang wrote: +static void gen_st_add(struct DisasContext *dc, + uint8_t rsrc, uint8_t rsrcb, uint8_t imm8, It needs int8_t instead of uint8_t for imm8, or it will cause memmove() of glibc generates incorrect result with -O1/2/s optimization. And tilegx linux-user still has another issues (at least 1 another bug), I shall continue analyzing, hope I can finish them within this month. Thanks. + TCGMemOp ops, const char *code) +{ +qemu_log_mask(CPU_LOG_TB_IN_ASM, %s r%d, r%d, %d\n, + code, rsrc, rsrcb, imm8); +tcg_gen_qemu_st_i64(load_gr(dc, rsrcb), load_gr(dc, rsrc), +MMU_USER_IDX, ops); +tcg_gen_addi_i64(dest_gr(dc, rsrc), load_gr(dc, rsrc), imm8); +} + Thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed
Re: [Qemu-devel] [PATCH 09/10 v12] target-tilegx: Generate tcg instructions to finish Hello world
On 6/13/15 21:21, Chen Gang wrote: + +static void decode_x1(struct DisasContext *dc, tilegx_bundle_bits bundle) +{ +unsigned int opcode = get_Opcode_X1(bundle); +uint8_t rsrc = (uint8_t)get_SrcA_X1(bundle); +uint8_t rdst = (uint8_t)get_Dest_X1(bundle); +int16_t imm16 = (int16_t)get_Imm16_X1(bundle); + These type cast should be removed. Thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed
Re: [Qemu-devel] [PATCH 09/10 v12] target-tilegx: Generate tcg instructions to finish Hello world
On 7/19/15 17:42, Chen Gang wrote: On 6/13/15 21:21, Chen Gang wrote: +static void gen_st_add(struct DisasContext *dc, + uint8_t rsrc, uint8_t rsrcb, uint8_t imm8, It needs int8_t instead of uint8_t for imm8, or it will cause memmove() of glibc generates incorrect result with -O1/2/s optimization. This bug causes many various issues: after fix this bug, vi is OK. Now, I am analyzing another issue, it is about stat64 failure issue. Thanks And tilegx linux-user still has another issues (at least 1 another bug), I shall continue analyzing, hope I can finish them within this month. Thanks. + TCGMemOp ops, const char *code) +{ +qemu_log_mask(CPU_LOG_TB_IN_ASM, %s r%d, r%d, %d\n, + code, rsrc, rsrcb, imm8); +tcg_gen_qemu_st_i64(load_gr(dc, rsrcb), load_gr(dc, rsrc), +MMU_USER_IDX, ops); +tcg_gen_addi_i64(dest_gr(dc, rsrc), load_gr(dc, rsrc), imm8); +} + Thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed
Re: [Qemu-devel] [PATCH 09/10 v12] target-tilegx: Generate tcg instructions to finish Hello world
Hello Maintainers: Please help review this patch when you have time. Thanks. On 06/13/2015 09:21 PM, Chen Gang wrote: Generate related tcg instructions, and qemu tilegx can finish running Hello world. The elf64 binary can be static or shared. Signed-off-by: Chen Gang gang.chen.5...@gmail.com --- target-tilegx/translate.c | 2966 + 1 file changed, 2966 insertions(+) create mode 100644 target-tilegx/translate.c diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c new file mode 100644 index 000..1dd3a43 --- /dev/null +++ b/target-tilegx/translate.c @@ -0,0 +1,2966 @@ +/* + * QEMU TILE-Gx CPU + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * http://www.gnu.org/licenses/lgpl-2.1.html + */ + +#include cpu.h +#include qemu/log.h +#include disas/disas.h +#include tcg-op.h +#include exec/cpu_ldst.h +#include opcode_tilegx.h +#include spr_def_64.h + +#define FMT64X %016 PRIx64 +#define TILEGX_TMP_REGS(TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE + 1) + +static TCGv_ptr cpu_env; +static TCGv cpu_pc; +static TCGv cpu_regs[TILEGX_R_COUNT]; +static TCGv cpu_spregs[TILEGX_SPR_COUNT]; +#if defined(CONFIG_USER_ONLY) +static TCGv_i32 cpu_excparam; +#endif + +static const char * const reg_names[] = { + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, +r16, r17, r18, r19, r20, r21, r22, r23, +r24, r25, r26, r27, r28, r29, r30, r31, +r32, r33, r34, r35, r36, r37, r38, r39, +r40, r41, r42, r43, r44, r45, r46, r47, +r48, r49, r50, r51, bp, tp, sp, lr +}; + +static const char * const spreg_names[] = { +cmpexch, criticalsec, simcontrol +}; + +/* It is for temporary registers */ +typedef struct DisasContextTemp { +uint8_t idx; /* index */ +TCGv val; /* value */ +} DisasContextTemp; + +/* This is the state at translation time. */ +typedef struct DisasContext { +uint64_t pc; /* Current pc */ +int exception; /* Current exception */ + +TCGv zero; /* For zero register */ + +DisasContextTemp *tmp_regcur; /* Current temporary registers */ +DisasContextTemp tmp_regs[TILEGX_TMP_REGS]; /* All temporary registers */ +struct { +TCGCond cond; /* Branch condition */ +TCGv dest; /* pc jump destination, if will jump */ +TCGv val1; /* Firt value for condition comparing */ +TCGv val2; /* Second value for condition comparing */ +} jmp; /* Jump object, only once in each TB block */ +} DisasContext; + +#include exec/gen-icount.h + +static void gen_exception(DisasContext *dc, int num) +{ +TCGv_i32 tmp = tcg_const_i32(num); + +gen_helper_exception(cpu_env, tmp); +tcg_temp_free_i32(tmp); +} + +/* + * All exceptions which can still let working flow continue are all in pipe x1, + * which is the last pipe of a bundle. So it is OK to only process the first + * exception within a bundle. + */ +static void set_exception(DisasContext *dc, int num) +{ +if (dc-exception == TILEGX_EXCP_NONE) { +dc-exception = num; +} +} + +static bool check_gr(DisasContext *dc, uint8_t reg) +{ +if (likely(reg TILEGX_R_COUNT)) { +return true; +} + +switch (reg) { +case TILEGX_R_SN: +case TILEGX_R_ZERO: +break; +case TILEGX_R_IDN0: +case TILEGX_R_IDN1: +set_exception(dc, TILEGX_EXCP_REG_IDN_ACCESS); +break; +case TILEGX_R_UDN0: +case TILEGX_R_UDN1: +case TILEGX_R_UDN2: +case TILEGX_R_UDN3: +set_exception(dc, TILEGX_EXCP_REG_UDN_ACCESS); +break; +default: +g_assert_not_reached(); +} +return false; +} + +static TCGv load_zero(DisasContext *dc) +{ +if (TCGV_IS_UNUSED_I64(dc-zero)) { +dc-zero = tcg_const_i64(0); +} +return dc-zero; +} + +static TCGv load_gr(DisasContext *dc, uint8_t reg) +{ +if (check_gr(dc, reg)) { +return cpu_regs[reg]; +} +return load_zero(dc); +} + +static TCGv dest_gr(DisasContext *dc, uint8_t rdst)
[Qemu-devel] [PATCH 09/10 v12] target-tilegx: Generate tcg instructions to finish Hello world
Generate related tcg instructions, and qemu tilegx can finish running Hello world. The elf64 binary can be static or shared. Signed-off-by: Chen Gang gang.chen.5...@gmail.com --- target-tilegx/translate.c | 2966 + 1 file changed, 2966 insertions(+) create mode 100644 target-tilegx/translate.c diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c new file mode 100644 index 000..1dd3a43 --- /dev/null +++ b/target-tilegx/translate.c @@ -0,0 +1,2966 @@ +/* + * QEMU TILE-Gx CPU + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * http://www.gnu.org/licenses/lgpl-2.1.html + */ + +#include cpu.h +#include qemu/log.h +#include disas/disas.h +#include tcg-op.h +#include exec/cpu_ldst.h +#include opcode_tilegx.h +#include spr_def_64.h + +#define FMT64X %016 PRIx64 +#define TILEGX_TMP_REGS(TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE + 1) + +static TCGv_ptr cpu_env; +static TCGv cpu_pc; +static TCGv cpu_regs[TILEGX_R_COUNT]; +static TCGv cpu_spregs[TILEGX_SPR_COUNT]; +#if defined(CONFIG_USER_ONLY) +static TCGv_i32 cpu_excparam; +#endif + +static const char * const reg_names[] = { + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, +r16, r17, r18, r19, r20, r21, r22, r23, +r24, r25, r26, r27, r28, r29, r30, r31, +r32, r33, r34, r35, r36, r37, r38, r39, +r40, r41, r42, r43, r44, r45, r46, r47, +r48, r49, r50, r51, bp, tp, sp, lr +}; + +static const char * const spreg_names[] = { +cmpexch, criticalsec, simcontrol +}; + +/* It is for temporary registers */ +typedef struct DisasContextTemp { +uint8_t idx; /* index */ +TCGv val; /* value */ +} DisasContextTemp; + +/* This is the state at translation time. */ +typedef struct DisasContext { +uint64_t pc; /* Current pc */ +int exception; /* Current exception */ + +TCGv zero; /* For zero register */ + +DisasContextTemp *tmp_regcur; /* Current temporary registers */ +DisasContextTemp tmp_regs[TILEGX_TMP_REGS]; /* All temporary registers */ +struct { +TCGCond cond; /* Branch condition */ +TCGv dest; /* pc jump destination, if will jump */ +TCGv val1; /* Firt value for condition comparing */ +TCGv val2; /* Second value for condition comparing */ +} jmp; /* Jump object, only once in each TB block */ +} DisasContext; + +#include exec/gen-icount.h + +static void gen_exception(DisasContext *dc, int num) +{ +TCGv_i32 tmp = tcg_const_i32(num); + +gen_helper_exception(cpu_env, tmp); +tcg_temp_free_i32(tmp); +} + +/* + * All exceptions which can still let working flow continue are all in pipe x1, + * which is the last pipe of a bundle. So it is OK to only process the first + * exception within a bundle. + */ +static void set_exception(DisasContext *dc, int num) +{ +if (dc-exception == TILEGX_EXCP_NONE) { +dc-exception = num; +} +} + +static bool check_gr(DisasContext *dc, uint8_t reg) +{ +if (likely(reg TILEGX_R_COUNT)) { +return true; +} + +switch (reg) { +case TILEGX_R_SN: +case TILEGX_R_ZERO: +break; +case TILEGX_R_IDN0: +case TILEGX_R_IDN1: +set_exception(dc, TILEGX_EXCP_REG_IDN_ACCESS); +break; +case TILEGX_R_UDN0: +case TILEGX_R_UDN1: +case TILEGX_R_UDN2: +case TILEGX_R_UDN3: +set_exception(dc, TILEGX_EXCP_REG_UDN_ACCESS); +break; +default: +g_assert_not_reached(); +} +return false; +} + +static TCGv load_zero(DisasContext *dc) +{ +if (TCGV_IS_UNUSED_I64(dc-zero)) { +dc-zero = tcg_const_i64(0); +} +return dc-zero; +} + +static TCGv load_gr(DisasContext *dc, uint8_t reg) +{ +if (check_gr(dc, reg)) { +return cpu_regs[reg]; +} +return load_zero(dc); +} + +static TCGv dest_gr(DisasContext *dc, uint8_t rdst) +{ +DisasContextTemp *tmp = dc-tmp_regcur++; + +/* Skip the result, mark the exception if necessary, and continue */ +check_gr(dc, rdst); +assert((dc-tmp_regcur - dc-tmp_regs) TILEGX_TMP_REGS); +tmp-idx = rdst; +tmp-val = tcg_temp_new_i64(); +return