* [Qemu-devel] [4691] PPC TCG Fixes
@ 2008-06-07 20:31 malc
2008-06-08 8:31 ` Thiemo Seufer
0 siblings, 1 reply; 3+ messages in thread
From: malc @ 2008-06-07 20:31 UTC (permalink / raw)
To: qemu-devel
Revision: 4691
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4691
Author: malc
Date: 2008-06-07 20:31:33 +0000 (Sat, 07 Jun 2008)
Log Message:
-----------
PPC TCG Fixes
* Fix typo in aliased div2
* "Optimize" aliased div2/divu2
* Fix two remaining branch retranslation problems
(Kudos to Andrzej Zaborowski)
* Rework goto_tb and set_jmp_target1
* Use correct size when flushing icache
* Use correct register selection for ORI
(Was harmless since in both cases srcreg was equal to dstreg)
Modified Paths:
--------------
trunk/exec-all.h
trunk/tcg/ppc/tcg-target.c
Modified: trunk/exec-all.h
===================================================================
--- trunk/exec-all.h 2008-06-07 08:07:37 UTC (rev 4690)
+++ trunk/exec-all.h 2008-06-07 20:31:33 UTC (rev 4691)
@@ -184,32 +184,37 @@
#if defined(USE_DIRECT_JUMP)
#if defined(__powerpc__)
+static inline void flush_icache_range(unsigned long start, unsigned long stop);
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
- uint32_t val, *ptr;
+ /* This must be in concord with INDEX_op_goto_tb inside tcg_out_op */
+ uint32_t *ptr;
long disp = addr - jmp_addr;
+ unsigned long patch_size;
ptr = (uint32_t *)jmp_addr;
- val = *ptr;
if ((disp << 6) >> 6 != disp) {
- uint16_t *p1;
-
- p1 = (uint16_t *) ptr;
- *ptr = (val & ~0x03fffffc) | 4;
- p1[3] = addr >> 16;
- p1[5] = addr & 0xffff;
+ ptr[0] = 0x3c000000 | (addr >> 16); /* lis 0,addr@ha */
+ ptr[1] = 0x60000000 | (addr & 0xffff); /* la 0,addr@l(0) */
+ ptr[2] = 0x7c0903a6; /* mtctr 0 */
+ ptr[3] = 0x4e800420; /* brctr */
+ patch_size = 16;
} else {
/* patch the branch destination */
- val = (val & ~0x03fffffc) | (disp & 0x03fffffc);
- *ptr = val;
+ if (disp != 16) {
+ *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
+ patch_size = 4;
+ } else {
+ ptr[0] = 0x60000000; /* nop */
+ ptr[1] = 0x60000000;
+ ptr[2] = 0x60000000;
+ ptr[3] = 0x60000000;
+ patch_size = 16;
+ }
}
/* flush icache */
- asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
+ flush_icache_range(jmp_addr, jmp_addr + patch_size);
}
#elif defined(__i386__) || defined(__x86_64__)
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
Modified: trunk/tcg/ppc/tcg-target.c
===================================================================
--- trunk/tcg/ppc/tcg-target.c 2008-06-07 08:07:37 UTC (rev 4690)
+++ trunk/tcg/ppc/tcg-target.c 2008-06-07 20:31:33 UTC (rev 4691)
@@ -388,7 +388,7 @@
else {
tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
if (arg & 0xffff)
- tcg_out32 (s, ORI | RT (ret) | RA (ret) | (arg & 0xffff));
+ tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
}
}
@@ -939,18 +939,14 @@
tcg_out32 (s, op | RA (arg1) | RB (arg2));
}
- if (l->has_value) {
- tcg_target_long disp;
-
- disp = (tcg_target_long) s->code_ptr - l->u.value;
- if (disp != (int16_t) disp)
- tcg_abort ();
-
+ if (l->has_value)
tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr,
l->u.value));
- }
else {
- tcg_out32 (s, tcg_to_bc[cond]);
+ uint16_t val = *(uint16_t *) &s->code_ptr[2];
+
+ /* Thanks to Andrzej Zaborowski */
+ tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc));
tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
}
}
@@ -1029,24 +1025,9 @@
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
/* direct jump method */
- uint32_t val;
- uint16_t *p;
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- /* Thanks to Andrzej Zaborowski for this */
- val = *(uint32_t *) s->code_ptr & 0x3fffffc;
-
- tcg_out32 (s, B | val);
-
- /* For branches outside of LL range
- This must be in concord with tb_set_jmp_target1 */
- p = (uint16_t *) s->code_ptr;
- p[0] = (ADDIS | RT (0) | RA (0)) >> 16;
- p[2] = (ORI | RT (0) | RA (0)) >> 16;
- s->code_ptr += 8;
-
- tcg_out32 (s, MTSPR | RS (0) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS);
+ s->code_ptr += 16;
}
else {
tcg_abort ();
@@ -1061,7 +1042,10 @@
tcg_out_b (s, 0, l->u.value);
}
else {
- tcg_out32 (s, B);
+ uint32_t val = *(uint32_t *) s->code_ptr;
+
+ /* Thanks to Andrzej Zaborowski */
+ tcg_out32 (s, B | (val & 0x3fffffc));
tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
}
}
@@ -1222,10 +1206,10 @@
case INDEX_op_div2_i32:
if (args[0] == args[2] || args[0] == args[3]) {
tcg_out32 (s, DIVW | TAB (0, args[2], args[3]));
+ tcg_out32 (s, MTSPR | RS (0) | CTR);
tcg_out32 (s, MULLW | TAB (0, 0, args[3]));
- tcg_out32 (s, SUBF | TAB (0, 0, args[2]));
- tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3]));
- tcg_out_mov (s, args[1], 0);
+ tcg_out32 (s, SUBF | TAB (args[1], 0, args[2]));
+ tcg_out32 (s, MFSPR | RT (args[0]) | CTR);
}
else {
tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3]));
@@ -1236,10 +1220,10 @@
case INDEX_op_divu2_i32:
if (args[0] == args[2] || args[0] == args[3]) {
tcg_out32 (s, DIVWU | TAB (0, args[2], args[3]));
+ tcg_out32 (s, MTSPR | RS (0) | CTR);
tcg_out32 (s, MULLW | TAB (0, 0, args[3]));
- tcg_out32 (s, SUBF | TAB (0, 0, args[2]));
- tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3]));
- tcg_out_mov (s, args[1], 0);
+ tcg_out32 (s, SUBF | TAB (args[1], 0, args[2]));
+ tcg_out32 (s, MFSPR | RT (args[0]) | CTR);
}
else {
tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3]));
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [4691] PPC TCG Fixes
2008-06-07 20:31 [Qemu-devel] [4691] PPC TCG Fixes malc
@ 2008-06-08 8:31 ` Thiemo Seufer
2008-06-08 20:09 ` malc
0 siblings, 1 reply; 3+ messages in thread
From: Thiemo Seufer @ 2008-06-08 8:31 UTC (permalink / raw)
To: malc; +Cc: qemu-devel
malc wrote:
> Revision: 4691
> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4691
> Author: malc
> Date: 2008-06-07 20:31:33 +0000 (Sat, 07 Jun 2008)
>
> Log Message:
> -----------
> PPC TCG Fixes
>
> * Fix typo in aliased div2
> * "Optimize" aliased div2/divu2
> * Fix two remaining branch retranslation problems
> (Kudos to Andrzej Zaborowski)
> * Rework goto_tb and set_jmp_target1
> * Use correct size when flushing icache
> * Use correct register selection for ORI
> (Was harmless since in both cases srcreg was equal to dstreg)
FYI, the mips system emulation still crashes when executing the very
first TB, apparently due to stack corruption. (This commit didn't
change the behaviour.)
Thiemo
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [4691] PPC TCG Fixes
2008-06-08 8:31 ` Thiemo Seufer
@ 2008-06-08 20:09 ` malc
0 siblings, 0 replies; 3+ messages in thread
From: malc @ 2008-06-08 20:09 UTC (permalink / raw)
To: Thiemo Seufer; +Cc: qemu-devel
On Sun, 8 Jun 2008, Thiemo Seufer wrote:
> malc wrote:
>> Revision: 4691
>> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4691
>> Author: malc
>> Date: 2008-06-07 20:31:33 +0000 (Sat, 07 Jun 2008)
>>
>> Log Message:
>> -----------
>> PPC TCG Fixes
>>
>> * Fix typo in aliased div2
>> * "Optimize" aliased div2/divu2
>> * Fix two remaining branch retranslation problems
>> (Kudos to Andrzej Zaborowski)
>> * Rework goto_tb and set_jmp_target1
>> * Use correct size when flushing icache
>> * Use correct register selection for ORI
>> (Was harmless since in both cases srcreg was equal to dstreg)
>
> FYI, the mips system emulation still crashes when executing the very
> first TB, apparently due to stack corruption. (This commit didn't
> change the behaviour.)
It's not a stack corruption it's a relocation problem, dyngen
relocates one of the calls inside (non tcged) op_mtc0_status as
R_PPC_REL24 but the signed displacement does not fit in 26 bits after
the code is placed into mmapped code_gen_buffer. Compiling op.o with
-mlongcall makes the emulation proceed much further, but then it still
crashes:
<transcript>
...
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 26964k/32768k available (2102k kernel code, 5804k reserved, 450k
data, 132k init, 0k highmem)
Break instruction in kernel code[#1]:
...
Call Trace:
[<802a1788>] kmem_cache_init+0x160/0x434
[<8028f7f0>] start_kernel+0x1b8/0x2c0
Code: 26100001 1611fff4 00000000 <0200000d> 8e42002c 8fa80018 00031880
0102001b 004001f4
Kernel panic - not syncing: Attempted to kill the idle task!
Perhaps something like this ought to be added to dyngen.c:
</transcript>
diff --git a/dyngen.c b/dyngen.c
index c38d123..69f4105 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -1963,6 +1963,11 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
break;
case R_PPC_REL24:
/* warning: must be at 32 MB distancy */
+ fprintf(outfile, "{\n"
+ " long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n"
+ " if ((disp << 6) >> 6 != disp) abort ();\n"
+ "}\n",
+ relname, reloc_offset, addend);
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
reloc_offset, reloc_offset, relname, reloc_offset, addend);
break;
--
mailto:av1474@comtv.ru
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-06-08 20:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-07 20:31 [Qemu-devel] [4691] PPC TCG Fixes malc
2008-06-08 8:31 ` Thiemo Seufer
2008-06-08 20:09 ` malc
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).