From patchwork Sat Dec 24 11:40:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 708658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tm3ZW27dhz9t0G for ; Sat, 24 Dec 2016 22:54:11 +1100 (AEDT) Received: from localhost ([::1]:43179 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cKktt-0001nv-7j for incoming@patchwork.ozlabs.org; Sat, 24 Dec 2016 06:54:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45396) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cKkh0-0007Ly-KL for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cKkgz-0007zi-0C for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:50 -0500 Received: from mout.kundenserver.de ([212.227.17.13]:57894) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cKkgy-0007zO-K7 for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:48 -0500 Received: from Quad.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue102 [212.227.15.183]) with ESMTPSA (Nemesis) id 0M40x8-1cbrpl1lP0-00rZe2; Sat, 24 Dec 2016 12:40:39 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Sat, 24 Dec 2016 12:40:23 +0100 Message-Id: <1482579633-3393-3-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482579633-3393-1-git-send-email-laurent@vivier.eu> References: <1482579633-3393-1-git-send-email-laurent@vivier.eu> X-Provags-ID: V03:K0:rHWwNILEaoo3rNeh69DaP6Mj1ySW1Vx2x0SOTHfgQFiIvnhtywL iZmWDbm4w+b3mHZ4FZGFBuxZbjbcCI+gi2BcpkIkm/U1HhQiSpM+3Dq2v08nm2NcWqIa9o/ SFpZReKCgWPxoyBmp0SCoBaCJcY3rgdVRl24voQjSEcB9MlI4Qd/ksyHw7wZLWQ8iSDxQkw 3juBnvn/GChFsvqOtpG5Q== X-UI-Out-Filterresults: notjunk:1; V01:K0:JnmJqnIFnR8=:EX0ohdGOjtxEklUndYmDWK c/lo183ZHACKbqhglhPuNtA3xjyCLQlRyP6zSxurxW5yuHnQSg13nh3NQNrW6jNrNqrQhA5oJ ek51ksYUltLhdWmhGLrRP5rf+QwWZUGswEs3EOXLd6BTWwT7FcrPuxJ7seyJVj7iG+R+axBlF D9J04my8y1IXxYqPqlIUF7/S+8lHUpY5Ij2gtGqlDgiPPR8o19PoYzsVhqC6wOOCwmCKiEEKh 3Ibx1BKXkqpi/oofilpSmHkC/b5gn0toTPMMDuO+aPSowsZrWk7mYRVNJb+pUS0tA7uPZcX71 GF1i8NT7CN3uAW67YI1i8K1A6gPJU8fgGaKKOFr9L5N/QH6MLomrXDEid7s6ZW2sCe3UepXrp jy+sMYmhwWj5MAVy9y45wrEjyZqT7R3ImNiLrAayV8KWi18I1IJ0bYH8aEeanZuGa5iuW5ugV jezKQegDSxsmGOsR4xw67/Qa0TAY1HiWQMDt7Vuzu/1WdcSU/l87vcyFD+XHCuRyEOsmX6wGA fDeVJ2vTnC0HKFtf1xVQGcKCNkEz41BeG8K6BT5EOmWv9oUrLSysvwCR4X0FFi7RMn2F7oamn 8p80FnFH0P+Rx6ly2ERkFnZWq6tHHGlfsvTm42OgETyFLNwCp/0oTEZapIlbBwLit8RsUwp47 OSm6zOLcDAvuezqGYwkvwOIMsUrpCGYn3s/xeuJ1tTdtZFn89Blm3K+LGuN0bb473IzU= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.13 Subject: [Qemu-devel] [PULL 02/12] target-m68k: Split gen_lea and gen_ea X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Provide gen_lea_mode and gen_ea_mode, where the mode can be specified manually, rather than taken from the instruction. Signed-off-by: Richard Henderson Message-Id: <1478206203-4606-3-git-send-email-rth@twiddle.net> --- target/m68k/translate.c | 112 +++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index a9066dc..aaa221e 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -697,37 +697,37 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv val) /* Generate code for an "effective address". Does not adjust the base register for autoincrement addressing modes. */ -static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, - int opsize) +static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s, + int mode, int reg0, int opsize) { TCGv reg; TCGv tmp; uint16_t ext; uint32_t offset; - switch ((insn >> 3) & 7) { + switch (mode) { case 0: /* Data register direct. */ case 1: /* Address register direct. */ return NULL_QREG; case 2: /* Indirect register */ case 3: /* Indirect postincrement. */ - return AREG(insn, 0); + return get_areg(s, reg0); case 4: /* Indirect predecrememnt. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); tmp = tcg_temp_new(); tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize)); return tmp; case 5: /* Indirect displacement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); tmp = tcg_temp_new(); ext = read_im16(env, s); tcg_gen_addi_i32(tmp, reg, (int16_t)ext); return tmp; case 6: /* Indirect index + displacement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); return gen_lea_indexed(env, s, reg); case 7: /* Other */ - switch (insn & 7) { + switch (reg0) { case 0: /* Absolute short. */ offset = (int16_t)read_im16(env, s); return tcg_const_i32(offset); @@ -749,39 +749,26 @@ static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, return NULL_QREG; } -/* Helper function for gen_ea. Reuse the computed address between the - for read/write operands. */ -static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s, - uint16_t insn, int opsize, TCGv val, - TCGv *addrp, ea_what what) +static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize) { - TCGv tmp; - - if (addrp && what == EA_STORE) { - tmp = *addrp; - } else { - tmp = gen_lea(env, s, insn, opsize); - if (IS_NULL_QREG(tmp)) - return tmp; - if (addrp) - *addrp = tmp; - } - return gen_ldst(s, opsize, tmp, val, what); + int mode = extract32(insn, 3, 3); + int reg0 = REG(insn, 0); + return gen_lea_mode(env, s, mode, reg0, opsize); } -/* Generate code to load/store a value from/into an EA. If VAL > 0 this is +/* Generate code to load/store a value from/into an EA. If WHAT > 0 this is a write otherwise it is a read (0 == sign extend, -1 == zero extend). ADDRP is non-null for readwrite operands. */ -static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, - int opsize, TCGv val, TCGv *addrp, ea_what what) +static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0, + int opsize, TCGv val, TCGv *addrp, ea_what what) { - TCGv reg; - TCGv result; - uint32_t offset; + TCGv reg, tmp, result; + int32_t offset; - switch ((insn >> 3) & 7) { + switch (mode) { case 0: /* Data register direct. */ - reg = DREG(insn, 0); + reg = cpu_dregs[reg0]; if (what == EA_STORE) { gen_partset_reg(opsize, reg, val); return store_dummy; @@ -789,7 +776,7 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return gen_extend(reg, opsize, what == EA_LOADS); } case 1: /* Address register direct. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); if (what == EA_STORE) { tcg_gen_mov_i32(reg, val); return store_dummy; @@ -797,45 +784,56 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return gen_extend(reg, opsize, what == EA_LOADS); } case 2: /* Indirect register */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); return gen_ldst(s, opsize, reg, val, what); case 3: /* Indirect postincrement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); result = gen_ldst(s, opsize, reg, val, what); if (what == EA_STORE || !addrp) { TCGv tmp = tcg_temp_new(); tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize)); - delay_set_areg(s, REG(insn, 0), tmp, true); + delay_set_areg(s, reg0, tmp, true); } return result; case 4: /* Indirect predecrememnt. */ - { - TCGv tmp; - if (addrp && what == EA_STORE) { - tmp = *addrp; - } else { - tmp = gen_lea(env, s, insn, opsize); - if (IS_NULL_QREG(tmp)) - return tmp; - if (addrp) - *addrp = tmp; + if (addrp && what == EA_STORE) { + tmp = *addrp; + } else { + tmp = gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(tmp)) { + return tmp; } - result = gen_ldst(s, opsize, tmp, val, what); - if (what == EA_STORE || !addrp) { - delay_set_areg(s, REG(insn, 0), tmp, false); + if (addrp) { + *addrp = tmp; } } + result = gen_ldst(s, opsize, tmp, val, what); + if (what == EA_STORE || !addrp) { + delay_set_areg(s, reg0, tmp, false); + } return result; case 5: /* Indirect displacement. */ case 6: /* Indirect index + displacement. */ - return gen_ea_once(env, s, insn, opsize, val, addrp, what); + do_indirect: + if (addrp && what == EA_STORE) { + tmp = *addrp; + } else { + tmp = gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(tmp)) { + return tmp; + } + if (addrp) { + *addrp = tmp; + } + } + return gen_ldst(s, opsize, tmp, val, what); case 7: /* Other */ - switch (insn & 7) { + switch (reg0) { case 0: /* Absolute short. */ case 1: /* Absolute long. */ case 2: /* pc displacement */ case 3: /* pc index+displacement. */ - return gen_ea_once(env, s, insn, opsize, val, addrp, what); + goto do_indirect; case 4: /* Immediate. */ /* Sign extend values for consistency. */ switch (opsize) { @@ -868,6 +866,14 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return NULL_QREG; } +static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize, TCGv val, TCGv *addrp, ea_what what) +{ + int mode = extract32(insn, 3, 3); + int reg0 = REG(insn, 0); + return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what); +} + typedef struct { TCGCond tcond; bool g1;