From patchwork Thu Dec 10 20:04:42 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 40935 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0AB05B7B69 for ; Sat, 12 Dec 2009 12:25:55 +1100 (EST) Received: from localhost ([127.0.0.1]:48157 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NJGk4-0000mQ-5I for incoming@patchwork.ozlabs.org; Fri, 11 Dec 2009 20:25:52 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NJGhs-0007ov-5n for qemu-devel@nongnu.org; Fri, 11 Dec 2009 20:23:36 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NJGho-0007lW-Dd for qemu-devel@nongnu.org; Fri, 11 Dec 2009 20:23:32 -0500 Received: from [199.232.76.173] (port=54744 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NJGhn-0007kg-P2 for qemu-devel@nongnu.org; Fri, 11 Dec 2009 20:23:31 -0500 Received: from are.twiddle.net ([75.149.56.221]:43433) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NJGhm-00035d-Vd for qemu-devel@nongnu.org; Fri, 11 Dec 2009 20:23:31 -0500 Received: by are.twiddle.net (Postfix, from userid 5000) id 5DFFD305; Fri, 11 Dec 2009 17:23:30 -0800 (PST) Message-Id: In-Reply-To: References: From: Richard Henderson Date: Thu, 10 Dec 2009 12:04:42 -0800 To: qemu-devel@nongnu.org MIME-Version: 1.0 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 01/13] alpha: Implement missing MVI instructions. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Richard Henderson --- target-alpha/helper.h | 14 ++++ target-alpha/op_helper.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++ target-alpha/translate.c | 79 +++++++++++++-------- 3 files changed, 231 insertions(+), 30 deletions(-) diff --git a/target-alpha/helper.h b/target-alpha/helper.h index 9c60be1..850ba0d 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -36,6 +36,20 @@ DEF_HELPER_2(insqh, i64, i64, i64) DEF_HELPER_2(cmpbge, i64, i64, i64) +DEF_HELPER_2(minub8, i64, i64, i64) +DEF_HELPER_2(minsb8, i64, i64, i64) +DEF_HELPER_2(minuw4, i64, i64, i64) +DEF_HELPER_2(minsw4, i64, i64, i64) +DEF_HELPER_2(maxub8, i64, i64, i64) +DEF_HELPER_2(maxsb8, i64, i64, i64) +DEF_HELPER_2(maxuw4, i64, i64, i64) +DEF_HELPER_2(maxsw4, i64, i64, i64) +DEF_HELPER_2(perr, i64, i64, i64) +DEF_HELPER_1(pklb, i64, i64) +DEF_HELPER_1(pkwb, i64, i64) +DEF_HELPER_1(unpkbl, i64, i64) +DEF_HELPER_1(unpkbw, i64, i64) + DEF_HELPER_0(load_fpcr, i64) DEF_HELPER_1(store_fpcr, void, i64) diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index 999a8ab..08d5924 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -277,6 +277,174 @@ uint64_t helper_cmpbge (uint64_t op1, uint64_t op2) return res; } +uint64_t helper_minub8 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + uint8_t opa, opb, opr; + int i; + + for (i = 0; i < 8; ++i) { + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); + opr = opa < opb ? opa : opb; + res |= (uint64_t)opr << (i * 8); + } + return res; +} + +uint64_t helper_minsb8 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + int8_t opa, opb; + uint8_t opr; + int i; + + for (i = 0; i < 8; ++i) { + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); + opr = opa < opb ? opa : opb; + res |= (uint64_t)opr << (i * 8); + } + return res; +} + +uint64_t helper_minuw4 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + uint16_t opa, opb, opr; + int i; + + for (i = 0; i < 4; ++i) { + opa = op1 >> (i * 16); + opb = op2 >> (i * 16); + opr = opa < opb ? opa : opb; + res |= (uint64_t)opr << (i * 16); + } + return res; +} + +uint64_t helper_minsw4 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + int16_t opa, opb; + uint16_t opr; + int i; + + for (i = 0; i < 4; ++i) { + opa = op1 >> (i * 16); + opb = op2 >> (i * 16); + opr = opa < opb ? opa : opb; + res |= (uint64_t)opr << (i * 16); + } + return res; +} + +uint64_t helper_maxub8 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + uint8_t opa, opb, opr; + int i; + + for (i = 0; i < 8; ++i) { + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); + opr = opa > opb ? opa : opb; + res |= (uint64_t)opr << (i * 8); + } + return res; +} + +uint64_t helper_maxsb8 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + int8_t opa, opb; + uint8_t opr; + int i; + + for (i = 0; i < 8; ++i) { + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); + opr = opa > opb ? opa : opb; + res |= (uint64_t)opr << (i * 8); + } + return res; +} + +uint64_t helper_maxuw4 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + uint16_t opa, opb, opr; + int i; + + for (i = 0; i < 4; ++i) { + opa = op1 >> (i * 16); + opb = op2 >> (i * 16); + opr = opa > opb ? opa : opb; + res |= (uint64_t)opr << (i * 16); + } + return res; +} + +uint64_t helper_maxsw4 (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + int16_t opa, opb; + uint16_t opr; + int i; + + for (i = 0; i < 4; ++i) { + opa = op1 >> (i * 16); + opb = op2 >> (i * 16); + opr = opa > opb ? opa : opb; + res |= (uint64_t)opr << (i * 16); + } + return res; +} + +uint64_t helper_perr (uint64_t op1, uint64_t op2) +{ + uint64_t res = 0; + uint8_t opa, opb, opr; + int i; + + for (i = 0; i < 8; ++i) { + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); + if (opa >= opb) + opr = opa - opb; + else + opr = opb - opa; + res += opr; + } + return res; +} + +uint64_t helper_pklb (uint64_t op1) +{ + return (op1 & 0xff) | ((op1 >> 24) & 0xff00); +} + +uint64_t helper_pkwb (uint64_t op1) +{ + return ((op1 & 0xff) + | ((op1 >> 8) & 0xff00) + | ((op1 >> 16) & 0xff0000) + | ((op1 >> 24) & 0xff000000)); +} + +uint64_t helper_unpkbl (uint64_t op1) +{ + return (op1 & 0xff) | ((op1 & 0xff00) << 24); +} + +uint64_t helper_unpkbw (uint64_t op1) +{ + return ((op1 & 0xff) + | ((op1 & 0xff00) << 8) + | ((op1 & 0xff0000) << 16) + | ((op1 & 0xff000000) << 24)); +} + /* Floating point helpers */ /* F floating (VAX) */ diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 3f8d1b2..851eb50 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -611,6 +611,30 @@ ARITH3(insqh) ARITH3(umulh) ARITH3(mullv) ARITH3(mulqv) +ARITH3(minub8) +ARITH3(minsb8) +ARITH3(minuw4) +ARITH3(minsw4) +ARITH3(maxub8) +ARITH3(maxsb8) +ARITH3(maxuw4) +ARITH3(maxsw4) +ARITH3(perr) + +#define MVIOP2(name) \ +static inline void glue(gen_, name)(int rb, int rc) \ +{ \ + if (unlikely(rc == 31)) \ + return; \ + if (unlikely(rb == 31)) \ + tcg_gen_movi_i64(cpu_ir[rc], 0); \ + else \ + gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \ +} +MVIOP2(pklb) +MVIOP2(pkwb) +MVIOP2(unpkbl) +MVIOP2(unpkbw) static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit, uint8_t lit) @@ -619,7 +643,7 @@ static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit, TCGv tmp; if (unlikely(rc == 31)) - return; + return; l1 = gen_new_label(); l2 = gen_new_label(); @@ -646,7 +670,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) uint32_t palcode; int32_t disp21, disp16, disp12; uint16_t fn11, fn16; - uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit; + uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit, real_islit; uint8_t lit; int ret; @@ -656,7 +680,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) rb = (insn >> 16) & 0x1F; rc = insn & 0x1F; sbz = (insn >> 13) & 0x07; - islit = (insn >> 12) & 1; + real_islit = islit = (insn >> 12) & 1; if (rb == 31 && !islit) { islit = 1; lit = 0; @@ -1913,8 +1937,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) /* PERR */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_perr(ra, rb, rc, islit, lit); break; case 0x32: /* CTLZ */ @@ -1942,85 +1965,81 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) /* UNPKBW */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + if (real_islit || ra != 31) + goto invalid_opc; + gen_unpkbw (rb, rc); break; case 0x35: - /* UNPKWL */ + /* UNPKBL */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + if (real_islit || ra != 31) + goto invalid_opc; + gen_unpkbl (rb, rc); break; case 0x36: /* PKWB */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + if (real_islit || ra != 31) + goto invalid_opc; + gen_pkwb (rb, rc); break; case 0x37: /* PKLB */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + if (real_islit || ra != 31) + goto invalid_opc; + gen_pklb (rb, rc); break; case 0x38: /* MINSB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_minsb8 (ra, rb, rc, islit, lit); break; case 0x39: /* MINSW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_minsw4 (ra, rb, rc, islit, lit); break; case 0x3A: /* MINUB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_minub8 (ra, rb, rc, islit, lit); break; case 0x3B: /* MINUW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_minuw4 (ra, rb, rc, islit, lit); break; case 0x3C: /* MAXUB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_maxub8 (ra, rb, rc, islit, lit); break; case 0x3D: /* MAXUW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_maxuw4 (ra, rb, rc, islit, lit); break; case 0x3E: /* MAXSB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_maxsb8 (ra, rb, rc, islit, lit); break; case 0x3F: /* MAXSW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; - /* XXX: TODO */ - goto invalid_opc; + gen_maxsw4 (ra, rb, rc, islit, lit); break; case 0x70: /* FTOIT */