From patchwork Tue Feb 11 00:40:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 11374655 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D761D109A for ; Tue, 11 Feb 2020 01:20:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9D9C020708 for ; Tue, 11 Feb 2020 01:20:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="PP+XehqH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9D9C020708 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=quicinc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42086 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1KE3-0002mP-Kb for patchwork-qemu-devel@patchwork.kernel.org; Mon, 10 Feb 2020 20:20:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34641) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1Jd1-0002rx-Vy for qemu-devel@nongnu.org; Mon, 10 Feb 2020 19:42:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j1Jcy-0003uI-SY for qemu-devel@nongnu.org; Mon, 10 Feb 2020 19:42:15 -0500 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:59197) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j1Jcy-0004rC-CP for qemu-devel@nongnu.org; Mon, 10 Feb 2020 19:42:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1581381732; x=1612917732; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uZ0AMtqN/AhARovGOnYVr64WuEeGXI4Cwov9bpYxJt0=; b=PP+XehqHkJbffHWvtWF7EfBbGCU5sQA5wdsaYVOymt/YK21CSEQEVj87 SnoCzeQnLxjHbJCKKTzbfOaAA0PMocWVBgwM5EB5yUycMQOQm6UHF3v0d 1VfOWJGTwQWOZhweF+CqrXeIja8FFJ57kIhjUuSuqw5MO1XsBHZIywceA c=; Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-02.qualcomm.com with ESMTP; 10 Feb 2020 16:41:03 -0800 Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg05-sd.qualcomm.com with ESMTP; 10 Feb 2020 16:41:03 -0800 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 346271B76; Mon, 10 Feb 2020 18:41:03 -0600 (CST) From: Taylor Simpson To: qemu-devel@nongnu.org Subject: [RFC PATCH 58/66] Hexagon HVX semantics generator Date: Mon, 10 Feb 2020 18:40:36 -0600 Message-Id: <1581381644-13678-59-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1581381644-13678-1-git-send-email-tsimpson@quicinc.com> References: <1581381644-13678-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 199.106.114.39 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: riku.voipio@iki.fi, richard.henderson@linaro.org, laurent@vivier.eu, Taylor Simpson , philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Add HVX support to the semantics generator Signed-off-by: Taylor Simpson --- target/hexagon/do_qemu.py | 175 ++++++++++++++++++++++++++++++++++++++--- target/hexagon/gen_semantics.c | 9 +++ 2 files changed, 171 insertions(+), 13 deletions(-) diff --git a/target/hexagon/do_qemu.py b/target/hexagon/do_qemu.py index 974d45e..5b90d32 100755 --- a/target/hexagon/do_qemu.py +++ b/target/hexagon/do_qemu.py @@ -111,6 +111,16 @@ def SEMANTICS(tag, beh, sem): attribdict[tag] = set() tags.append(tag) # dicts have no order, this is for order +def EXT_SEMANTICS(ext, tag, beh, sem): + #print tag,beh,sem + extnames[ext] = True + extdict[tag] = ext + behdict[tag] = beh + semdict[tag] = sem + attribdict[tag] = set() + tags.append(tag) # dicts have no order, this is for order + + def ATTRIBUTES(tag, attribstring): attribstring = \ attribstring.replace("ATTRIBS","").replace("(","").replace(")","") @@ -174,6 +184,9 @@ def compute_tag_immediates(tag): ## P predicate register ## R GPR register ## M modifier register +## Q HVX predicate vector +## V HVX vector register +## O HVX new vector register ## regid can be one of the following ## d, e destination register ## dd destination register pair @@ -205,6 +218,9 @@ def is_readwrite(regid): def is_scalar_reg(regtype): return regtype in "RPC" +def is_hvx_reg(regtype): + return regtype in "VQ" + def is_old_val(regtype, regid, tag): return regtype+regid+'V' in semdict[tag] @@ -215,7 +231,8 @@ tagimms = dict(zip(tags, list(map(compute_tag_immediates, tags)))) def need_slot(tag): if ('A_CONDEXEC' in attribdict[tag] or - 'A_STORE' in attribdict[tag]): + 'A_STORE' in attribdict[tag] or + 'A_CVI' in attribdict[tag]): return 1 else: return 0 @@ -301,19 +318,32 @@ def gen_helper_prototype(f, tag, regs, imms): f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) ## Generate the qemu DEF_HELPER type for each result + ## Iterate over this list twice + ## - Emit the scalar result + ## - Emit the vector result i=0 for regtype,regid,toss,numregs in regs: if (is_written(regid)): - gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) + if (not is_hvx_reg(regtype)): + gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 ## Put the env between the outputs and inputs f.write(', env' ) i += 1 + # Second pass + for regtype,regid,toss,numregs in regs: + if (is_written(regid)): + if (is_hvx_reg(regtype)): + gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + ## Generate the qemu type for each input operand (regs and immediates) for regtype,regid,toss,numregs in regs: if (is_read(regid)): + if (is_hvx_reg(regtype) and is_readwrite(regid)): + continue gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 for immlett,bits,immshift in imms: @@ -441,11 +471,33 @@ def genptr_dst_write(f,regtype, regid): macro = "WRITE_%sREG_%s" % (regtype, regid) f.write("%s(%s%sN, %s%sV);\n" % (macro, regtype, regid, regtype, regid)) +def genptr_dst_write_ext(f, regtype, regid, newv="0"): + macro = "WRITE_%sREG_%s" % (regtype, regid) + f.write("%s(%s%sN, %s%sV,%s);\n" % \ + (macro, regtype, regid, regtype, regid, newv)) + def genptr_dst_write_opn(f,regtype, regid, tag): if (is_pair(regid)): - genptr_dst_write(f, regtype, regid) + if (is_hvx_reg(regtype)): + if ('A_CVI_TMP' in attribdict[tag] or + 'A_CVI_TMP_DST' in attribdict[tag]): + genptr_dst_write_ext(f, regtype, regid, "EXT_TMP") + else: + genptr_dst_write_ext(f, regtype, regid) + else: + genptr_dst_write(f, regtype, regid) elif (is_single(regid)): - genptr_dst_write(f, regtype, regid) + if (is_hvx_reg(regtype)): + if 'A_CVI_NEW' in attribdict[tag]: + genptr_dst_write_ext(f, regtype, regid, "EXT_NEW") + elif 'A_CVI_TMP' in attribdict[tag]: + genptr_dst_write_ext(f, regtype, regid, "EXT_TMP") + elif 'A_CVI_TMP_DST' in attribdict[tag]: + genptr_dst_write_ext(f, regtype, regid, "EXT_TMP") + else: + genptr_dst_write_ext(f, regtype, regid, "EXT_DFL") + else: + genptr_dst_write(f, regtype, regid) else: print("Bad register parse: ",regtype,regid,toss,numregs) @@ -508,13 +560,23 @@ def gen_tcg_func(f, tag, regs, imms): ## If there is a scalar result, it is the return type for regtype,regid,toss,numregs in regs: if (is_written(regid)): + if (is_hvx_reg(regtype)): + continue gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 if (i > 0): f.write(", ") f.write("cpu_env") i=1 for regtype,regid,toss,numregs in regs: + if (is_written(regid)): + if (not is_hvx_reg(regtype)): + continue + gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + for regtype,regid,toss,numregs in regs: if (is_read(regid)): + if (is_hvx_reg(regtype) and is_readwrite(regid)): + continue gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 for immlett,bits,immshift in imms: @@ -577,12 +639,26 @@ def gen_helper_arg_pair(f,regtype,regid,regno): if regno >= 0 : f.write(", ") f.write("int64_t %s%sV" % (regtype,regid)) +def gen_helper_arg_ext(f,regtype,regid,regno): + if regno > 0 : f.write(", ") + f.write("void *%s%sV_void" % (regtype,regid)) + +def gen_helper_arg_ext_pair(f,regtype,regid,regno): + if regno > 0 : f.write(", ") + f.write("void *%s%sV_void" % (regtype,regid)) + def gen_helper_arg_opn(f,regtype,regid,i): if (is_pair(regid)): - gen_helper_arg_pair(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_arg_ext_pair(f,regtype,regid,i) + else: + gen_helper_arg_pair(f,regtype,regid,i) elif (is_single(regid)): if is_old_val(regtype, regid, tag): - gen_helper_arg(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_arg_ext(f,regtype,regid,i) + else: + gen_helper_arg(f,regtype,regid,i) elif is_new_val(regtype, regid, tag): gen_helper_arg_new(f,regtype,regid,i) else: @@ -601,25 +677,61 @@ def gen_helper_dest_decl_pair(f,regtype,regid,regno,subfield=""): f.write("int64_t %s%sV%s = 0;\n" % \ (regtype,regid,subfield)) +def gen_helper_dest_decl_ext(f,regtype,regid): + f.write("/* %s%sV is *(mmvector_t*)(%s%sV_void) */\n" % \ + (regtype,regid,regtype,regid)) + +def gen_helper_dest_decl_ext_pair(f,regtype,regid,regno): + f.write("/* %s%sV is *(mmvector_pair_t*))%s%sV_void) */\n" % \ + (regtype,regid,regtype, regid)) + def gen_helper_dest_decl_opn(f,regtype,regid,i): if (is_pair(regid)): - gen_helper_dest_decl_pair(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_dest_decl_ext_pair(f,regtype,regid, i) + else: + gen_helper_dest_decl_pair(f,regtype,regid,i) elif (is_single(regid)): - gen_helper_dest_decl(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_dest_decl_ext(f,regtype,regid) + else: + gen_helper_dest_decl(f,regtype,regid,i) else: print("Bad register parse: ",regtype,regid,toss,numregs) +def gen_helper_src_var_ext(f,regtype,regid): + f.write("/* %s%sV is *(mmvector_t*)(%s%sV_void) */\n" % \ + (regtype,regid,regtype,regid)) + +def gen_helper_src_var_ext_pair(f,regtype,regid,regno): + f.write("/* %s%sV%s is *(mmvector_pair_t*)(%s%sV%s_void) */\n" % \ + (regtype,regid,regno,regtype,regid,regno)) + def gen_helper_return(f,regtype,regid,regno): f.write("return %s%sV;\n" % (regtype,regid)) def gen_helper_return_pair(f,regtype,regid,regno): f.write("return %s%sV;\n" % (regtype,regid)) +def gen_helper_dst_write_ext(f,regtype,regid): + f.write("/* %s%sV is *(mmvector_t*)%s%sV_void */\n" % \ + (regtype,regid,regtype,regid)) + +def gen_helper_dst_write_ext_pair(f,regtype,regid): + f.write("/* %s%sV is *(mmvector_pair_t*)%s%sV_void */\n" % \ + (regtype,regid, regtype,regid)) + def gen_helper_return_opn(f, regtype, regid, i): if (is_pair(regid)): - gen_helper_return_pair(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_dst_write_ext_pair(f,regtype,regid) + else: + gen_helper_return_pair(f,regtype,regid,i) elif (is_single(regid)): - gen_helper_return(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + gen_helper_dst_write_ext(f,regtype,regid) + else: + gen_helper_return(f,regtype,regid,i) else: print("Bad register parse: ",regtype,regid,toss,numregs) @@ -658,14 +770,20 @@ def gen_helper_definition(f, tag, regs, imms): % (tag, tag)) else: ## The return type of the function is the type of the destination - ## register + ## register (if scalar) i=0 for regtype,regid,toss,numregs in regs: if (is_written(regid)): if (is_pair(regid)): - gen_helper_return_type_pair(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + continue + else: + gen_helper_return_type_pair(f,regtype,regid,i) elif (is_single(regid)): - gen_helper_return_type(f,regtype,regid,i) + if (is_hvx_reg(regtype)): + continue + else: + gen_helper_return_type(f,regtype,regid,i) else: print("Bad register parse: ",regtype,regid,toss,numregs) i += 1 @@ -674,10 +792,30 @@ def gen_helper_definition(f, tag, regs, imms): f.write("void") f.write(" HELPER(%s)(CPUHexagonState *env" % tag) + ## Arguments include the vector destination operands i = 1 + for regtype,regid,toss,numregs in regs: + if (is_written(regid)): + if (is_pair(regid)): + if (is_hvx_reg(regtype)): + gen_helper_arg_ext_pair(f,regtype,regid,i) + else: + continue + elif (is_single(regid)): + if (is_hvx_reg(regtype)): + gen_helper_arg_ext(f,regtype,regid,i) + else: + # This is the return value of the function + continue + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + i += 1 + ## Arguments to the helper function are the source regs and immediates for regtype,regid,toss,numregs in regs: if (is_read(regid)): + if (is_hvx_reg(regtype) and is_readwrite(regid)): + continue gen_helper_arg_opn(f,regtype,regid,i) i += 1 for immlett,bits,immshift in imms: @@ -700,6 +838,17 @@ def gen_helper_definition(f, tag, regs, imms): gen_helper_dest_decl_opn(f,regtype,regid,i) i += 1 + for regtype,regid,toss,numregs in regs: + if (is_read(regid)): + if (is_pair(regid)): + if (is_hvx_reg(regtype)): + gen_helper_src_var_ext_pair(f,regtype,regid,i) + elif (is_single(regid)): + if (is_hvx_reg(regtype)): + gen_helper_src_var_ext(f,regtype,regid) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + if 'A_FPOP' in attribdict[tag]: f.write('fFPOP_START();\n'); diff --git a/target/hexagon/gen_semantics.c b/target/hexagon/gen_semantics.c index 2211ae6..8fd97c7 100644 --- a/target/hexagon/gen_semantics.c +++ b/target/hexagon/gen_semantics.c @@ -87,6 +87,15 @@ int main(int argc, char *argv[]) #include "imported/macros.def" #undef DEF_MACRO +/* + * Process the macros for HVX + */ +#define DEF_MACRO(MNAME, PARAMS, SDESC, LDESC, BEH, ATTRS) \ + fprintf(outfile, "MACROATTRIB(\"%s\",\"\"\"%s\"\"\",\"%s\",\"%s\")\n", \ + #MNAME, STRINGIZE(BEH), STRINGIZE(ATTRS), EXTSTR); +#include "imported/allext_macros.def" +#undef DEF_MACRO + fclose(outfile); return 0; }