From: Richard Henderson <rth@twiddle.net>
To: identifier scorpio <cidentifier@yahoo.com.cn>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Porting TCG to alpha platform
Date: Wed, 20 Jan 2010 13:26:45 -0800 [thread overview]
Message-ID: <4B577515.3050102@twiddle.net> (raw)
In-Reply-To: <682404.21141.qm@web15904.mail.cnb.yahoo.com>
On 01/20/2010 09:19 AM, identifier scorpio wrote:
> Below i'll append my newly generated patch against stable-0.10,
> in case it is mangled, i also put it in the attachment.
For the record, the inline portion was again mangled; the attachment is
fine.
> in qemu_ld/st, we must use $16,$17,$18 as temporaries,
> because pass them as argument to helper functions such as qemu_ld/st_helpers[].
Ah, yes, I forgot about that.
>> With I/J constraints you don't need this special casing.
>
> I'm not very familiar with I/J constraints and i'll study them later.
I = uint8_t, to be used with the second arithmetic input.
J = 0, to be used with the first arithmetic input (i.e. $31).
>>> + tcg_out_inst2(s, opc^4,
>> TMP_REG1, 1);
>>> + /* record relocation infor */
>>> + tcg_out_reloc(s,
>> s->code_ptr, R_ALPHA_REFQUAD, label_index, 0);
>>> + s->code_ptr += 4;
>>
>> Bug: You've applied the relocation to the wrong
>> instruction.
>> Bug: What's with the "opc^4"?
>>
>
> what did you mean that i "applied the relocation to the wrong
> instruction", couldn't i apply relocation to INDEX_op_brcond_i32 operation?
With tcg_out_inst2 you emit the branch instruction, which calls
tcg_out32, which increments s->code_ptr. Next you call tcg_out_reloc
with the updated s->code_ptr, which means that the relocation gets
applied to the instruction *after* the branch. Finally, you increment
s->code_ptr *again*, which means that the instruction after the branch
is in fact completely uninitialized.
> and opc^4 here is used to toggle between OP_BLBC(opcode 0x38) and OP_BLBS(opcode 0x3c), ugly code :)
It does beg the question of why you're reversing the sense of the jump
at all. Just because the branch is forward doesn't mean its condition
should be changed. I think that's definitely a bug. The sense of the
jump should be exactly the same, never mind the direction of the jump.
Oh... I see what you're doing here -- you're generating the entire
branch instruction in patch_reloc, and you're generating branch over
branch here. That's both confusing and unnecessary.
We should do
static void patch_reloc(uint8_t *x_ptr, int type,
tcg_target_long value,
tcg_target_long addend)
{
uint32_t *code_ptr = (uint32_t *)x;
uint32_t insn = *code_ptr;
value += addend;
switch (type) {
case R_ALPHA_BRADDR:
value -= (long)x_ptr + 4;
if ((value & 3) || value < -0x400000 || value >= 0x400000) {
tcg_abort();
}
*code_ptr = insn | INSN_DISP21(val >> 2);
break;
default:
tcg_abort();
}
}
so as to apply the branch address relocation to the existing insn.
Which lets you write
static void tcg_out_br(TCGContext *s, int opc, int ra, int label_index)
{
TCGLabel *l = &s->labels[label_index];
tcg_target_long value;
if (l->has_value) {
value = l->u.value;
value -= (long)s->code_ptr + 4;
if ((value & 3) || value < -0x400000 || value >= 0x400000) {
tcg_abort();
}
value >>= 2;
} else {
tcg_out_reloc(s, s->code_ptr, R_ALPHA_BRADDR, label_index, 0);
value = 0;
}
tcg_out_fmt_br(s, opc, ra, value);
}
static void tcg_out_brcond(TCGContext *s, ...)
{
// Emit comparison into TMP_REG1.
opc = (cond & 1) ? INSN_BLBC : INSN_BLBS;
tcg_out_br(s, opc, TMP_REG1, label_index);
}
Isn't that much clearer?
> + tcg_out_mov(s, r1, addr_reg);
> + tcg_out_mov(s, r0, addr_reg);
> +
> +#if TARGET_LONG_BITS == 32
> + /* if VM is of 32-bit arch, clear higher 32-bit of addr */
> + tcg_out_fmt_opi(s, INSN_ZAPNOT, r0, 0x0f, r0);
> + tcg_out_fmt_opi(s, INSN_ZAPNOT, r1, 0x0f, r1);
> +#endif
I suggest creating a
static inline tcg_out_mov_addr(TCGContext *s, int rd, int rs)
{
if (TARGET_LONG_BITS == 32) {
tcg_out_fmt_opi(s, INSN_ZAPNOT, rs, 0x0f, rd);
} else {
tcg_out_mov(s, rd, rs);
}
}
and using that throughout qemu_ld/st. That will save some redundant
moves you are creating there, as well as removing some conditional
compilation. Indeed, I would suggest replacing all of the conditional
compilation vs TARGET_LONG_BITS with normal if's.
... Of course, in this particular case, that zapnot is redundant with
the INSN_AND that follows, for both R0 and R1.
> + tcg_out_movi(s, TCG_TYPE_I64, TMP_REG1, (tcg_target_long)qemu_ld_helpers[s_bits]);
> + tcg_out_push(s, addr_reg);
> + //tcg_out_push(s, TCG_REG_26);
> + //tcg_out_push(s, TCG_REG_15);
> + tcg_out_mov(s, TCG_REG_27, TMP_REG1);
> + tcg_out_fmt_jmp(s, INSN_CALL, TCG_REG_26, TMP_REG1, 0);
> + //tcg_out_pop(s, TCG_REG_15);
> + //tcg_out_pop(s, TCG_REG_26);
> + tcg_out_pop(s, addr_reg);
You need not save and restore ADDR_REG; it is not used after the call.
Also, you can load the address into $27 directly and not use the temp.
> + *(uint32_t *)label1_ptr = (uint32_t) \
> + ( INSN_BNE | ( TMP_REG1 << 21 ) | ( val & 0x1fffff));
Frankly, I don't really think it's worth being so convoluted with the
branches in here. I know that's the way that the i386 port does it in
qemu_ld/st, but I think we should rather pattern it after the i386 brcond2.
I.e. use gen_new_label to create a new label for use within the routine,
use a normal call into tcg_out_br to generate the branch, and use
tcg_out_label to place the label at the proper place and resolve the
forward branch.
It may be be a teeny bit less efficient, but it's far clearer.
> + tcg_out_movi(s, TCG_TYPE_I64, TMP_REG1, \
> + offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read));
> + tcg_out_fmt_opr(s, INSN_ADDQ, r1, TMP_REG1, r1);
> + tcg_out_fmt_mem(s, INSN_LDQ, TMP_REG1, r1, 0);
You may want to use
tcg_out_ld(s, TCG_TYPE_I64, TMP_REG1, r1, offsetof ...);
for clarity, and to reuse the tcg_out_op_long improvements.
> +#else
> + r0 = addr_reg;
> +#endif // endif defined(CONFIG_SOFTMMU)
Missing GUEST_BASE handling, though that won't help your winnt...
>>> + case INDEX_op_sar_i32:
>>> + tcg_out_inst4i(s,
>> OP_SHIFT, args[1], 32, FUNC_SLL, args[1]);
>>> + tcg_out_inst4i(s,
>> OP_SHIFT, args[1], 32, FUNC_SRA, args[1]);
>>
>> That last shift can be combined with the requested shift
>> via addition. For constant input, this saves an insn; for
>> register input, the addition can be done in parallel with
>> the first shift.
>
> i changed to use "addl r, 0, r" here.
Even better.
> I think when qemu met x86 divide instructions, it will call helper
> functions to simulate them, must i define div_i32/divu_i32/...?
If you want to emulate anything other than x86, yes.
r~
next prev parent reply other threads:[~2010-01-20 21:52 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-20 17:19 [Qemu-devel] [PATCH] Porting TCG to alpha platform identifier scorpio
2010-01-20 21:26 ` Richard Henderson [this message]
-- strict thread matches above, loose matches on Subject: below --
2010-01-22 15:47 identifier scorpio
2010-01-22 18:00 ` Richard Henderson
2010-01-26 1:19 ` Richard Henderson
2010-01-29 1:55 ` identifier scorpio
2010-01-29 17:04 ` Richard Henderson
2010-01-29 21:38 ` Edgar E. Iglesias
2010-01-29 23:04 ` Stefan Weil
2010-01-30 0:38 ` Edgar E. Iglesias
2010-01-30 1:14 ` Laurent Desnogues
2010-01-29 17:37 ` Richard Henderson
2010-01-29 19:19 ` Richard Henderson
2010-01-30 2:45 ` identifier scorpio
2010-01-31 23:09 ` Richard Henderson
2010-01-21 3:42 identifier scorpio
2010-01-21 18:18 ` Stefan Weil
2010-01-19 8:47 identifier scorpio
2010-01-19 20:18 ` Richard Henderson
2010-01-19 21:35 ` malc
2010-01-19 21:42 ` Stefan Weil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B577515.3050102@twiddle.net \
--to=rth@twiddle.net \
--cc=cidentifier@yahoo.com.cn \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).