[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] target-tilegx: Execute _start and reach to _
From: |
Chen Gang |
Subject: |
Re: [Qemu-devel] [PATCH v2] target-tilegx: Execute _start and reach to __libc_start_main successfully |
Date: |
Sat, 14 Mar 2015 07:07:15 +0800 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 |
Firstly, thank you very much for your reviewing, and I shall send patch
v3 within this week end (2015-03-15).
On 3/14/15 02:20, Richard Henderson wrote:
> On 03/12/2015 09:06 AM, Chen Gang wrote:
>> +#define TILEGX_GEN_SAVE_PREP(rdst) \
>> + dc->tmp_regcur->idx = rdst; \
>> + dc->tmp_regcur->val = tcg_temp_new_i64();
>> +
>> +#define TILEGX_GEN_SAVE_TMP_1(func, rdst, x1) \
>> + TILEGX_GEN_SAVE_PREP(rdst) \
>> + func(dc->tmp_regcur->val, x1);
>> +
>> +#define TILEGX_GEN_SAVE_TMP_2(func, rdst, x1, x2) \
>> + TILEGX_GEN_SAVE_PREP(rdst) \
>> + func(dc->tmp_regcur->val, x1, x2);
>> +
>> +#define TILEGX_GEN_SAVE_TMP_3(func, rdst, x1, x2, x3) \
>> + TILEGX_GEN_SAVE_PREP(rdst) \
>> + func(dc->tmp_regcur->val, x1, x2, x3);
>
> Again, I told you to get rid of all of these macros. I even suggested how to
> do it, using a helper function:
>
> static TCGv dest_gr(DisasContext *dc, uint8_t rdst)
> {
> DisasContextTemp *tmp = dc->tmp_regcur;
> tmp->idx = rdst;
> tmp->val = tcg_temp_new_i64();
> return tmp->val;
> }
>
>> +static const char *reg_names[] = {
>
> Again, const char * const reg_names.
>
>> +/* This is the state at translation time. */
>> +typedef struct DisasContext {
>> + uint64_t pc; /* Current pc */
>> + uint64_t exception; /* Current exception, 0 means empty */
>> +
>> + TCGv zero; /* For zero register */
>> +
>> + struct {
>> + unsigned char idx; /* index */
>> + TCGv val; /* value */
>> + } *tmp_regcur, /* Current temporary registers */
>> + tmp_regs[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; /* All temporary
>> registers */
>
> Again, I told you to name this structure. See DisasContextTemp above.
>
>> +static void gen_shl16insli(struct DisasContext *dc,
>> + uint8_t rdst, uint8_t rsrc, uint16_t uimm16)
>> +{
>> + TCGv_i64 tmp = tcg_temp_new_i64();
>> +
>> + qemu_log("shl16insli r%d, r%d, %llx\n", rdst, rsrc, (long long)uimm16);
>> + tcg_gen_shli_i64(tmp, load_gr(dc, rsrc), 16);
>> + TILEGX_GEN_SAVE_TMP_2(tcg_gen_ori_i64, rdst, tmp, uimm16);
>> + tcg_temp_free_i64(tmp);
>
> Again, you don't need the temporary here, since the one you will have created
> with dest_gr is sufficient.
>
Oh, sorry for my carelessness for the 'Again' above.
>> +static void gen_ld(struct DisasContext *dc, uint8_t rdst, uint8_t rsrc)
>> +{
>> + qemu_log("ld r%d, r%d\n", rdst, rsrc);
>> + tcg_gen_qemu_ld_i64(load_gr(dc, rdst), load_gr(dc, rsrc),
>> + MMU_USER_IDX, MO_LEQ);
>
> You're incorrectly loading into a source temporary. You need to load into a
> temporary created by dest_gr.
>
OK, thanks.
>> + /* for tcg_gen_qemu_st_i64, rsrc and rdst are reverted */
>> + tcg_gen_qemu_st_i64(load_gr(dc, rsrc), load_gr(dc, rdst),
>> + MMU_USER_IDX, MO_LEQ);
>
> Huh? The address is always the second argument to tcg_gen_qemu_st_i64.
> It would also probably be better if you named these arguments properly: there
> is no "rdst" for a store instruction. They're called SrcA and SrcB in the
> architecture manual.
>
OK, thanks. The comments is incorrect (misleading), and I will use SrcA
and SrcB.
>> +static void decode_insns_y0_10(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>> +{
>> + uint8_t rsrc, rsrcb, rdst;
>> +
>> + if (get_RRROpcodeExtension_Y0(bundle) == 2) {
>
> Use the proper symbol, not the number 2.
> Which in this case is OR_RRR_5_OPCODE_Y0.
>
> There is a very simple pattern to the naming in opcode_tilegx.h.
> The symbols are very easy to look up.
>
OK, thanks.
>> + rdst = (uint8_t)get_Dest_Y0(bundle);
>> + rsrc = (uint8_t)get_SrcA_Y0(bundle);
>> + rsrcb = (uint8_t)get_SrcB_Y0(bundle);
>> + /* move Dest, SrcA */
>> + if (rsrcb == TILEGX_R_ZERO) {
>> + gen_move(dc, rdst, rsrc);
>> + return;
>> + }
>
> I insist that you *not* special case these pseudo instructions from section
> 4.1.15, at least to start with. It will be fantastically easier to review if
> we see the symbolic opcode name followed by tcg functions bearing the same
> name.
>
OK, I will remove all pseudo instructions.
> Compare the code that you wrote with the following:
>
> static void decode_rrr_5_opcode_y0(DisasContext *dc, tilegx_bundle_bits
> bundle)
> {
> unsigned rsrca = get_SrcA_Y0(bundle);
> unsigned rsrcb = get_SrcB_Y0(bundle);
> unsigned rdest = get_Dest_Y0(bundle);
> unsigned ext = get_RRROpcodeExtension_Y0(bundle);
>
> switch (ext) {
> case OR_RRR_5_OPCODE_Y0:
> gen_or(rdest, rsrca, rsrcb);
> break;
>
> default:
> qemu_log_mask(LOG_UNIMP, "UNIMP rrr_5_opcode_y0, extension %d\n", ext);
> dc->exception = TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
> break;
> }
> }
>
OK, thank you for your sample above, it is valuable to me.
>> +static void decode_insns_y1_1(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>> +{
>> + uint8_t rsrc = (uint8_t)get_SrcA_Y1(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_Y1(bundle);
>> + int8_t imm8 = (int8_t)get_Imm8_Y1(bundle);
>> +
>> + gen_addi(dc, rdst, rsrc, imm8);
>> +}
>
> I think the naming on these functions should be better. "y1_1" does not tell
> me much. Better is to name them after the symbol in opcode_tilegx.h. In this
> case the name would be decode_addi_opcode_y1.
>
OK, thanks.
>> +static void decode_insns_y1_7(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_rrr_1_opcode_y1.
>
>> +{
>> + /* fnop */
>> + if ((get_RRROpcodeExtension_Y1(bundle) == 0x03)
>
> UNARY_RRR_1_OPCODE_Y1
>
>> + && (get_UnaryOpcodeExtension_Y1(bundle) == 0x08)
>
> FNOP_UNARY_OPCODE_Y1
>
>> +static void decode_insns_x0_1(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_addli_opcode_x0
>
OK, thanks
>> +{
>> + uint8_t rsrc = (uint8_t)get_SrcA_X0(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_X0(bundle);
>> + int16_t imm16 = (int16_t)get_Imm16_X0(bundle);
>> +
>> + /* moveli Dest, Imm16 */
>> + if (rsrc == TILEGX_R_ZERO) {
>
> No special case for zero. Just do tcg_gen_addi_tl.
>
>> + qemu_log("in x0_1, unimplement %16.16llx\n", bundle);
>> + dc->exception = TILEGX_EXCP_OPCODE_UNIMPLEMENT;
>> +}
>
> which means there's nothing unimplemented. See how much extra work you're
> making for yourself?
>
OK, thanks.
>> +static void decode_insns_x0_4(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_imm8_opcode_x0
>
>> + uint8_t rsrc = (uint8_t)get_SrcA_X0(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_X0(bundle);
>> + int8_t imm8 = (int8_t)get_Imm8_X0(bundle);
>> +
>> + switch (get_Imm8OpcodeExtension_X0(bundle)) {
>> + /* addi Dest, SrcA, Imm8 */
>> + case 0x01:
>
> ADDI_IMM8_OPCODE_X0. The comment is then obvious and superfluous.
>
>> + gen_addi(dc, rdst, rsrc, imm8);
>> + return;
>> + /* andi Dest, SrcA, Imm8 */
>> + case 0x03:
>
> ANDI_IMM8_OPCODE_X0
>
>> +static void decode_insns_x0_5(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_rrr_0_opcode_x0
>
>> +{
>> + uint8_t rsrc = (uint8_t)get_SrcA_X0(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_X0(bundle);
>> +
>> + switch (get_RRROpcodeExtension_X0(bundle)) {
>> + case 0x03:
>> + /* add, Dest, SrcA, SrcB */
>
> ADD_RRR_0_OPCODE_X0
>
>> + gen_add(dc, rdst, rsrc, (uint8_t)get_SrcB_X0(bundle));
>> + return;
>> + case 0x52:
>> + /* fnop */
>
> UNARY_RRR_0_OPCODE_X0.
>
>> + if ((get_UnaryOpcodeExtension_X0(bundle) == 0x03) && !rsrc &&
>> !rdst) {
>
> FNOP_UNARY_OPCODE_X0.
OK, thanks.
> There are enough of these it's probably worth splitting
> out decode of this to its own function.
>
OK, I will add gen_fnop() for it.
>> +static void decode_insns_x0_7(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_shl16insli_opcode_x0
>
>> +static void decode_insns_x1_0(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_addli_opcode_x1
>
>> +{
>> + 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);
>> +
>> + /* moveli Dest, Imm16 */
>> + if (rsrc == TILEGX_R_ZERO) {
>> + gen_moveli(dc, rdst, imm16);
>> + return;
>> + }
>> + qemu_log("in x1_0, unimplement %16.16llx\n", bundle);
>> + dc->exception = TILEGX_EXCP_OPCODE_UNIMPLEMENT;
>
> Again, no special case for R_ZERO. Again, just implement the add.
>
>> +static void decode_insns_x1_3(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_imm8_opcode_x1
>
>> +{
>> + uint8_t rsrc = (uint8_t)get_SrcA_X1(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_X1(bundle);
>> + int8_t imm8 = (int8_t)get_Imm8_X1(bundle);
>> +
>> + /* addi Dest, SrcA, Imm8 */
>> + if (get_Imm8OpcodeExtension_X1(bundle) == 0x01) {
>
> ADDI_IMM8_OPCODE_X1
>
>> +static void decode_insns_x1_5(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_rrr_0_opcode_x1
>
>> +{
>> + uint8_t rsrc = (uint8_t)get_SrcA_X1(bundle);
>> + uint8_t rdst = (uint8_t)get_Dest_X1(bundle);
>> +
>> + switch (get_RRROpcodeExtension_X1(bundle)) {
>> + case 0x03:
>> + /* add Dest, SrcA, SrcB */
>
> ADD_RRR_0_OPCODE_X1
>
>> + gen_add(dc, rdst, rsrc, (uint8_t)get_SrcB_X1(bundle));
>> + return;
>> + case 0x35:
>
> UNARY_RRR_0_OPCODE_X1
>
>> + switch (get_UnaryOpcodeExtension_X1(bundle)) {
>> + case 0x0e:
>> + /* jr SrcA */
>
> JR_UNARY_OPCODE_X1
>
>> + if (!rdst) {
>> + gen_jr(dc, rsrc);
>> + return;
>> + }
>> + break;
>> + case 0x1e:
>> + /* lnk Dest */
>
> LNK_UNARY_OPCODE_X1
>
>> +static void decode_insns_x1_7(struct DisasContext *dc,
>> + tilegx_bundle_bits bundle)
>
> decode_shl16insli_opcode
>
OK, thanks.
>> +/* by "grep _OPCODE_X0 opcode_tilegx.h | awk '{print $3, $1}' | sort -n" */
>> +static TileGXDecodeInsn decode_insns_x0[] = {
>
> These tables are both pointless and incorrect.
>
> Note that the Opcode_X0 field is only 3 bits wide. This should have been your
> first hint that having 165 entries in the table could not be right.
>
OK, thanks.
>> + decode_insns_x0_1, /* 1, ADDI_IMM8_OPCODE_X0
>> + ADDLI_OPCODE_X0
>> + ADDXSC_RRR_0_OPCODE_X0
>> + CNTLZ_UNARY_OPCODE_X0
>> + ROTLI_SHIFT_OPCODE_X0 */
>
> ADDI_IMM8_OPCODE_X0 does not come from get_Opcode_X0, but from
> get_Imm8OpcodeExtension_X0. ADDXSC_RRR_0_OPCODE_X0 does not come from
> get_Opcode_X0, but from get_RRROpcodeExtension_X0. Etc.
>
OK, thanks.
>
>> +static void translate_x0(struct DisasContext *dc, tilegx_bundle_bits bundle)
>> +{
>> + unsigned int opcode = get_Opcode_X0(bundle);
>> +
>> + if (opcode > TILEGX_OPCODE_MAX_X0) {
>> + dc->exception = TILEGX_EXCP_OPCODE_UNKNOWN;
>> + qemu_log("unknown x0 opcode: %u for bundle: %16.16llx\n",
>> + opcode, bundle);
>> + return;
>> + }
>> + if (!decode_insns_x0[opcode]) {
>> + dc->exception = TILEGX_EXCP_OPCODE_UNIMPLEMENT;
>> + qemu_log("unimplement x0 opcode: %u for bundle: %16.16llx\n",
>> + opcode, bundle);
>> + return;
>> + }
>> +
>> + dc->tmp_regcur = dc->tmp_regs + 0;
>> + decode_insns_x0[opcode](dc, bundle);
>
> Thus I think this function should be written
>
> static void decode_x0(DisasContext *dc, tilegx_bundle_bits bundle)
> {
> unsigned int opcode = get_Opcode_X0(bundle);
> switch (opcode) {
> case ADDLI_OPCODE_X0:
> decode_addli_opcode_x0(dc, bundle);
> break;
> case RRR_0_opcode_X0:
> decode_rrr_0_opcode_x0(dc, bundle);
> break;
> ...
> default:
> qemu_log_mask(LOG_UNIMP, "UNIMP x0, opcode %d\n", opcode);
> dc->exception = TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
> break;
> }
> }
>
OK, thanks.
>> +static void translate_x1(struct DisasContext *dc, tilegx_bundle_bits bundle)
>> +static void translate_y0(struct DisasContext *dc, tilegx_bundle_bits bundle)
>> +static void translate_y1(struct DisasContext *dc, tilegx_bundle_bits bundle)
>> +static void translate_y2(struct DisasContext *dc, tilegx_bundle_bits bundle)
>
> And similarly for these others.
>
OK, thanks.
Thanks.
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed