From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K5nUp-00041q-HG for qemu-devel@nongnu.org; Mon, 09 Jun 2008 15:57:39 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K5nUo-000414-I5 for qemu-devel@nongnu.org; Mon, 09 Jun 2008 15:57:38 -0400 Received: from [199.232.76.173] (port=40681 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K5nUo-00040r-Bm for qemu-devel@nongnu.org; Mon, 09 Jun 2008 15:57:38 -0400 Received: from savannah.gnu.org ([199.232.41.3]:60213 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K5nUn-0001GC-V7 for qemu-devel@nongnu.org; Mon, 09 Jun 2008 15:57:38 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1K5nUn-0000VB-B0 for qemu-devel@nongnu.org; Mon, 09 Jun 2008 19:57:37 +0000 Received: from malc by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1K5nUn-0000V4-5f for qemu-devel@nongnu.org; Mon, 09 Jun 2008 19:57:37 +0000 MIME-Version: 1.0 Errors-To: malc Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: malc Message-Id: Date: Mon, 09 Jun 2008 19:57:37 +0000 Subject: [Qemu-devel] [4715] Emit trampolines manually in prologue Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 4715 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4715 Author: malc Date: 2008-06-09 19:57:36 +0000 (Mon, 09 Jun 2008) Log Message: ----------- Emit trampolines manually in prologue Modified Paths: -------------- trunk/tcg/ppc/tcg-target.c Modified: trunk/tcg/ppc/tcg-target.c =================================================================== --- trunk/tcg/ppc/tcg-target.c 2008-06-09 19:57:27 UTC (rev 4714) +++ trunk/tcg/ppc/tcg-target.c 2008-06-09 19:57:36 UTC (rev 4715) @@ -23,6 +23,8 @@ */ static uint8_t *tb_ret_addr; +static uint8_t *udiv_addr; +static uint8_t *div_addr; #define FAST_PATH #if TARGET_PHYS_ADDR_BITS <= 32 @@ -118,7 +120,7 @@ }; static const int tcg_target_callee_save_regs[] = { - TCG_REG_R13, /* sould r13 be saved? */ + TCG_REG_R13, /* should r13 be saved? */ TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, @@ -135,6 +137,22 @@ TCG_REG_R31 }; +static const int div_save_regs[] = { + TCG_REG_R4, + TCG_REG_R5, + TCG_REG_R7, + TCG_REG_R8, + TCG_REG_R9, + TCG_REG_R10, + TCG_REG_R11, + TCG_REG_R12, + TCG_REG_R13, /* should r13 be saved? */ + TCG_REG_R24, + TCG_REG_R25, + TCG_REG_R26, + TCG_REG_R27, +}; + static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) { tcg_target_long disp; @@ -799,9 +817,25 @@ #endif } +static uint64_t ppc_udiv_helper (uint64_t a, uint32_t b) +{ + uint64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + +static uint64_t ppc_div_helper (int64_t a, int32_t b) +{ + int64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + void tcg_target_qemu_prologue (TCGContext *s) { - int i, frame_size; + int i, j, frame_size; frame_size = 0 + 4 /* back chain */ @@ -837,6 +871,49 @@ tcg_out32 (s, MTSPR | RS (0) | LR); tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); tcg_out32 (s, BCLR | BO_ALWAYS); + + /* div trampolines */ + for (j = 0; j < 2; ++j) { + tcg_target_long target; + + frame_size = 8 + ARRAY_SIZE (div_save_regs) * 4; + frame_size = (frame_size + 15) & ~15; + + if (j == 0) { + target = (tcg_target_long) ppc_udiv_helper; + udiv_addr = s->code_ptr; + } + else { + target = (tcg_target_long) ppc_div_helper; + div_addr = s->code_ptr; + } + + tcg_out32 (s, MFSPR | RT (0) | LR); + tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff)); + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) + tcg_out32 (s, (STW + | RS (div_save_regs[i]) + | RA (1) + | (i * 4 + 8) + ) + ); + tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4)); + tcg_out_mov (s, 4, 6); + tcg_out_b (s, LK, target); + tcg_out_mov (s, 6, 4); + + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) + tcg_out32 (s, (LWZ + | RT (div_save_regs[i]) + | RA (1) + | (i * 4 + 8) + ) + ); + tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4)); + tcg_out32 (s, MTSPR | RS (0) | LR); + tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); + tcg_out32 (s, BCLR | BO_ALWAYS); + } } static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, @@ -1018,41 +1095,6 @@ tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); } -static uint64_t __attribute ((used)) ppc_udiv_helper (uint64_t a, uint32_t b) -{ - uint64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - -static uint64_t __attribute ((used)) ppc_div_helper (int64_t a, int32_t b) -{ - int64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - -#define MAKE_TRAMPOLINE(name) \ -extern void name##_trampoline (void); \ -asm (#name "_trampoline:\n" \ - " mflr 0\n" \ - " addi 1,1,-112\n" \ - " mr 4,6\n" \ - " stmw 7,0(1)\n" \ - " stw 0,108(0)\n" \ - " bl ppc_" #name "_helper\n" \ - " lmw 7,0(1)\n" \ - " lwz 0,108(0)\n" \ - " addi 1,1,112\n" \ - " mtlr 0\n" \ - " blr\n" \ - ) - -MAKE_TRAMPOLINE (div); -MAKE_TRAMPOLINE (udiv); - static void tcg_out_div2 (TCGContext *s, int uns) { void *label1_ptr, *label2_ptr; @@ -1067,7 +1109,7 @@ label1_ptr = s->code_ptr; tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); - tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_trampoline : div_trampoline)); + tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr)); label2_ptr = s->code_ptr; tcg_out32 (s, B);