From patchwork Thu Oct 29 23:58:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F00CC2D0A3 for ; Fri, 30 Oct 2020 00:00:49 +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 DAC8D2076B for ; Fri, 30 Oct 2020 00:00:48 +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="ZIlDZ7/L" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DAC8D2076B 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHqZ-0001Gs-1O for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:00:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37056) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHop-00082P-RV for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:58:59 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:54880) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHom-0004Kz-NQ for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:58:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015936; x=1635551936; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wrhw+HUlj4sJBBnLINhw9+QtFSyOzOEUrVXfEjv+HqI=; b=ZIlDZ7/L6fmNb5DVepLdsa8ZjyRSpqze/mMl62ghpMv8EswltQWk8lnh 8FdsMVF9DCPiOf0I6RE3SBtVd7ckrt4pTge818fIEWiiLCbobRTTwkwZK VL0bxZAOFNl6K+9i++zv3cc9qKFuYWh6fjRhaMt3kB0t6awtZpo71CSgA 0=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:53 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg02-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:52 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 6E7AA410F; Thu, 29 Oct 2020 18:58:52 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 01/33] Hexagon Update MAINTAINERS file Date: Thu, 29 Oct 2020 18:58:18 -0500 Message-Id: <1604015931-23005-2-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add Taylor Simpson as the Hexagon target maintainer Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8c744a9..ba93512 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -184,6 +184,14 @@ F: include/hw/cris/ F: tests/tcg/cris/ F: disas/cris.c +Hexagon TCG CPUs +M: Taylor Simpson +S: Supported +F: target/hexagon/ +F: linux-user/hexagon/ +F: disas/hexagon.c +F: default-configs/hexagon-linux-user.mak + HPPA (PA-RISC) TCG CPUs M: Richard Henderson S: Maintained From patchwork Thu Oct 29 23:58:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2B13C4741F for ; Fri, 30 Oct 2020 00:06:20 +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 F3DC420724 for ; Fri, 30 Oct 2020 00:06:19 +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="rvtAzqO2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F3DC420724 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50976 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHvu-0008Mn-SE for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:06:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37092) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHos-000856-6N for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:02 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:62907) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHom-0004LA-TW for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015936; x=1635551936; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IsMjxbSqC4fk05GZxfaZe7SbJnqOKRw9CBj/HEMsxVM=; b=rvtAzqO2ylH/rCwA4Q/duonda4ZVTNR36mWBYZALxVce6DYqheQ4lov3 ABfJ9g3Bnd35TMghYrCCIOA+47YHCyKhQZXZw6CTIuLEXAbxtkkm59T9r Z/lNKXVK7Eb/+d1LSLrttkKliXZLe4XgfEJtjW29LbYbNm8uFOAzwDG0J Y=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:53 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg02-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:52 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 831304115; Thu, 29 Oct 2020 18:58:52 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 02/33] Hexagon (target/hexagon) README Date: Thu, 29 Oct 2020 18:58:19 -0500 Message-Id: <1604015931-23005-3-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Gives an introduction and overview to the Hexagon target Signed-off-by: Taylor Simpson --- target/hexagon/README | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 target/hexagon/README diff --git a/target/hexagon/README b/target/hexagon/README new file mode 100644 index 0000000..1d48eee --- /dev/null +++ b/target/hexagon/README @@ -0,0 +1,235 @@ +Hexagon is Qualcomm's very long instruction word (VLIW) digital signal +processor(DSP). + +The following versions of the Hexagon core are supported + Scalar core: v67 + https://developer.qualcomm.com/downloads/qualcomm-hexagon-v67-programmer-s-reference-manual + +We presented an overview of the project at the 2019 KVM Forum. + https://kvmforum2019.sched.com/event/Tmwc/qemu-hexagon-automatic-translation-of-the-isa-manual-pseudcode-to-tiny-code-instructions-of-a-vliw-architecture-niccolo-izzo-revng-taylor-simpson-qualcomm-innovation-center + +*** Tour of the code *** + +The qemu-hexagon implementation is a combination of qemu and the Hexagon +architecture library (aka archlib). The three primary directories with +Hexagon-specific code are + + qemu/target/hexagon + This has all the instruction and packet semantics + qemu/target/hexagon/imported + These files are imported with very little modification from archlib + *.idef Instruction semantics definition + macros.def Mapping of macros to instruction attributes + encode*.def Encoding patterns for each instruction + iclass.def Instruction class definitions used to determine + legal VLIW slots for each instruction + qemu/linux-user/hexagon + Helpers for loading the ELF file and making Linux system calls, + signals, etc + +We start with scripts that generate a bunch of include files. This +is a two step process. The first step is to use the C preprocessor to expand +macros inside the architecture definition files. This is done in +target/hexagon/gen_semantics.c. This step produces + /target/hexagon/semantics_generated.pyinc. +That file is consumed by the following python scripts to produce the indicated +header files in /target/hexagon + gen_opcodes_def.py -> opcodes_def_generated.h + gen_op_regs.py -> op_regs_generated.h + gen_printinsn.py -> printinsn_generated.h + gen_op_attribs.py -> op_attribs_generated.h + gen_helper_protos.py -> helper_protos_generated.h + gen_shortcode.py -> shortcode_generated.h + gen_tcg_funcs.py -> tcg_funcs_generated.h + gen_tcg_func_table.py -> tcg_func_table_generated.h + gen_helper_funcs.py -> helper_funcs_generated.h + +Qemu helper functions have 3 parts + DEF_HELPER declaration indicates the signature of the helper + gen_helper_ will generate a TCG call to the helper function + The helper implementation + +Here's an example of the A2_add instruction. + Instruction tag A2_add + Assembly syntax "Rd32=add(Rs32,Rt32)" + Instruction semantics "{ RdV=RsV+RtV;}" + +By convention, the operands are identified by letter + RdV is the destination register + RsV, RtV are source registers + +The generator uses the operand naming conventions (see large comment in +hex_common.py) to determine the signature of the helper function. Here are the +results for A2_add + +helper_protos_generated.h + DEF_HELPER_3(A2_add, s32, env, s32, s32) + +tcg_funcs_generated.h + static void generate_A2_add( + CPUHexagonState *env, + DisasContext *ctx, + Insn *insn, + Packet *pkt) + { + TCGv RdV = tcg_temp_local_new(); + const int RdN = insn->regno[0]; + TCGv RsV = hex_gpr[insn->regno[1]]; + TCGv RtV = hex_gpr[insn->regno[2]]; + gen_helper_A2_add(RdV, cpu_env, RsV, RtV); + gen_log_reg_write(RdN, RdV); + ctx_log_reg_write(ctx, RdN); + tcg_temp_free(RdV); + } + +helper_funcs_generated.h + int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV) + { + uint32_t slot __attribute__((unused)) = 4; + int32_t RdV = 0; + { RdV=RsV+RtV;} + return RdV; + } + +Note that generate_A2_add updates the disassembly context to be processed +when the packet commits (see "Packet Semantics" below). + +The generator checks for fGEN_TCG_ macro. This allows us to generate +TCG code instead of a call to the helper. If defined, the macro takes 1 +argument. + C semantics (aka short code) + +This allows the code generator to override the auto-generated code. In some +cases this is necessary for correct execution. We can also override for +faster emulation. For example, calling a helper for add is more expensive +than generating a TCG add operation. + +The gen_tcg.h file has any overrides. For example, we could write + #define fGEN_TCG_A2_add(GENHLPR, SHORTCODE) \ + tcg_gen_add_tl(RdV, RsV, RtV) + +The instruction semantics C code relies heavily on macros. In cases where the +C semantics are specified only with macros, we can override the default with +the short semantics option and #define the macros to generate TCG code. One +example is L2_loadw_locked: + Instruction tag L2_loadw_locked + Assembly syntax "Rd32=memw_locked(Rs32)" + Instruction semantics "{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }" + +In gen_tcg.h, we use the shortcode +#define fGEN_TCG_L2_loadw_locked(SHORTCODE) \ + SHORTCODE + +There are also cases where we brute force the TCG code generation. +Instructions with multiple definitions are examples. These require special +handling because qemu helpers can only return a single value. + +In addition to instruction semantics, we use a generator to create the decode +tree. This generation is also a two step process. The first step is to run +target/hexagon/gen_dectree_import.c to produce + /target/hexagon/iset.py +This file is imported by target/hexagon/dectree.py to produce + /target/hexagon/dectree_generated.h + +*** Key Files *** + +cpu.h + +This file contains the definition of the CPUHexagonState struct. It is the +runtime information for each thread and contains stuff like the GPR and +predicate registers. + +macros.h + +The Hexagon arch lib relies heavily on macros for the instruction semantics. +This is a great advantage for qemu because we can override them for different +purposes. You will also notice there are sometimes two definitions of a macro. +The QEMU_GENERATE variable determines whether we want the macro to generate TCG +code. If QEMU_GENERATE is not defined, we want the macro to generate vanilla +C code that will work in the helper implementation. + +translate.c + +The functions in this file generate TCG code for a translation block. Some +important functions in this file are + + gen_start_packet - initialize the data structures for packet semantics + gen_commit_packet - commit the register writes, stores, etc for a packet + decode_and_translate_packet - disassemble a packet and generate code + +genptr.c +gen_tcg.h + +These files create a function for each instruction. It is mostly composed of +fGEN_TCG_ definitions followed by including tcg_funcs_generated.h. + +op_helper.c + +This file contains the implementations of all the helpers. There are a few +general purpose helpers, but most of them are generated by including +helper_funcs_generated.h. There are also several helpers used for debugging. + + +*** Packet Semantics *** + +VLIW packet semantics differ from serial semantics in that all input operands +are read, then the operations are performed, then all the results are written. +For exmaple, this packet performs a swap of registers r0 and r1 + { r0 = r1; r1 = r0 } +Note that the result is different if the instructions are executed serially. + +Packet semantics dictate that we defer any changes of state until the entire +packet is committed. We record the results of each instruction in a side data +structure, and update the visible processor state when we commit the packet. + +The data structures are divided between the runtime state and the translation +context. + +During the TCG generation (see translate.[ch]), we use the DisasContext to +track what needs to be done during packet commit. Here are the relevant +fields + + reg_log list of registers written + reg_log_idx index into ctx_reg_log + pred_log list of predicates written + pred_log_idx index into ctx_pred_log + store_width width of stores (indexed by slot) + +During runtime, the following fields in CPUHexagonState (see cpu.h) are used + + new_value new value of a given register + reg_written boolean indicating if register was written + new_pred_value new value of a predicate register + pred_written boolean indicating if predicate was written + mem_log_stores record of the stores (indexed by slot) + +*** Debugging *** + +You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in +internal.h. This will stream a lot of information as it generates TCG and +executes the code. + +To track down nasty issues with Hexagon->TCG generation, we compare the +execution results with actual hardware running on a Hexagon Linux target. +Run qemu with the "-d cpu" option. Then, we can diff the results and figure +out where qemu and hardware behave differently. + +The stacks are located at different locations. We handle this by changing +env->stack_adjust in translate.c. First, set this to zero and run qemu. +Then, change env->stack_adjust to the difference between the two stack +locations. Then rebuild qemu and run again. That will produce a very +clean diff. + +Here are some handy places to set breakpoints + + At the call to gen_start_packet for a given PC (note that the line number + might change in the future) + br translate.c:602 if ctx->base.pc_next == 0xdeadbeef + The helper function for each instruction is named helper_, so here's + an example that will set a breakpoint at the start + br helper_A2_add + If you have the HEX_DEBUG macro set, the following will be useful + At the start of execution of a packet for a given PC + br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef + At the end of execution of a packet for a given PC + br helper_debug_commit_end if env->this_PC == 0xdeadbeef From patchwork Thu Oct 29 23:58:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88F7DC4742C for ; Fri, 30 Oct 2020 00:04:11 +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 F11D020724 for ; Fri, 30 Oct 2020 00:04:10 +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="tn2SSP9v" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F11D020724 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42662 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHtp-0004sy-UJ for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:04:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37078) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHor-00082y-2t for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:01 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:48752) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHon-0004LT-6t for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015937; x=1635551937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OU3eiNWH0dvHEp0gcXayEbYHbKv2nxVLisPkhN0hwbo=; b=tn2SSP9vCpNhCjp8Tl1CftgIvXejKafDns+iYuRIIeiiXf47ViJK0MDp 5hTM7Ib2EMIc4DJz7N3r2+jPNsYxCnB7wSP9G2TeFSRSoufmQhk8t+te+ OtwvioW2pNCCX0/SbXJ1LQiQEBgIsHttTGN6LAbBYm8LK/ysPvboT3ECD s=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:53 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:53 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id D73DC411A; Thu, 29 Oct 2020 18:58:52 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 05/33] Hexagon (disas) disassembler Date: Thu, 29 Oct 2020 18:58:22 -0500 Message-Id: <1604015931-23005-6-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add hexagon to disas/meson.build Add disas/hexagon.c Add hexagon to include/disas/dis-asm.h Signed-off-by: Taylor Simpson --- include/disas/dis-asm.h | 1 + disas/hexagon.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ disas/meson.build | 1 + 3 files changed, 70 insertions(+) create mode 100644 disas/hexagon.c diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index 2164762..1f54fc0 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -459,6 +459,7 @@ int print_insn_xtensa (bfd_vma, disassemble_info*); int print_insn_riscv32 (bfd_vma, disassemble_info*); int print_insn_riscv64 (bfd_vma, disassemble_info*); int print_insn_rx(bfd_vma, disassemble_info *); +int print_insn_hexagon(bfd_vma, disassemble_info *); #ifdef CONFIG_CAPSTONE bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); diff --git a/disas/hexagon.c b/disas/hexagon.c new file mode 100644 index 0000000..968f11c --- /dev/null +++ b/disas/hexagon.c @@ -0,0 +1,68 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * QEMU Hexagon Disassembler + */ + +#include "qemu/osdep.h" +#include "disas/dis-asm.h" +#include "target/hexagon/cpu_bits.h" + +/* + * We will disassemble a packet with up to 4 instructions, so we need + * a hefty size buffer. + */ +#define PACKET_BUFFER_LEN 1028 + +int print_insn_hexagon(bfd_vma memaddr, struct disassemble_info *info) +{ + uint32_t words[PACKET_WORDS_MAX]; + bool found_end = false; + char buf[PACKET_BUFFER_LEN]; + int i; + + for (i = 0; i < PACKET_WORDS_MAX && !found_end; i++) { + int status = (*info->read_memory_func)(memaddr + i * sizeof(uint32_t), + (bfd_byte *)&words[i], + sizeof(uint32_t), info); + if (status) { + if (i > 0) { + break; + } + (*info->memory_error_func)(status, memaddr, info); + return status; + } + if (is_packet_end(words[i])) { + found_end = true; + } + } + + if (!found_end) { + (*info->fprintf_func)(info->stream, ""); + return PACKET_WORDS_MAX * 4; + } + + int len = disassemble_hexagon(words, i, memaddr, buf, PACKET_BUFFER_LEN); + int slen = strlen(buf); + if (buf[slen - 1] == '\n') { + buf[slen - 1] = '\0'; + } + (*info->fprintf_func)(info->stream, "%s", buf); + + return len; +} diff --git a/disas/meson.build b/disas/meson.build index 09a8527..be878c0 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -7,6 +7,7 @@ common_ss.add_all(when: 'CONFIG_ARM_A64_DIS', if_true: libvixl_ss) common_ss.add(when: 'CONFIG_ARM_DIS', if_true: files('arm.c')) common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c')) common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) +common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c')) common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c')) common_ss.add(when: 'CONFIG_LM32_DIS', if_true: files('lm32.c')) common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) From patchwork Thu Oct 29 23:58:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7ACAC2D0A3 for ; Fri, 30 Oct 2020 00:05:20 +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 04D7920724 for ; Fri, 30 Oct 2020 00:05:19 +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="WS+FH5Nc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 04D7920724 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:47038 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHuw-0006gZ-QY for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:05:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37268) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHp1-0008TC-Sj for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:11 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:45885) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHoz-0004LV-EK for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015949; x=1635551949; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3oQkrRpo7U0k1j06uRl+Ko8wJbT7hHLbi+yTj6D9sHY=; b=WS+FH5NcR5aa/F+cFIIEmS49uodBiY5cMqq6BQi1gRNhbJWHSqh8Sd8E qXLp56A+KP3BEAxOxzYRm2YemY6XwTNNg+dC8WXIuGLOwLNda2UVCz7UV aQlXhBp3Os6zoNPeeFoRkEPgc/VBlAEeteHsuLEB7rFG4nQ8KJu+yR1IW 8=; Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-01.qualcomm.com with ESMTP; 29 Oct 2020 16:59:01 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg05-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:59 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id EA0AC40D0; Thu, 29 Oct 2020 18:58:52 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 06/33] Hexagon (target/hexagon) register names Date: Thu, 29 Oct 2020 18:58:23 -0500 Message-Id: <1604015931-23005-7-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.38; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-01.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson --- target/hexagon/hex_regs.h | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 target/hexagon/hex_regs.h diff --git a/target/hexagon/hex_regs.h b/target/hexagon/hex_regs.h new file mode 100644 index 0000000..3b4249a --- /dev/null +++ b/target/hexagon/hex_regs.h @@ -0,0 +1,83 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_REGS_H +#define HEXAGON_REGS_H + +enum { + HEX_REG_R00 = 0, + HEX_REG_R01 = 1, + HEX_REG_R02 = 2, + HEX_REG_R03 = 3, + HEX_REG_R04 = 4, + HEX_REG_R05 = 5, + HEX_REG_R06 = 6, + HEX_REG_R07 = 7, + HEX_REG_R08 = 8, + HEX_REG_R09 = 9, + HEX_REG_R10 = 10, + HEX_REG_R11 = 11, + HEX_REG_R12 = 12, + HEX_REG_R13 = 13, + HEX_REG_R14 = 14, + HEX_REG_R15 = 15, + HEX_REG_R16 = 16, + HEX_REG_R17 = 17, + HEX_REG_R18 = 18, + HEX_REG_R19 = 19, + HEX_REG_R20 = 20, + HEX_REG_R21 = 21, + HEX_REG_R22 = 22, + HEX_REG_R23 = 23, + HEX_REG_R24 = 24, + HEX_REG_R25 = 25, + HEX_REG_R26 = 26, + HEX_REG_R27 = 27, + HEX_REG_R28 = 28, + HEX_REG_R29 = 29, + HEX_REG_SP = 29, + HEX_REG_FP = 30, + HEX_REG_R30 = 30, + HEX_REG_LR = 31, + HEX_REG_R31 = 31, + HEX_REG_SA0 = 32, + HEX_REG_LC0 = 33, + HEX_REG_SA1 = 34, + HEX_REG_LC1 = 35, + HEX_REG_P3_0 = 36, + HEX_REG_M0 = 38, + HEX_REG_M1 = 39, + HEX_REG_USR = 40, + HEX_REG_PC = 41, + HEX_REG_UGP = 42, + HEX_REG_GP = 43, + HEX_REG_CS0 = 44, + HEX_REG_CS1 = 45, + HEX_REG_UPCYCLELO = 46, + HEX_REG_UPCYCLEHI = 47, + HEX_REG_FRAMELIMIT = 48, + HEX_REG_FRAMEKEY = 49, + HEX_REG_PKTCNTLO = 50, + HEX_REG_PKTCNTHI = 51, + /* Use reserved control registers for qemu execution counts */ + HEX_REG_QEMU_PKT_CNT = 52, + HEX_REG_QEMU_INSN_CNT = 53, + HEX_REG_UTIMERLO = 62, + HEX_REG_UTIMERHI = 63, +}; + +#endif From patchwork Thu Oct 29 23:58:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316576 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97A98C2D0A3 for ; Fri, 30 Oct 2020 00:21:43 +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 C9BAC20756 for ; Fri, 30 Oct 2020 00:21:42 +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="O+iWxnup" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C9BAC20756 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:59518 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYIAn-0007C0-Ob for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:21:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37232) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHoz-0008Lo-74 for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:09 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:45885) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHow-0004LV-Dp for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015946; x=1635551946; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uglsZ3eiI/MMkCcfScADMxe/ATBlY3PIwVJOHPBy3ws=; b=O+iWxnupRJVvbJTCByarCTUbTeoUtK7YMuVVtfGKdGnSJ3ZCi9Eu3wAe YTnmXKwaTjn9gWsqsB3ziBQ/qGgC0zepIoNIVKOvXqxEV7JtkhZ6/3RPG prxiZV7EItsmUqs+an1Z8OUKm7p1zUBWa81REJS/cFX4x3+eObkY0AgoE w=; Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-01.qualcomm.com with ESMTP; 29 Oct 2020 16:59:01 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg05-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:59 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 41BD14116; Thu, 29 Oct 2020 18:58:53 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 09/33] Hexagon (target/hexagon) architecture types Date: Thu, 29 Oct 2020 18:58:26 -0500 Message-Id: <1604015931-23005-10-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.38; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-01.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Define types used in files imported from the Hexagon architecture library Signed-off-by: Taylor Simpson --- target/hexagon/hex_arch_types.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 target/hexagon/hex_arch_types.h diff --git a/target/hexagon/hex_arch_types.h b/target/hexagon/hex_arch_types.h new file mode 100644 index 0000000..57dc846 --- /dev/null +++ b/target/hexagon/hex_arch_types.h @@ -0,0 +1,38 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ARCH_TYPES_H +#define HEXAGON_ARCH_TYPES_H + +#include "qemu/osdep.h" +#include "qemu/int128.h" + +/* + * These types are used by the code imported from the Hexagon + * architecture library. + */ +typedef uint8_t size1u_t; +typedef int8_t size1s_t; +typedef uint16_t size2u_t; +typedef int16_t size2s_t; +typedef uint32_t size4u_t; +typedef int32_t size4s_t; +typedef uint64_t size8u_t; +typedef int64_t size8s_t; +typedef Int128 size16s_t; + +#endif From patchwork Thu Oct 29 23:58:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316586 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7561EC2D0A3 for ; Fri, 30 Oct 2020 00:01:38 +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 A815E2076B for ; Fri, 30 Oct 2020 00:01:37 +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="jhQ92kY+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A815E2076B 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35550 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHrM-0001ul-GW for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:01:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37200) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHox-0008Il-Rb for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:07 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:62907) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHos-0004LA-Fg for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015942; x=1635551942; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UhjV0r3e7nIeUbW225cudNMynRWdL7+RRLLzvw1IUBU=; b=jhQ92kY+jkJI9tIaSuoOwCPX/v9rYeZmR/hLemCaCDsmVa/5aX3930ep Vctekl4vuUcXWLicTT4Y2yzvEz4UkRPW+dhAm/kqSnrvXjsQuE+GvC3uo IGwEgEzBQs9Ser/0Ps5o/E+6PWCvp+Hj7VQ7H6JqTcKo+H7FdeeQr+HPe 0=; Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg03-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:53 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id AA464411A; Thu, 29 Oct 2020 18:58:53 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 13/33] Hexagon (target/hexagon) instruction/packet decode Date: Thu, 29 Oct 2020 18:58:30 -0500 Message-Id: <1604015931-23005-14-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Take the words from instruction memory and build a packet_t for TCG code generation The following operations are performed Convert the .new encoded offset to the register number of the producer Reorder the packet so .new producer is before consumer Apply constant extenders Separate subinsn's into two instructions Break compare-jumps into two instructions Create instructions for :endloop Signed-off-by: Taylor Simpson --- target/hexagon/decode.h | 32 +++ target/hexagon/decode.c | 581 ++++++++++++++++++++++++++++++++++++++++++++ target/hexagon/q6v_decode.c | 385 +++++++++++++++++++++++++++++ 3 files changed, 998 insertions(+) create mode 100644 target/hexagon/decode.h create mode 100644 target/hexagon/decode.c create mode 100644 target/hexagon/q6v_decode.c diff --git a/target/hexagon/decode.h b/target/hexagon/decode.h new file mode 100644 index 0000000..38f597c --- /dev/null +++ b/target/hexagon/decode.h @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_DECODE_H +#define HEXAGON_DECODE_H + +#include "cpu.h" +#include "opcodes.h" +#include "insn.h" + +extern void decode_init(void); + +extern void decode_send_insn_to(Packet *packet, int start, int newloc); + +extern int decode_packet(int max_words, const uint32_t *words, Packet *pkt, + bool disas_only); + +#endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c new file mode 100644 index 0000000..26c661c --- /dev/null +++ b/target/hexagon/decode.c @@ -0,0 +1,581 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "iclass.h" +#include "opcodes.h" +#include "genptr.h" +#include "decode.h" +#include "insn.h" +#include "printinsn.h" + +#define fZXTN(N, M, VAL) ((VAL) & ((1LL << (N)) - 1)) + +enum { + EXT_IDX_noext = 0, + EXT_IDX_noext_AFTER = 4, + EXT_IDX_mmvec = 4, + EXT_IDX_mmvec_AFTER = 8, + XX_LAST_EXT_IDX +}; + +/* + * Certain operand types represent a non-contiguous set of values. + * For example, the compound compare-and-jump instruction can only access + * registers R0-R7 and R16-23. + * This table represents the mapping from the encoding to the actual values. + */ + +#define DEF_REGMAP(NAME, ELEMENTS, ...) \ + static const unsigned int DECODE_REGISTER_##NAME[ELEMENTS] = \ + { __VA_ARGS__ }; + /* Name Num Table */ +DEF_REGMAP(R_16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23) +DEF_REGMAP(R__8, 8, 0, 2, 4, 6, 16, 18, 20, 22) + +#define DECODE_MAPPED_REG(REGNO, NAME) \ + insn->regno[REGNO] = DECODE_REGISTER_##NAME[insn->regno[REGNO]]; + +typedef struct { + const struct DectreeTable *table_link; + const struct DectreeTable *table_link_b; + Opcode opcode; + enum { + DECTREE_ENTRY_INVALID, + DECTREE_TABLE_LINK, + DECTREE_SUBINSNS, + DECTREE_EXTSPACE, + DECTREE_TERMINAL + } type; +} DectreeEntry; + +typedef struct DectreeTable { + unsigned int (*lookup_function)(int startbit, int width, uint32_t opcode); + unsigned int size; + unsigned int startbit; + unsigned int width; + const DectreeEntry table[]; +} DectreeTable; + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ + static const DectreeTable dectree_table_##TAG; +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#include "dectree_generated.h" + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +#define DECODE_SEPARATOR_BITS(START, WIDTH) NULL, START, WIDTH +#define DECODE_NEW_TABLE_HELPER(TAG, SIZE, FN, START, WIDTH) \ + static const DectreeTable dectree_table_##TAG = { \ + .size = SIZE, \ + .lookup_function = FN, \ + .startbit = START, \ + .width = WIDTH, \ + .table = { +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ + DECODE_NEW_TABLE_HELPER(TAG, SIZE, WHATNOT) + +#define TABLE_LINK(TABLE) \ + { .type = DECTREE_TABLE_LINK, .table_link = &dectree_table_##TABLE }, +#define TERMINAL(TAG, ENC) \ + { .type = DECTREE_TERMINAL, .opcode = TAG }, +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) \ + { \ + .type = DECTREE_SUBINSNS, \ + .table_link = &dectree_table_DECODE_SUBINSN_##CLASSA, \ + .table_link_b = &dectree_table_DECODE_SUBINSN_##CLASSB \ + }, +#define EXTSPACE(TAG, ENC) { .type = DECTREE_EXTSPACE }, +#define INVALID() { .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE }, + +#define DECODE_END_TABLE(...) } }; + +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#include "dectree_generated.h" + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_NEW_TABLE_HELPER +#undef DECODE_SEPARATOR_BITS + +static const DectreeTable dectree_table_DECODE_EXT_EXT_noext = { + .size = 1, .lookup_function = NULL, .startbit = 0, .width = 0, + .table = { + { .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE }, + } +}; + +static const DectreeTable *ext_trees[XX_LAST_EXT_IDX]; + +static void decode_ext_init(void) +{ + int i; + for (i = EXT_IDX_noext; i < EXT_IDX_noext_AFTER; i++) { + ext_trees[i] = &dectree_table_DECODE_EXT_EXT_noext; + } +} + +typedef struct { + uint32_t mask; + uint32_t match; +} DecodeITableEntry; + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#define DECODE_MATCH_INFO_NORMAL(TAG, MASK, MATCH) \ + [TAG] = { \ + .mask = MASK, \ + .match = MATCH, \ + }, + +#define DECODE_MATCH_INFO_NULL(TAG, MASK, MATCH) \ + [TAG] = { .match = ~0 }, + +#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ + +static const DecodeITableEntry decode_itable[XX_LAST_OPCODE] = { +#include "dectree_generated.h" +}; + +#undef DECODE_MATCH_INFO +#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NULL(__VA_ARGS__) + +#undef DECODE_LEGACY_MATCH_INFO +#define DECODE_LEGACY_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) + +static const DecodeITableEntry decode_legacy_itable[XX_LAST_OPCODE] = { +#include "dectree_generated.h" +}; + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +void decode_init(void) +{ + decode_ext_init(); +} + +void decode_send_insn_to(Packet *packet, int start, int newloc) +{ + Insn tmpinsn; + int direction; + int i; + if (start == newloc) { + return; + } + if (start < newloc) { + /* Move towards end */ + direction = 1; + } else { + /* move towards beginning */ + direction = -1; + } + for (i = start; i != newloc; i += direction) { + tmpinsn = packet->insn[i]; + packet->insn[i] = packet->insn[i + direction]; + packet->insn[i + direction] = tmpinsn; + } +} + +/* Fill newvalue registers with the correct regno */ +static void +decode_fill_newvalue_regno(Packet *packet) +{ + int i, use_regidx, def_idx; + uint16_t def_opcode, use_opcode; + char *dststr; + + for (i = 1; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) && + !GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) { + use_opcode = packet->insn[i].opcode; + + /* It's a store, so we're adjusting the Nt field */ + if (GET_ATTRIB(use_opcode, A_STORE)) { + use_regidx = strchr(opcode_reginfo[use_opcode], 't') - + opcode_reginfo[use_opcode]; + } else { /* It's a Jump, so we're adjusting the Ns field */ + use_regidx = strchr(opcode_reginfo[use_opcode], 's') - + opcode_reginfo[use_opcode]; + } + + /* + * What's encoded at the N-field is the offset to who's producing + * the value. Shift off the LSB which indicates odd/even register. + */ + def_idx = i - ((packet->insn[i].regno[use_regidx]) >> 1); + + /* + * Check for a badly encoded N-field which points to an instruction + * out-of-range + */ + g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1)))); + + /* + * packet->insn[def_idx] is the producer + * Figure out which type of destination it produces + * and the corresponding index in the reginfo + */ + def_opcode = packet->insn[def_idx].opcode; + dststr = strstr(opcode_wregs[def_opcode], "Rd"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'd'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Rx"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'x'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Re"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'e'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Ry"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'y'); + } else { + g_assert_not_reached(); + } + } + } + } + g_assert(dststr != NULL); + + /* Now patch up the consumer with the register number */ + int dst_idx = dststr - opcode_reginfo[def_opcode]; + packet->insn[i].regno[use_regidx] = + packet->insn[def_idx].regno[dst_idx]; + /* + * We need to remember who produces this value to later + * check if it was dynamically cancelled + */ + packet->insn[i].new_value_producer_slot = + packet->insn[def_idx].slot; + } + } +} + +/* Split CJ into a compare and a jump */ +static void decode_split_cmpjump(Packet *pkt) +{ + int last, i; + int numinsns = pkt->num_insns; + + /* + * First, split all compare-jumps. + * The compare is sent to the end as a new instruction. + * Do it this way so we don't reorder dual jumps. Those need to stay in + * original order. + */ + for (i = 0; i < numinsns; i++) { + /* It's a cmp-jump */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_NEWCMPJUMP)) { + last = pkt->num_insns; + pkt->insn[last] = pkt->insn[i]; /* copy the instruction */ + pkt->insn[last].part1 = 1; /* last instruction does the CMP */ + pkt->insn[i].part1 = 0; /* existing instruction does the JUMP */ + pkt->num_insns++; + } + } + + /* Now re-shuffle all the compares back to the beginning */ + for (i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].part1) { + decode_send_insn_to(pkt, i, 0); + } + } +} + +static inline int decode_opcode_can_jump(int opcode) +{ + if ((GET_ATTRIB(opcode, A_JUMP)) || + (GET_ATTRIB(opcode, A_CALL)) || + (opcode == J2_trap0)) { + /* Exception to A_JUMP attribute */ + if (opcode == J4_hintjumpr) { + return 0; + } + return 1; + } + + return 0; +} + +static inline int decode_opcode_ends_loop(int opcode) +{ + return GET_ATTRIB(opcode, A_HWLOOP0_END) || + GET_ATTRIB(opcode, A_HWLOOP1_END); +} + +/* Set the is_* fields in each instruction */ +static void decode_set_insn_attr_fields(Packet *pkt) +{ + int i; + int numinsns = pkt->num_insns; + uint16_t opcode; + + pkt->pkt_has_cof = 0; + pkt->pkt_has_endloop = 0; + pkt->pkt_has_dczeroa = 0; + + for (i = 0; i < numinsns; i++) { + opcode = pkt->insn[i].opcode; + if (pkt->insn[i].part1) { + continue; /* Skip compare of cmp-jumps */ + } + + if (GET_ATTRIB(opcode, A_DCZEROA)) { + pkt->pkt_has_dczeroa = 1; + } + + if (GET_ATTRIB(opcode, A_STORE)) { + if (pkt->insn[i].slot == 0) { + pkt->pkt_has_store_s0 = 1; + } else { + pkt->pkt_has_store_s1 = 1; + } + } + + pkt->pkt_has_cof |= decode_opcode_can_jump(opcode); + + pkt->insn[i].is_endloop = decode_opcode_ends_loop(opcode); + + pkt->pkt_has_endloop |= pkt->insn[i].is_endloop; + + pkt->pkt_has_cof |= pkt->pkt_has_endloop; + } +} + +/* + * Shuffle for execution + * Move stores to end (in same order as encoding) + * Move compares to beginning (for use by .new insns) + */ +static void decode_shuffle_for_execution(Packet *packet) +{ + int changed = 0; + int i; + int flag; /* flag means we've seen a non-memory instruction */ + int n_mems; + int last_insn = packet->num_insns - 1; + + /* + * Skip end loops, somehow an end loop is getting in and messing + * up the order + */ + if (decode_opcode_ends_loop(packet->insn[last_insn].opcode)) { + last_insn--; + } + + do { + changed = 0; + /* + * Stores go last, must not reorder. + * Cannot shuffle stores past loads, either. + * Iterate backwards. If we see a non-memory instruction, + * then a store, shuffle the store to the front. Don't shuffle + * stores wrt each other or a load. + */ + for (flag = n_mems = 0, i = last_insn; i >= 0; i--) { + int opcode = packet->insn[i].opcode; + + if (flag && GET_ATTRIB(opcode, A_STORE)) { + decode_send_insn_to(packet, i, last_insn - n_mems); + n_mems++; + changed = 1; + } else if (GET_ATTRIB(opcode, A_STORE)) { + n_mems++; + } else if (GET_ATTRIB(opcode, A_LOAD)) { + /* + * Don't set flag, since we don't want to shuffle a + * store past a load + */ + n_mems++; + } else if (GET_ATTRIB(opcode, A_DOTNEWVALUE)) { + /* + * Don't set flag, since we don't want to shuffle past + * a .new value + */ + } else { + flag = 1; + } + } + + if (changed) { + continue; + } + /* Compares go first, may be reordered wrt each other */ + for (flag = 0, i = 0; i < last_insn + 1; i++) { + int opcode = packet->insn[i].opcode; + + if ((strstr(opcode_wregs[opcode], "Pd4") || + strstr(opcode_wregs[opcode], "Pe4")) && + GET_ATTRIB(opcode, A_STORE) == 0) { + /* This should be a compare (not a store conditional) */ + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else if (GET_ATTRIB(opcode, A_IMPLICIT_WRITES_P3) && + !decode_opcode_ends_loop(packet->insn[i].opcode)) { + /* + * spNloop instruction + * Don't reorder endloops; they are not valid for .new uses, + * and we want to match HW + */ + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else if (GET_ATTRIB(opcode, A_IMPLICIT_WRITES_P0) && + !GET_ATTRIB(opcode, A_NEWCMPJUMP)) { + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else { + flag = 1; + } + } + if (changed) { + continue; + } + } while (changed); + + /* + * If we have a .new register compare/branch, move that to the very + * very end, past stores + */ + for (i = 0; i < last_insn; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE)) { + decode_send_insn_to(packet, i, last_insn); + break; + } + } +} + +static void +apply_extender(Packet *pkt, int i, uint32_t extender) +{ + int immed_num; + uint32_t base_immed; + + immed_num = opcode_which_immediate_is_extended(pkt->insn[i].opcode); + base_immed = pkt->insn[i].immed[immed_num]; + + pkt->insn[i].immed[immed_num] = extender | fZXTN(6, 32, base_immed); +} + +static void decode_apply_extenders(Packet *packet) +{ + int i; + for (i = 0; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_IT_EXTENDER)) { + packet->insn[i + 1].extension_valid = 1; + apply_extender(packet, i + 1, packet->insn[i].immed[0]); + } + } +} + +static void decode_remove_extenders(Packet *packet) +{ + int i, j; + for (i = 0; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_IT_EXTENDER)) { + /* Remove this one by moving the remaining instructions down */ + for (j = i; + (j < packet->num_insns - 1) && (j < INSTRUCTIONS_MAX - 1); + j++) { + packet->insn[j] = packet->insn[j + 1]; + } + packet->num_insns--; + } + } +} + +static SlotMask get_valid_slots(const Packet *pkt, unsigned int slot) +{ + return find_iclass_slots(pkt->insn[slot].opcode, + pkt->insn[slot].iclass); +} + +#include "q6v_decode.c" + +/* Used for "-d in_asm" logging */ +int disassemble_hexagon(uint32_t *words, int nwords, bfd_vma pc, + char *buf, int bufsize) +{ + Packet pkt; + + if (decode_packet(nwords, words, &pkt, true) > 0) { + snprint_a_pkt_disas(buf, bufsize, &pkt, words, pc); + return pkt.encod_pkt_size_in_bytes; + } else { + snprintf(buf, bufsize, ""); + return 0; + } +} diff --git a/target/hexagon/q6v_decode.c b/target/hexagon/q6v_decode.c new file mode 100644 index 0000000..106b836 --- /dev/null +++ b/target/hexagon/q6v_decode.c @@ -0,0 +1,385 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ + +#define DECODE_REG(REGNO, WIDTH, STARTBIT) \ + insn->regno[REGNO] = ((encoding >> STARTBIT) & ((1 << WIDTH) - 1)); + +#define DECODE_IMPL_REG(REGNO, VAL) \ + insn->regno[REGNO] = VAL; + +#define DECODE_IMM(IMMNO, WIDTH, STARTBIT, VALSTART) \ + insn->immed[IMMNO] |= (((encoding >> STARTBIT) & ((1 << WIDTH) - 1))) << \ + (VALSTART); + +#define DECODE_IMM_SXT(IMMNO, WIDTH) \ + insn->immed[IMMNO] = ((((int32_t)insn->immed[IMMNO]) << (32 - WIDTH)) >> \ + (32 - WIDTH)); + +#define DECODE_IMM_NEG(IMMNO, WIDTH) \ + insn->immed[IMMNO] = -insn->immed[IMMNO]; + +#define DECODE_IMM_SHIFT(IMMNO, SHAMT) \ + if ((!insn->extension_valid) || \ + (insn->which_extended != IMMNO)) { \ + insn->immed[IMMNO] <<= SHAMT; \ + } + +#define DECODE_OPINFO(TAG, BEH) \ + case TAG: \ + { BEH } \ + break; \ + +/* + * Fill in the operands of the instruction + * dectree_generated.h had a DECODE_OPINFO entry for each opcode + * For example, + * DECODE_OPINFO(A2_addi, + * DECODE_REG(0,5,0) + * DECODE_REG(1,5,16) + * DECODE_IMM(0,7,21,9) + * DECODE_IMM(0,9,5,0) + * DECODE_IMM_SXT(0,16) + * with the macros defined above, we'll fill in a switch statement + * where each case is an opcode tag. + */ +static void +decode_op(Insn *insn, Opcode tag, uint32_t encoding) +{ + insn->immed[0] = 0; + insn->immed[1] = 0; + insn->opcode = tag; + if (insn->extension_valid) { + insn->which_extended = opcode_which_immediate_is_extended(tag); + } + + switch (tag) { +#include "dectree_generated.h" + default: + break; + } + + insn->generate = opcode_genptr[tag]; + + insn->iclass = iclass_bits(encoding); +} + +#undef DECODE_REG +#undef DECODE_IMPL_REG +#undef DECODE_IMM +#undef DECODE_IMM_SHIFT +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +static unsigned int +decode_subinsn_tablewalk(Insn *insn, const DectreeTable *table, + uint32_t encoding) +{ + unsigned int i; + Opcode opc; + if (table->lookup_function) { + i = table->lookup_function(table->startbit, table->width, encoding); + } else { + i = extract32(encoding, table->startbit, table->width); + } + if (table->table[i].type == DECTREE_TABLE_LINK) { + return decode_subinsn_tablewalk(insn, table->table[i].table_link, + encoding); + } else if (table->table[i].type == DECTREE_TERMINAL) { + opc = table->table[i].opcode; + if ((encoding & decode_itable[opc].mask) != decode_itable[opc].match) { + return 0; + } + decode_op(insn, opc, encoding); + return 1; + } else { + return 0; + } +} + +static unsigned int get_insn_a(uint32_t encoding) +{ + return extract32(encoding, 0, 13); +} + +static unsigned int get_insn_b(uint32_t encoding) +{ + return extract32(encoding, 16, 13); +} + +static unsigned int +decode_insns_tablewalk(Insn *insn, const DectreeTable *table, + uint32_t encoding) +{ + unsigned int i; + unsigned int a, b; + Opcode opc; + if (table->lookup_function) { + i = table->lookup_function(table->startbit, table->width, encoding); + } else { + i = extract32(encoding, table->startbit, table->width); + } + if (table->table[i].type == DECTREE_TABLE_LINK) { + return decode_insns_tablewalk(insn, table->table[i].table_link, + encoding); + } else if (table->table[i].type == DECTREE_SUBINSNS) { + a = get_insn_a(encoding); + b = get_insn_b(encoding); + b = decode_subinsn_tablewalk(insn, table->table[i].table_link_b, b); + a = decode_subinsn_tablewalk(insn + 1, table->table[i].table_link, a); + if ((a == 0) || (b == 0)) { + return 0; + } + return 2; + } else if (table->table[i].type == DECTREE_TERMINAL) { + opc = table->table[i].opcode; + if ((encoding & decode_itable[opc].mask) != decode_itable[opc].match) { + if ((encoding & decode_legacy_itable[opc].mask) != + decode_legacy_itable[opc].match) { + return 0; + } + } + decode_op(insn, opc, encoding); + return 1; + } else { + return 0; + } +} + +static unsigned int +decode_insns(Insn *insn, uint32_t encoding) +{ + const DectreeTable *table; + if (parse_bits(encoding) != 0) { + /* Start with PP table - 32 bit instructions */ + table = &dectree_table_DECODE_ROOT_32; + } else { + /* start with EE table - duplex instructions */ + table = &dectree_table_DECODE_ROOT_EE; + } + return decode_insns_tablewalk(insn, table, encoding); +} + +static void decode_add_endloop_insn(Insn *insn, int loopnum) +{ + if (loopnum == 10) { + insn->opcode = J2_endloop01; + insn->generate = opcode_genptr[J2_endloop01]; + } else if (loopnum == 1) { + insn->opcode = J2_endloop1; + insn->generate = opcode_genptr[J2_endloop1]; + } else if (loopnum == 0) { + insn->opcode = J2_endloop0; + insn->generate = opcode_genptr[J2_endloop0]; + } else { + g_assert_not_reached(); + } +} + +static inline int decode_parsebits_is_loopend(uint32_t encoding32) +{ + uint32_t bits = parse_bits(encoding32); + return bits == 0x2; +} + +static void +decode_set_slot_number(Packet *pkt) +{ + int slot; + int i; + int hit_mem_insn = 0; + int hit_duplex = 0; + + /* + * The slots are encoded in reverse order + * For each instruction, count down until you find a suitable slot + */ + for (i = 0, slot = 3; i < pkt->num_insns; i++) { + SlotMask valid_slots = get_valid_slots(pkt, i); + + while (!(valid_slots & (1 << slot))) { + slot--; + } + pkt->insn[i].slot = slot; + if (slot) { + /* I've assigned the slot, now decrement it for the next insn */ + slot--; + } + } + + /* Fix the exceptions - mem insns to slot 0,1 */ + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* First memory instruction always goes to slot 0 */ + if ((GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE) || + GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE_PACKET_RULES)) && + !hit_mem_insn) { + hit_mem_insn = 1; + pkt->insn[i].slot = 0; + continue; + } + + /* Next memory instruction always goes to slot 1 */ + if ((GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE) || + GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE_PACKET_RULES)) && + hit_mem_insn) { + pkt->insn[i].slot = 1; + } + } + + /* Fix the exceptions - duplex always slot 0,1 */ + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* First subinsn always goes to slot 0 */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN) && !hit_duplex) { + hit_duplex = 1; + pkt->insn[i].slot = 0; + continue; + } + + /* Next subinsn always goes to slot 1 */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN) && hit_duplex) { + pkt->insn[i].slot = 1; + } + } + + /* Fix the exceptions - slot 1 is never empty, always aligns to slot 0 */ + int slot0_found = 0; + int slot1_found = 0; + int slot1_iidx = 0; + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* Is slot0 used? */ + if (pkt->insn[i].slot == 0) { + int is_endloop = (pkt->insn[i].opcode == J2_endloop01); + is_endloop |= (pkt->insn[i].opcode == J2_endloop0); + is_endloop |= (pkt->insn[i].opcode == J2_endloop1); + + /* + * Make sure it's not endloop since, we're overloading + * slot0 for endloop + */ + if (!is_endloop) { + slot0_found = 1; + } + } + /* Is slot1 used? */ + if (pkt->insn[i].slot == 1) { + slot1_found = 1; + slot1_iidx = i; + } + } + /* Is slot0 empty and slot1 used? */ + if ((slot0_found == 0) && (slot1_found == 1)) { + /* Then push it to slot0 */ + pkt->insn[slot1_iidx].slot = 0; + } +} + +/* + * decode_packet + * Decodes packet with given words + * Returns 0 on insufficient words, + * or number of words used on success + */ + +int decode_packet(int max_words, const uint32_t *words, Packet *pkt, + bool disas_only) +{ + int num_insns = 0; + int words_read = 0; + int end_of_packet = 0; + int new_insns = 0; + uint32_t encoding32; + + /* Initialize */ + memset(pkt, 0, sizeof(*pkt)); + /* Try to build packet */ + while (!end_of_packet && (words_read < max_words)) { + encoding32 = words[words_read]; + end_of_packet = is_packet_end(encoding32); + new_insns = decode_insns(&pkt->insn[num_insns], encoding32); + /* + * If we saw an extender, mark next word extended so immediate + * decode works + */ + if (pkt->insn[num_insns].opcode == A4_ext) { + pkt->insn[num_insns + 1].extension_valid = 1; + } + num_insns += new_insns; + words_read++; + } + + pkt->num_insns = num_insns; + if (!end_of_packet) { + /* Ran out of words! */ + return 0; + } + pkt->encod_pkt_size_in_bytes = words_read * 4; + + /* + * Check for :endloop in the parse bits + * Section 10.6 of the Programmer's Reference describes the encoding + * The end of hardware loop 0 can be encoded with 2 words + * The end of hardware loop 1 needs 3 words + */ + if ((words_read == 2) && (decode_parsebits_is_loopend(words[0]))) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 0); + } + if (words_read >= 3) { + uint32_t has_loop0, has_loop1; + has_loop0 = decode_parsebits_is_loopend(words[0]); + has_loop1 = decode_parsebits_is_loopend(words[1]); + if (has_loop0 && has_loop1) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 10); + } else if (has_loop1) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 1); + } else if (has_loop0) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 0); + } + } + + decode_apply_extenders(pkt); + if (!disas_only) { + decode_remove_extenders(pkt); + } + decode_set_slot_number(pkt); + decode_fill_newvalue_regno(pkt); + + if (!disas_only) { + decode_shuffle_for_execution(pkt); + decode_split_cmpjump(pkt); + decode_set_insn_attr_fields(pkt); + } + + return words_read; +} From patchwork Thu Oct 29 23:58:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316582 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8CCAC2D0A3 for ; Fri, 30 Oct 2020 00:07:15 +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 20D7520724 for ; Fri, 30 Oct 2020 00:07:15 +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="xBgd7g+D" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 20D7520724 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55242 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHwo-0001fE-3p for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:07:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37272) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHp4-00005P-1h for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:14 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:9898) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHow-0004Lk-Se for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015946; x=1635551946; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=udkgD1ImzEv5jIE9Ii9NJIQujrB9EbZZs4ZfMO38aSM=; b=xBgd7g+DTstpQF2C98bjKF0qHsyhrAM8AGND63CK7l2006HGj3wZ8nz/ gSxn8o9YV1dWPaQu/IzRfkIYIr7+aT17sQotivxQF+PyI7zoFCp6qORFu AgPJV3LXKKaiJpmCvvHprCfLVni0D/K9pjfuVv3ta+8kwBHM3pTZHyQ+B A=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id F15D3411B; Thu, 29 Oct 2020 18:58:53 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 16/33] Hexagon (target/hexagon/conv_emu.[ch]) utility functions Date: Thu, 29 Oct 2020 18:58:33 -0500 Message-Id: <1604015931-23005-17-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Taylor Simpson --- target/hexagon/conv_emu.h | 31 ++++++++ target/hexagon/conv_emu.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 target/hexagon/conv_emu.h create mode 100644 target/hexagon/conv_emu.c diff --git a/target/hexagon/conv_emu.h b/target/hexagon/conv_emu.h new file mode 100644 index 0000000..d05e7cc --- /dev/null +++ b/target/hexagon/conv_emu.h @@ -0,0 +1,31 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_CONV_EMU_H +#define HEXAGON_CONV_EMU_H + +extern uint64_t conv_sf_to_8u(float32 in, float_status *fp_status); +extern uint32_t conv_sf_to_4u(float32 in, float_status *fp_status); +extern int64_t conv_sf_to_8s(float32 in, float_status *fp_status); +extern int32_t conv_sf_to_4s(float32 in, float_status *fp_status); + +extern uint64_t conv_df_to_8u(float64 in, float_status *fp_status); +extern uint32_t conv_df_to_4u(float64 in, float_status *fp_status); +extern int64_t conv_df_to_8s(float64 in, float_status *fp_status); +extern int32_t conv_df_to_4s(float64 in, float_status *fp_status); + +#endif diff --git a/target/hexagon/conv_emu.c b/target/hexagon/conv_emu.c new file mode 100644 index 0000000..b09ea63 --- /dev/null +++ b/target/hexagon/conv_emu.c @@ -0,0 +1,177 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "fpu/softfloat.h" +#include "macros.h" +#include "conv_emu.h" + +#define LL_MAX_POS 0x7fffffffffffffffULL +#define MAX_POS 0x7fffffffU + +static uint64_t conv_f64_to_8u_n(float64 in, int will_negate, + float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + if (float64_is_infinity(in)) { + float_raise(float_flag_invalid, fp_status); + if (float64_is_neg(in)) { + return 0ULL; + } else { + return ~0ULL; + } + } + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return ~0ULL; + } + if (float64_is_zero(in)) { + return 0; + } + if (sign) { + float_raise(float_flag_invalid, fp_status); + return 0; + } + if (float64_lt(in, float64_half, fp_status)) { + /* Near zero, captures large fracshifts, denorms, etc */ + float_raise(float_flag_inexact, fp_status); + switch (get_float_rounding_mode(fp_status)) { + case float_round_down: + if (will_negate) { + return 1; + } else { + return 0; + } + case float_round_up: + if (!will_negate) { + return 1; + } else { + return 0; + } + default: + return 0; /* nearest or towards zero */ + } + } + return float64_to_uint64(in, fp_status); +} + +static void clr_float_exception_flags(uint8_t flag, float_status *fp_status) +{ + uint8_t flags = fp_status->float_exception_flags; + flags &= ~flag; + set_float_exception_flags(flags, fp_status); +} + +static uint32_t conv_df_to_4u_n(float64 fp64, int will_negate, + float_status *fp_status) +{ + uint64_t tmp; + tmp = conv_f64_to_8u_n(fp64, will_negate, fp_status); + if (tmp > 0x00000000ffffffffULL) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + return ~0U; + } + return (uint32_t)tmp; +} + +uint64_t conv_df_to_8u(float64 in, float_status *fp_status) +{ + return conv_f64_to_8u_n(in, 0, fp_status); +} + +uint32_t conv_df_to_4u(float64 in, float_status *fp_status) +{ + return conv_df_to_4u_n(in, 0, fp_status); +} + +int64_t conv_df_to_8s(float64 in, float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + uint64_t tmp; + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return -1; + } + if (sign) { + float64 minus_fp64 = float64_abs(in); + tmp = conv_f64_to_8u_n(minus_fp64, 1, fp_status); + } else { + tmp = conv_f64_to_8u_n(in, 0, fp_status); + } + if (tmp > (LL_MAX_POS + sign)) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + tmp = (LL_MAX_POS + sign); + } + if (sign) { + return -tmp; + } else { + return tmp; + } +} + +int32_t conv_df_to_4s(float64 in, float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + uint64_t tmp; + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return -1; + } + if (sign) { + float64 minus_fp64 = float64_abs(in); + tmp = conv_f64_to_8u_n(minus_fp64, 1, fp_status); + } else { + tmp = conv_f64_to_8u_n(in, 0, fp_status); + } + if (tmp > (MAX_POS + sign)) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + tmp = (MAX_POS + sign); + } + if (sign) { + return -tmp; + } else { + return tmp; + } +} + +uint64_t conv_sf_to_8u(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_8u(fp64, fp_status); +} + +uint32_t conv_sf_to_4u(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_4u(fp64, fp_status); +} + +int64_t conv_sf_to_8s(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_8s(fp64, fp_status); +} + +int32_t conv_sf_to_4s(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_4s(fp64, fp_status); +} From patchwork Thu Oct 29 23:58:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316574 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9146C2D0A3 for ; Fri, 30 Oct 2020 00:24:55 +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 2471420709 for ; Fri, 30 Oct 2020 00:24:55 +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="ln9AKUCM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2471420709 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39872 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYIDu-0002Hw-3E for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:24:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37270) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHp2-0008Vv-Oh for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:12 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:62907) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHoy-0004LA-2f for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015948; x=1635551948; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2SiyIb0r/rPj3jamrnzMVVaC7bZ/Y8rLmp2o+/1c6RU=; b=ln9AKUCMWBaD9Pn6GyKwxdsK801Ub8jN1MqhqbYY5ULimfl+pyAaOgAO vTwcZowB9khcBNPX3+mEWRQX9Qn8myuU7XH3NlNegFSzTJd8VxjmO1yRI CgNYqKdgjvwWU8VClJkQcgVcSKVj3j+f884/x4NTXCV/EajKhH0kgu+tQ o=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 18F4E411C; Thu, 29 Oct 2020 18:58:54 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 17/33] Hexagon (target/hexagon/fma_emu.[ch]) utility functions Date: Thu, 29 Oct 2020 18:58:34 -0500 Message-Id: <1604015931-23005-18-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Taylor Simpson --- target/hexagon/fma_emu.h | 32 +++ target/hexagon/fma_emu.c | 706 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 738 insertions(+) create mode 100644 target/hexagon/fma_emu.h create mode 100644 target/hexagon/fma_emu.c diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h new file mode 100644 index 0000000..4402d63 --- /dev/null +++ b/target/hexagon/fma_emu.h @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_FMA_EMU_H +#define HEXAGON_FMA_EMU_H + +extern int32_t float64_getexp(float64 f64); +extern int32_t float32_getexp(float32 f32); +extern float32 infinite_float32(uint8_t sign); +extern float32 internal_fmafx(float32 a, float32 b, float32 c, + int scale, float_status *fp_status); +extern float32 internal_mpyf(float32 a, float32 b, + float_status *fp_status); +extern float64 internal_mpyhh(float64 a, float64 b, + unsigned long long int accumulated, + float_status *fp_status); + +#endif diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c new file mode 100644 index 0000000..2318a6e --- /dev/null +++ b/target/hexagon/fma_emu.c @@ -0,0 +1,706 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/int128.h" +#include "fpu/softfloat.h" +#include "macros.h" +#include "conv_emu.h" +#include "fma_emu.h" + +#define DF_INF_EXP 0x7ff +#define DF_BIAS 1023 +#define DF_MANTBITS 52 +#define DF_NAN 0xffffffffffffffffULL +#define DF_INF 0x7ff0000000000000ULL +#define DF_MINUS_INF 0xfff0000000000000ULL +#define DF_MAXF 0x7fefffffffffffffULL +#define DF_MINUS_MAXF 0xffefffffffffffffULL + +#define SF_INF_EXP 0xff +#define SF_BIAS 127 +#define SF_MANTBITS 23 +#define SF_INF 0x7f800000 +#define SF_MINUS_INF 0xff800000 +#define SF_MAXF 0x7f7fffff +#define SF_MINUS_MAXF 0xff7fffff + +#define HF_INF_EXP 0x1f +#define HF_BIAS 15 + +#define WAY_BIG_EXP 4096 + +typedef union { + double f; + uint64_t i; + struct { + uint64_t mant:52; + uint64_t exp:11; + uint64_t sign:1; + }; +} Double; + +typedef union { + float f; + uint32_t i; + struct { + uint32_t mant:23; + uint32_t exp:8; + uint32_t sign:1; + }; +} Float; + +static inline uint64_t float64_getmant(float64 f64) +{ + Double a = { .i = f64 }; + if (float64_is_normal(f64)) { + return a.mant | 1ULL << 52; + } + if (float64_is_zero(f64)) { + return 0; + } + if (float64_is_denormal(f64)) { + return a.mant; + } + return ~0ULL; +} + +int32_t float64_getexp(float64 f64) +{ + Double a = { .i = f64 }; + if (float64_is_normal(f64)) { + return a.exp; + } + if (float64_is_denormal(f64)) { + return a.exp + 1; + } + return -1; +} + +static inline uint64_t float32_getmant(float32 f32) +{ + Float a = { .i = f32 }; + if (float32_is_normal(f32)) { + return a.mant | 1ULL << 23; + } + if (float32_is_zero(f32)) { + return 0; + } + if (float32_is_denormal(f32)) { + return a.mant; + } + return ~0ULL; +} + +int32_t float32_getexp(float32 f32) +{ + Float a = { .i = f32 }; + if (float32_is_normal(f32)) { + return a.exp; + } + if (float32_is_denormal(f32)) { + return a.exp + 1; + } + return -1; +} + +static inline uint32_t int128_getw0(Int128 x) +{ + return int128_getlo(x); +} + +static inline uint32_t int128_getw1(Int128 x) +{ + return int128_getlo(x) >> 32; +} + +static inline Int128 int128_mul_6464(uint64_t ai, uint64_t bi) +{ + Int128 a, b; + uint64_t pp0, pp1a, pp1b, pp1s, pp2; + + a = int128_make64(ai); + b = int128_make64(bi); + pp0 = (uint64_t)int128_getw0(a) * (uint64_t)int128_getw0(b); + pp1a = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw0(b); + pp1b = (uint64_t)int128_getw1(b) * (uint64_t)int128_getw0(a); + pp2 = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw1(b); + + pp1s = pp1a + pp1b; + if ((pp1s < pp1a) || (pp1s < pp1b)) { + pp2 += (1ULL << 32); + } + uint64_t ret_low = pp0 + (pp1s << 32); + if ((ret_low < pp0) || (ret_low < (pp1s << 32))) { + pp2 += 1; + } + + return int128_make128(ret_low, pp2 + (pp1s >> 32)); +} + +static inline Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow) +{ + Int128 ret = int128_sub(a, b); + if (borrow != 0) { + ret = int128_sub(ret, int128_one()); + } + return ret; +} + +typedef struct { + Int128 mant; + int32_t exp; + uint8_t sign; + uint8_t guard; + uint8_t round; + uint8_t sticky; +} Accum; + +static inline void accum_init(Accum *p) +{ + p->mant = int128_zero(); + p->exp = 0; + p->sign = 0; + p->guard = 0; + p->round = 0; + p->sticky = 0; +} + +static inline Accum accum_norm_left(Accum a) +{ + a.exp--; + a.mant = int128_lshift(a.mant, 1); + a.mant = int128_or(a.mant, int128_make64(a.guard)); + a.guard = a.round; + a.round = a.sticky; + return a; +} + +static inline Accum accum_norm_right(Accum a, int amt) +{ + if (amt > 130) { + a.sticky |= + a.round | a.guard | int128_nz(a.mant); + a.guard = a.round = 0; + a.mant = int128_zero(); + a.exp += amt; + return a; + + } + while (amt >= 64) { + a.sticky |= a.round | a.guard | (int128_getlo(a.mant) != 0); + a.guard = (int128_getlo(a.mant) >> 63) & 1; + a.round = (int128_getlo(a.mant) >> 62) & 1; + a.mant = int128_make64(int128_gethi(a.mant)); + a.exp += 64; + amt -= 64; + } + while (amt > 0) { + a.exp++; + a.sticky |= a.round; + a.round = a.guard; + a.guard = int128_getlo(a.mant) & 1; + a.mant = int128_rshift(a.mant, 1); + amt--; + } + return a; +} + +/* + * On the add/sub, we need to be able to shift out lots of bits, but need a + * sticky bit for what was shifted out, I think. + */ +static Accum accum_add(Accum a, Accum b); + +static inline Accum accum_sub(Accum a, Accum b, int negate) +{ + Accum ret; + accum_init(&ret); + int borrow; + + if (a.sign != b.sign) { + b.sign = !b.sign; + return accum_add(a, b); + } + if (b.exp > a.exp) { + /* small - big == - (big - small) */ + return accum_sub(b, a, !negate); + } + if ((b.exp == a.exp) && (int128_gt(b.mant, a.mant))) { + /* small - big == - (big - small) */ + return accum_sub(b, a, !negate); + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: shrink a exponent and grow mantissa */ + if (int128_gethi(a.mant) & (1ULL << 62)) { + /* Can't grow a any more */ + break; + } else { + a = accum_norm_left(a); + } + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: grow b exponent and shrink mantissa */ + /* Keep around shifted out bits... we might need those later */ + b = accum_norm_right(b, a.exp - b.exp); + } + + if ((int128_gt(b.mant, a.mant))) { + return accum_sub(b, a, !negate); + } + + /* OK, now things should be normalized! */ + ret.sign = a.sign; + ret.exp = a.exp; + assert(!int128_gt(b.mant, a.mant)); + borrow = (b.round << 2) | (b.guard << 1) | b.sticky; + ret.mant = int128_sub_borrow(a.mant, b.mant, (borrow != 0)); + borrow = 0 - borrow; + ret.guard = (borrow >> 2) & 1; + ret.round = (borrow >> 1) & 1; + ret.sticky = (borrow >> 0) & 1; + if (negate) { + ret.sign = !ret.sign; + } + return ret; +} + +static Accum accum_add(Accum a, Accum b) +{ + Accum ret; + accum_init(&ret); + if (a.sign != b.sign) { + b.sign = !b.sign; + return accum_sub(a, b, 0); + } + if (b.exp > a.exp) { + /* small + big == (big + small) */ + return accum_add(b, a); + } + if ((b.exp == a.exp) && int128_gt(b.mant, a.mant)) { + /* small + big == (big + small) */ + return accum_add(b, a); + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: shrink a exponent and grow mantissa */ + if (int128_gethi(a.mant) & (1ULL << 62)) { + /* Can't grow a any more */ + break; + } else { + a = accum_norm_left(a); + } + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: grow b exponent and shrink mantissa */ + /* Keep around shifted out bits... we might need those later */ + b = accum_norm_right(b, a.exp - b.exp); + } + + /* OK, now things should be normalized! */ + if (int128_gt(b.mant, a.mant)) { + return accum_add(b, a); + }; + ret.sign = a.sign; + ret.exp = a.exp; + assert(!int128_gt(b.mant, a.mant)); + ret.mant = int128_add(a.mant, b.mant); + ret.guard = b.guard; + ret.round = b.round; + ret.sticky = b.sticky; + return ret; +} + +/* Return an infinity with requested sign */ +static inline float64 infinite_float64(uint8_t sign) +{ + if (sign) { + return make_float64(DF_MINUS_INF); + } else { + return make_float64(DF_INF); + } +} + +/* Return a maximum finite value with requested sign */ +static inline float64 maxfinite_float64(uint8_t sign) +{ + if (sign) { + return make_float64(DF_MINUS_MAXF); + } else { + return make_float64(DF_MAXF); + } +} + +/* Return a zero value with requested sign */ +static inline float64 zero_float64(uint8_t sign) +{ + if (sign) { + return make_float64(0x8000000000000000); + } else { + return float64_zero; + } +} + +/* Return an infinity with the requested sign */ +float32 infinite_float32(uint8_t sign) +{ + if (sign) { + return make_float32(SF_MINUS_INF); + } else { + return make_float32(SF_INF); + } +} + +/* Return a maximum finite value with the requested sign */ +static inline float32 maxfinite_float32(uint8_t sign) +{ + if (sign) { + return make_float32(SF_MINUS_MAXF); + } else { + return make_float32(SF_MAXF); + } +} + +/* Return a zero value with requested sign */ +static inline float32 zero_float32(uint8_t sign) +{ + if (sign) { + return make_float32(0x80000000); + } else { + return float32_zero; + } +} + +#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \ +static inline SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \ +{ \ + if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \ + && ((a.guard | a.round | a.sticky) == 0)) { \ + /* result zero */ \ + switch (fp_status->float_rounding_mode) { \ + case float_round_down: \ + return zero_##SUFFIX(1); \ + default: \ + return zero_##SUFFIX(0); \ + } \ + } \ + /* Normalize right */ \ + /* We want MANTBITS bits of mantissa plus the leading one. */ \ + /* That means that we want MANTBITS+1 bits, or 0x000000000000FF_FFFF */ \ + /* So we need to normalize right while the high word is non-zero and \ + * while the low word is nonzero when masked with 0xffe0_0000_0000_0000 */ \ + while ((int128_gethi(a.mant) != 0) || \ + ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0)) { \ + a = accum_norm_right(a, 1); \ + } \ + /* \ + * OK, now normalize left \ + * We want to normalize left until we have a leading one in bit 24 \ + * Theoretically, we only need to shift a maximum of one to the left if we \ + * shifted out lots of bits from B, or if we had no shift / 1 shift sticky \ + * shoudl be 0 \ + */ \ + while ((int128_getlo(a.mant) & (1ULL << MANTBITS)) == 0) { \ + a = accum_norm_left(a); \ + } \ + /* \ + * OK, now we might need to denormalize because of potential underflow. \ + * We need to do this before rounding, and rounding might make us normal \ + * again \ + */ \ + while (a.exp <= 0) { \ + a = accum_norm_right(a, 1 - a.exp); \ + /* \ + * Do we have underflow? \ + * That's when we get an inexact answer because we ran out of bits \ + * in a denormal. \ + */ \ + if (a.guard || a.round || a.sticky) { \ + float_raise(float_flag_underflow, fp_status); \ + } \ + } \ + /* OK, we're relatively canonical... now we need to round */ \ + if (a.guard || a.round || a.sticky) { \ + float_raise(float_flag_inexact, fp_status); \ + switch (fp_status->float_rounding_mode) { \ + case float_round_to_zero: \ + /* Chop and we're done */ \ + break; \ + case float_round_up: \ + if (a.sign == 0) { \ + a.mant = int128_add(a.mant, int128_one()); \ + } \ + break; \ + case float_round_down: \ + if (a.sign != 0) { \ + a.mant = int128_add(a.mant, int128_one()); \ + } \ + break; \ + default: \ + if (a.round || a.sticky) { \ + /* round up if guard is 1, down if guard is zero */ \ + a.mant = int128_add(a.mant, int128_make64(a.guard)); \ + } else if (a.guard) { \ + /* exactly .5, round up if odd */ \ + a.mant = int128_add(a.mant, int128_and(a.mant, int128_one())); \ + } \ + break; \ + } \ + } \ + /* \ + * OK, now we might have carried all the way up. \ + * So we might need to shr once \ + * at least we know that the lsb should be zero if we rounded and \ + * got a carry out... \ + */ \ + if ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0) { \ + a = accum_norm_right(a, 1); \ + } \ + /* Overflow? */ \ + if (a.exp >= INF_EXP) { \ + /* Yep, inf result */ \ + float_raise(float_flag_overflow, fp_status); \ + float_raise(float_flag_inexact, fp_status); \ + switch (fp_status->float_rounding_mode) { \ + case float_round_to_zero: \ + return maxfinite_##SUFFIX(a.sign); \ + case float_round_up: \ + if (a.sign == 0) { \ + return infinite_##SUFFIX(a.sign); \ + } else { \ + return maxfinite_##SUFFIX(a.sign); \ + } \ + case float_round_down: \ + if (a.sign != 0) { \ + return infinite_##SUFFIX(a.sign); \ + } else { \ + return maxfinite_##SUFFIX(a.sign); \ + } \ + default: \ + return infinite_##SUFFIX(a.sign); \ + } \ + } \ + /* Underflow? */ \ + if (int128_getlo(a.mant) & (1ULL << MANTBITS)) { \ + /* Leading one means: No, we're normal. So, we should be done... */ \ + INTERNAL_TYPE ret; \ + ret.i = 0; \ + ret.sign = a.sign; \ + ret.exp = a.exp; \ + ret.mant = int128_getlo(a.mant); \ + return ret.i; \ + } \ + assert(a.exp == 1); \ + INTERNAL_TYPE ret; \ + ret.i = 0; \ + ret.sign = a.sign; \ + ret.exp = 0; \ + ret.mant = int128_getlo(a.mant); \ + return ret.i; \ +} + +GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double) +GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float) + +static bool isfinite(float64 x) +{ + return !float64_is_any_nan(x) && !float64_is_infinity(x); +} + +static bool is_inf_prod(float64 a, float64 b) +{ + return ((float64_is_infinity(a) && float64_is_infinity(b)) || + (float64_is_infinity(a) && isfinite(b) && (!float64_is_zero(b))) || + (float64_is_infinity(b) && isfinite(a) && (float64_is_zero(a)))); +} + +static inline float64 special_fma(float64 a, float64 b, float64 c, + float_status *fp_status) +{ + float64 ret = make_float64(0); + + /* + * If A multiplied by B is an exact infinity and C is also an infinity + * but with the opposite sign, FMA returns NaN and raises invalid. + */ + uint8_t a_sign = float64_is_neg(a); + uint8_t b_sign = float64_is_neg(b); + uint8_t c_sign = float64_is_neg(c); + if (is_inf_prod(a, b) && float64_is_infinity(c)) { + if ((a_sign ^ b_sign) != c_sign) { + ret = make_float64(DF_NAN); + float_raise(float_flag_invalid, fp_status); + return ret; + } + } + if ((float64_is_infinity(a) && float64_is_zero(b)) || + (float64_is_zero(a) && float64_is_infinity(b))) { + ret = make_float64(DF_NAN); + float_raise(float_flag_invalid, fp_status); + return ret; + } + /* + * If none of the above checks are true and C is a NaN, + * a NaN shall be returned + * If A or B are NaN, a NAN shall be returned. + */ + if (float64_is_any_nan(a) || + float64_is_any_nan(b) || + float64_is_any_nan(c)) { + if (float64_is_any_nan(a) && (fGETBIT(51, a) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + if (float64_is_any_nan(b) && (fGETBIT(51, b) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + if (float64_is_any_nan(c) && (fGETBIT(51, c) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + ret = make_float64(DF_NAN); + return ret; + } + /* + * We have checked for adding opposite-signed infinities. + * Other infinities return infinity with the correct sign + */ + if (float64_is_infinity(c)) { + ret = infinite_float64(c_sign); + return ret; + } + if (float64_is_infinity(a) || float64_is_infinity(b)) { + ret = infinite_float64(a_sign ^ b_sign); + return ret; + } + g_assert_not_reached(); +} + +static inline float32 special_fmaf(float32 a, float32 b, float32 c, + float_status *fp_status) +{ + float64 aa, bb, cc; + aa = float32_to_float64(a, fp_status); + bb = float32_to_float64(b, fp_status); + cc = float32_to_float64(c, fp_status); + return float64_to_float32(special_fma(aa, bb, cc, fp_status), fp_status); +} + +float32 internal_fmafx(float32 a, float32 b, float32 c, int scale, + float_status *fp_status) +{ + Accum prod; + Accum acc; + Accum result; + accum_init(&prod); + accum_init(&acc); + accum_init(&result); + + uint8_t a_sign = float32_is_neg(a); + uint8_t b_sign = float32_is_neg(b); + uint8_t c_sign = float32_is_neg(c); + if (float32_is_infinity(a) || + float32_is_infinity(b) || + float32_is_infinity(c)) { + return special_fmaf(a, b, c, fp_status); + } + if (float32_is_any_nan(a) || + float32_is_any_nan(b) || + float32_is_any_nan(c)) { + return special_fmaf(a, b, c, fp_status); + } + if ((scale == 0) && (float32_is_zero(a) || float32_is_zero(b))) { + float32 tmp = float32_mul(a, b, fp_status); + tmp = float32_add(tmp, c, fp_status); + return tmp; + } + + /* (a * 2**b) * (c * 2**d) == a*c * 2**(b+d) */ + prod.mant = int128_mul_6464(float32_getmant(a), float32_getmant(b)); + + /* + * Note: extracting the mantissa into an int is multiplying by + * 2**23, so adjust here + */ + prod.exp = float32_getexp(a) + float32_getexp(b) - SF_BIAS - 23; + prod.sign = a_sign ^ b_sign; + if (float32_is_zero(a) || float32_is_zero(b)) { + prod.exp = -2 * WAY_BIG_EXP; + } + if ((scale > 0) && float32_is_denormal(c)) { + acc.mant = int128_mul_6464(0, 0); + acc.exp = -WAY_BIG_EXP; + acc.sign = c_sign; + acc.sticky = 1; + result = accum_add(prod, acc); + } else if (!float32_is_zero(c)) { + acc.mant = int128_mul_6464(float32_getmant(c), 1); + acc.exp = float32_getexp(c); + acc.sign = c_sign; + result = accum_add(prod, acc); + } else { + result = prod; + } + result.exp += scale; + return accum_round_float32(result, fp_status); +} + +float32 internal_mpyf(float32 a, float32 b, float_status *fp_status) +{ + if (float32_is_zero(a) || float32_is_zero(b)) { + return float32_mul(a, b, fp_status); + } + return internal_fmafx(a, b, float32_zero, 0, fp_status); +} + +float64 internal_mpyhh(float64 a, float64 b, + unsigned long long int accumulated, + float_status *fp_status) +{ + Accum x; + unsigned long long int prod; + unsigned int sticky; + + sticky = accumulated & 1; + accumulated >>= 1; + accum_init(&x); + if (float64_is_zero(a) || + float64_is_any_nan(a) || + float64_is_infinity(a)) { + return float64_mul(a, b, fp_status); + } + if (float64_is_zero(b) || + float64_is_any_nan(b) || + float64_is_infinity(b)) { + return float64_mul(a, b, fp_status); + } + x.mant = int128_mul_6464(accumulated, 1); + x.sticky = sticky; + prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b)); + x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL)); + x.exp = float64_getexp(a) + float64_getexp(b) - DF_BIAS - 20; + if (!float64_is_normal(a) || !float64_is_normal(b)) { + /* crush to inexact zero */ + x.sticky = 1; + x.exp = -4096; + } + uint8_t a_sign = float64_is_neg(a); + uint8_t b_sign = float64_is_neg(b); + x.sign = a_sign ^ b_sign; + return accum_round_float64(x, fp_status); +} From patchwork Thu Oct 29 23:58:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316572 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14A13C55179 for ; Fri, 30 Oct 2020 00:28:29 +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 76ABC2076D for ; Fri, 30 Oct 2020 00:28:28 +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="AZ1f4Jxt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 76ABC2076D 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYIHL-0005pB-Av for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:28:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37298) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHpE-0000O0-QU for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:24 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:54880) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHpC-0004Kz-AZ for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015962; x=1635551962; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ea16rMLO9ENk2mX5wAHnY6ZStYfbopsALMRyKJlSI+A=; b=AZ1f4Jxtr8y5DOfogxCkR9Kl1Ym/a9XXs3aoV6AsMWTU5dAdQ9k/AAtZ 984FQzJeHQ5gQTQ8V+cFiMX+etiA+vAXzcepdENCWJDvTQSPkxk/ecyj8 ZK/Bea260twHSxa+qB7apkA1D8dbzoEAKkL7LeXG7rSjxgixuSr9h88Es I=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:54 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id B1F2E4115; Thu, 29 Oct 2020 18:58:54 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 19/33] Hexagon (target/hexagon) generator phase 1 - C preprocessor for semantics Date: Thu, 29 Oct 2020 18:58:36 -0500 Message-Id: <1604015931-23005-20-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Run the C preprocessor across the instruction definition files and macro definition file to expand macros and prepare the semantics_generated.pyinc file. The resulting file contains one entry with the semantics for each instruction and one line with the instruction attributes associated with each macro. Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé . + */ + +/* + * This program generates the semantics file that is processed by + * the do_qemu.py script. We use the C preporcessor to manipulate the + * files imported from the Hexagon architecture library. + */ + +#include +#define STRINGIZE(X) #X + +int main(int argc, char *argv[]) +{ + FILE *outfile; + + if (argc != 2) { + fprintf(stderr, "Usage: gen_semantics ouptputfile\n"); + return 1; + } + outfile = fopen(argv[1], "w"); + if (outfile == NULL) { + fprintf(stderr, "Cannot open %s for writing\n", argv[1]); + return 1; + } + +/* + * Process the instruction definitions + * Scalar core instructions have the following form + * Q6INSN(A2_add,"Rd32=add(Rs32,Rt32)",ATTRIBS(), + * "Add 32-bit registers", + * { RdV=RsV+RtV;}) + */ +#define Q6INSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + do { \ + fprintf(outfile, "SEMANTICS( \\\n" \ + " \"%s\", \\\n" \ + " %s, \\\n" \ + " \"\"\"%s\"\"\" \\\n" \ + ")\n", \ + #TAG, STRINGIZE(BEH), STRINGIZE(SEM)); \ + fprintf(outfile, "ATTRIBUTES( \\\n" \ + " \"%s\", \\\n" \ + " \"%s\" \\\n" \ + ")\n", \ + #TAG, STRINGIZE(ATTRIBS)); \ + } while (0); +#include "imported/allidefs.def" +#undef Q6INSN + +/* + * Process the macro definitions + * Macros definitions have the following form + * DEF_MACRO( + * fLSBNEW0, + * predlog_read(thread,0), + * () + * ) + * The important part here is the attributes. Whenever an instruction + * invokes a macro, we add the macro's attributes to the instruction. + */ +#define DEF_MACRO(MNAME, BEH, ATTRS) \ + fprintf(outfile, "MACROATTRIB( \\\n" \ + " \"%s\", \\\n" \ + " \"\"\"%s\"\"\", \\\n" \ + " \"%s\" \\\n" \ + ")\n", \ + #MNAME, STRINGIZE(BEH), STRINGIZE(ATTRS)); +#include "imported/macros.def" +#undef DEF_MACRO + + fclose(outfile); + return 0; +} From patchwork Thu Oct 29 23:58:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316575 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0E77C2D0A3 for ; Fri, 30 Oct 2020 00:23:46 +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 108DE20709 for ; Fri, 30 Oct 2020 00:23:45 +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="PH5YgPh5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 108DE20709 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:36294 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYICm-0000rZ-WC for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:23:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37318) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHpG-0000SH-CV for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:26 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:62907) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHpD-0004LA-HU for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015963; x=1635551963; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JY9APKqwwFW6QQIVwUlm2KqDq6O0G/1RptPUjIoD7HY=; b=PH5YgPh55qxeuurlDyitWd5lE8klcNw/JtpZghzvBas8FXazLKKNQo9R ccnf2mzsLJP8RONszKyLUydxd6WZgM2h0XUmC3dyfm3mU3zooT+HkWJRN xeoWfSkelgxT2F9355+zx5jN3r1k9F4RuO8jRRcBfmyldhE861Uysidum g=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 113AF411A; Thu, 29 Oct 2020 18:58:55 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 21/33] Hexagon (target/hexagon) generator phase 3 - C preprocessor for decode tree Date: Thu, 29 Oct 2020 18:58:38 -0500 Message-Id: <1604015931-23005-22-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Run the C preprocessor across the instruction definition and encoding files to expand macros and prepare the iset.py file. The resulting fill contains python data structures used to build the decode tree. Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé . + */ + +/* + * This program generates the encodings file that is processed by + * the dectree.py script to produce the decoding tree. We use the C + * preprocessor to manipulate the files imported from the Hexagon + * architecture library. + */ +#include "qemu/osdep.h" +#include "opcodes.h" + +#define STRINGIZE(X) #X + +const char * const opcode_names[] = { +#define OPCODE(IID) STRINGIZE(IID) +#include "opcodes_def_generated.h" + NULL +#undef OPCODE +}; + +/* + * Process the instruction definitions + * Scalar core instructions have the following form + * Q6INSN(A2_add,"Rd32=add(Rs32,Rt32)",ATTRIBS(), + * "Add 32-bit registers", + * { RdV=RsV+RtV;}) + */ +const char * const opcode_syntax[XX_LAST_OPCODE] = { +#define Q6INSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + [TAG] = BEH, +#define EXTINSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + [TAG] = BEH, +#include "imported/allidefs.def" +#undef Q6INSN +#undef EXTINSN +}; + +const char * const opcode_rregs[] = { +#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#include "op_regs_generated.h" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const char * const opcode_wregs[] = { +#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#include "op_regs_generated.h" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const OpcodeEncoding opcode_encodings[] = { +#define DEF_ENC32(TAG, ENCSTR) \ + [TAG] = { .encoding = ENCSTR }, +#define DEF_ENC_SUBINSN(TAG, CLASS, ENCSTR) \ + [TAG] = { .encoding = ENCSTR, .enc_class = CLASS }, +#define DEF_EXT_ENC(TAG, CLASS, ENCSTR) \ + [TAG] = { .encoding = ENCSTR, .enc_class = CLASS }, +#include "imported/encode.def" +#undef DEF_ENC32 +#undef DEF_ENC_SUBINSN +#undef DEF_EXT_ENC +}; + +static const char * const opcode_enc_class_names[XX_LAST_ENC_CLASS] = { + "NORMAL", + "16BIT", + "SUBINSN_A", + "SUBINSN_L1", + "SUBINSN_L2", + "SUBINSN_S1", + "SUBINSN_S2", + "EXT_noext", + "EXT_mmvec", +}; + +static const char *get_opcode_enc(int opcode) +{ + const char *tmp = opcode_encodings[opcode].encoding; + if (tmp == NULL) { + tmp = "MISSING ENCODING"; + } + return tmp; +} + +static const char *get_opcode_enc_class(int opcode) +{ + return opcode_enc_class_names[opcode_encodings[opcode].enc_class]; +} + +static void gen_iset_table(FILE *out) +{ + int i; + + fprintf(out, "iset = {\n"); + for (i = 0; i < XX_LAST_OPCODE; i++) { + fprintf(out, "\t\'%s\' : {\n", opcode_names[i]); + fprintf(out, "\t\t\'tag\' : \'%s\',\n", opcode_names[i]); + fprintf(out, "\t\t\'syntax\' : \'%s\',\n", opcode_syntax[i]); + fprintf(out, "\t\t\'rregs\' : \'%s\',\n", opcode_rregs[i]); + fprintf(out, "\t\t\'wregs\' : \'%s\',\n", opcode_wregs[i]); + fprintf(out, "\t\t\'enc\' : \'%s\',\n", get_opcode_enc(i)); + fprintf(out, "\t\t\'enc_class\' : \'%s\',\n", get_opcode_enc_class(i)); + fprintf(out, "\t},\n"); + } + fprintf(out, "};\n\n"); +} + +static void gen_tags_list(FILE *out) +{ + int i; + + fprintf(out, "tags = [\n"); + for (i = 0; i < XX_LAST_OPCODE; i++) { + fprintf(out, "\t\'%s\',\n", opcode_names[i]); + } + fprintf(out, "];\n\n"); +} + +static void gen_enc_ext_spaces_table(FILE *out) +{ + fprintf(out, "enc_ext_spaces = {\n"); +#define DEF_EXT_SPACE(SPACEID, ENCSTR) \ + fprintf(out, "\t\'%s\' : \'%s\',\n", #SPACEID, ENCSTR); +#include "imported/encode.def" +#undef DEF_EXT_SPACE + fprintf(out, "};\n\n"); +} + +static void gen_subinsn_groupings_table(FILE *out) +{ + fprintf(out, "subinsn_groupings = {\n"); +#define DEF_PACKED32(TAG, TYPEA, TYPEB, ENCSTR) \ + do { \ + fprintf(out, "\t\'%s\' : {\n", #TAG); \ + fprintf(out, "\t\t\'name\' : \'%s\',\n", #TAG); \ + fprintf(out, "\t\t\'class_a\' : \'%s\',\n", #TYPEA); \ + fprintf(out, "\t\t\'class_b\' : \'%s\',\n", #TYPEB); \ + fprintf(out, "\t\t\'enc\' : \'%s\',\n", ENCSTR); \ + fprintf(out, "\t},\n"); \ + } while (0); +#include "imported/encode.def" +#undef DEF_PACKED32 + fprintf(out, "};\n\n"); +} + +int main(int argc, char *argv[]) +{ + FILE *outfile; + + if (argc != 2) { + fprintf(stderr, "Usage: gen_dectree_import ouptputfile\n"); + return 1; + } + outfile = fopen(argv[1], "w"); + if (outfile == NULL) { + fprintf(stderr, "Cannot open %s for writing\n", argv[1]); + return 1; + } + + gen_iset_table(outfile); + gen_tags_list(outfile); + gen_enc_ext_spaces_table(outfile); + gen_subinsn_groupings_table(outfile); + + fclose(outfile); + return 0; +} From patchwork Thu Oct 29 23:58:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBA94C2D0A3 for ; Fri, 30 Oct 2020 00:26:29 +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 319D720709 for ; Fri, 30 Oct 2020 00:26:29 +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="Z5c3mzeX" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 319D720709 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44584 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYIFQ-0004Ja-57 for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:26:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37380) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHpS-0000ZU-6e for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:38 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:54880) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHpP-0004Kz-2i for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015975; x=1635551975; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=imU09Tt+d1ujYxvMKPP7vwVzxTmlGL4gnQuSe05AbUk=; b=Z5c3mzeX1jA9Iw0iJk1eAp5+75X5+Mv4xR7qjq/7jyrkNO56oBwv4cNc MmZUwD2w56I135l56f+AjqyoPXphsQDBdPNsGGNOzWU5ednAvtrB4oDHq sVKuPOdoaTz89JYmDQRod1ZAa8fdQAjJMLnUOT21aHeCmakbLNmNqKC9m 8=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 3F5F84115; Thu, 29 Oct 2020 18:58:55 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 23/33] Hexagon (target/hexagon) opcode data structures Date: Thu, 29 Oct 2020 18:58:40 -0500 Message-Id: <1604015931-23005-24-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Taylor Simpson --- target/hexagon/opcodes.h | 63 +++++++++++++++++++++ target/hexagon/opcodes.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 target/hexagon/opcodes.h create mode 100644 target/hexagon/opcodes.c diff --git a/target/hexagon/opcodes.h b/target/hexagon/opcodes.h new file mode 100644 index 0000000..1aa2074 --- /dev/null +++ b/target/hexagon/opcodes.h @@ -0,0 +1,63 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_OPCODES_H +#define HEXAGON_OPCODES_H + +#include "qemu/bitmap.h" +#include "attribs.h" + +typedef enum { +#define OPCODE(IID) IID +#include "opcodes_def_generated.h" + XX_LAST_OPCODE +#undef OPCODE +} Opcode; + +typedef enum { + NORMAL, + HALF, + SUBINSN_A, + SUBINSN_L1, + SUBINSN_L2, + SUBINSN_S1, + SUBINSN_S2, + EXT_noext, + EXT_mmvec, + XX_LAST_ENC_CLASS +} EncClass; + +extern const char * const opcode_names[]; + +extern const char * const opcode_reginfo[]; +extern const char * const opcode_rregs[]; +extern const char * const opcode_wregs[]; + +typedef struct { + const char * const encoding; + const EncClass enc_class; +} OpcodeEncoding; + +extern const OpcodeEncoding opcode_encodings[XX_LAST_OPCODE]; + +extern DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB); + +extern void opcode_init(void); + +extern int opcode_which_immediate_is_extended(Opcode opcode); + +#endif diff --git a/target/hexagon/opcodes.c b/target/hexagon/opcodes.c new file mode 100644 index 0000000..20400f5 --- /dev/null +++ b/target/hexagon/opcodes.c @@ -0,0 +1,142 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * opcodes.c + * + * data tables generated automatically + * Maybe some functions too + */ + +#include "qemu/osdep.h" +#include "opcodes.h" +#include "decode.h" + +#define VEC_DESCR(A, B, C) DESCR(A, B, C) +#define DONAME(X) #X + +const char * const opcode_names[] = { +#define OPCODE(IID) DONAME(IID) +#include "opcodes_def_generated.h" + NULL +#undef OPCODE +}; + +const char * const opcode_reginfo[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) REGINFO, +#include "op_regs_generated.h" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_rregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, +#include "op_regs_generated.h" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_wregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, +#include "op_regs_generated.h" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const char * const opcode_short_semantics[] = { +#define DEF_SHORTCODE(TAG, SHORTCODE) [TAG] = #SHORTCODE, +#include "shortcode_generated.h" +#undef DEF_SHORTCODE + NULL +}; + +DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB); + +static void init_attribs(int tag, ...) +{ + va_list ap; + int attr; + va_start(ap, tag); + while ((attr = va_arg(ap, int)) != 0) { + set_bit(attr, opcode_attribs[tag]); + } +} + +const OpcodeEncoding opcode_encodings[] = { +#define DEF_ENC32(OPCODE, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR }, + +#define DEF_ENC_SUBINSN(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#define DEF_EXT_ENC(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#include "imported/encode.def" + +#undef DEF_ENC32 +#undef DEF_ENC_SUBINSN +#undef DEF_EXT_ENC +}; + +void opcode_init(void) +{ + init_attribs(0, 0); + +#define ATTRIBS(...) , ## __VA_ARGS__, 0 +#define OP_ATTRIB(TAG, ARGS) init_attribs(TAG ARGS); +#include "op_attribs_generated.h" +#undef OP_ATTRIB +#undef ATTRIBS + + decode_init(); +} + + +#define NEEDLE "IMMEXT(" + +int opcode_which_immediate_is_extended(Opcode opcode) +{ + const char *p; + + g_assert(opcode < XX_LAST_OPCODE); + g_assert(GET_ATTRIB(opcode, A_EXTENDABLE)); + + p = opcode_short_semantics[opcode]; + p = strstr(p, NEEDLE); + g_assert(p); + p += strlen(NEEDLE); + while (isspace(*p)) { + p++; + } + /* lower is always imm 0, upper always imm 1. */ + if (islower(*p)) { + return 0; + } else if (isupper(*p)) { + return 1; + } else { + g_assert_not_reached(); + } +} From patchwork Thu Oct 29 23:58:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC160C2D0A3 for ; Fri, 30 Oct 2020 00:19: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 09FC220756 for ; Fri, 30 Oct 2020 00:19:29 +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="O3a+oRg6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 09FC220756 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56000 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYI8e-0005dn-UR for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:19:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37266) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHp1-0008S7-Gl for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:11 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:54410) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHot-0004L0-0H for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015943; x=1635551943; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=m+lZZo8zrYMfHUbTWbWGbgG+6XXEcffnvelfRtRKKSo=; b=O3a+oRg6Rkrks1Zas3hqXKfe58E3FFyMpBPGmuejeci4sf5BwXQH1x5k /Itk9JqrtK1P6IkUs5uiKNx1TlHvzPTL7ZySNGZjOyCXEffd+oNUsm4GM 1C4E3+FnNkOqN5W0FgHySiQZ/vlFS5VFPTQrlkPDGie5fkG8WA3a0pcjd 8=; Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by alexa-out-sd-01.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg01-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 723EE411C; Thu, 29 Oct 2020 18:58:55 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 25/33] Hexagon (target/hexagon) instruction classes Date: Thu, 29 Oct 2020 18:58:42 -0500 Message-Id: <1604015931-23005-26-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.38; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-01.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Determine legal VLIW slots for each instruction Signed-off-by: Taylor Simpson --- target/hexagon/iclass.h | 50 ++++++++++++++++++++++++++ target/hexagon/iclass.c | 73 ++++++++++++++++++++++++++++++++++++++ target/hexagon/imported/iclass.def | 51 ++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 target/hexagon/iclass.h create mode 100644 target/hexagon/iclass.c create mode 100644 target/hexagon/imported/iclass.def diff --git a/target/hexagon/iclass.h b/target/hexagon/iclass.h new file mode 100644 index 0000000..b57f11d --- /dev/null +++ b/target/hexagon/iclass.h @@ -0,0 +1,50 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ICLASS_H +#define HEXAGON_ICLASS_H + +#include "opcodes.h" + +#define ICLASS_FROM_TYPE(TYPE) ICLASS_##TYPE + +enum { + +#define DEF_PP_ICLASS32(TYPE, SLOTS, UNITS) ICLASS_FROM_TYPE(TYPE), +#define DEF_EE_ICLASS32(TYPE, SLOTS, UNITS) ICLASS_FROM_TYPE(TYPE), +#include "imported/iclass.def" +#undef DEF_PP_ICLASS32 +#undef DEF_EE_ICLASS32 + + ICLASS_FROM_TYPE(COPROC_VX), + ICLASS_FROM_TYPE(COPROC_VMEM), + NUM_ICLASSES +}; + +typedef enum { + SLOTS_0 = (1 << 0), + SLOTS_1 = (1 << 1), + SLOTS_2 = (1 << 2), + SLOTS_3 = (1 << 3), + SLOTS_01 = SLOTS_0 | SLOTS_1, + SLOTS_23 = SLOTS_2 | SLOTS_3, + SLOTS_0123 = SLOTS_0 | SLOTS_1 | SLOTS_2 | SLOTS_3, +} SlotMask; + +extern SlotMask find_iclass_slots(Opcode opcode, int itype); + +#endif diff --git a/target/hexagon/iclass.c b/target/hexagon/iclass.c new file mode 100644 index 0000000..05117a9 --- /dev/null +++ b/target/hexagon/iclass.c @@ -0,0 +1,73 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "iclass.h" + +static const SlotMask iclass_info[] = { + +#define DEF_PP_ICLASS32(TYPE, SLOTS, UNITS) \ + [ICLASS_FROM_TYPE(TYPE)] = SLOTS_##SLOTS, +#define DEF_EE_ICLASS32(TYPE, SLOTS, UNITS) \ + [ICLASS_FROM_TYPE(TYPE)] = SLOTS_##SLOTS, +#include "imported/iclass.def" +#undef DEF_PP_ICLASS32 +#undef DEF_EE_ICLASS32 +}; + +SlotMask find_iclass_slots(Opcode opcode, int itype) +{ + /* There are some exceptions to what the iclass dictates */ + if (GET_ATTRIB(opcode, A_ICOP)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT0ONLY)) { + return SLOTS_0; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT1ONLY)) { + return SLOTS_1; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT2ONLY)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT3ONLY)) { + return SLOTS_3; + } else if (GET_ATTRIB(opcode, A_COF) && + GET_ATTRIB(opcode, A_INDIRECT) && + !GET_ATTRIB(opcode, A_MEMLIKE) && + !GET_ATTRIB(opcode, A_MEMLIKE_PACKET_RULES)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_NOSLOT1)) { + return SLOTS_0; + } else if ((opcode == J2_trap0) || + (opcode == Y2_isync) || + (opcode == J4_hintjumpr)) { + return SLOTS_2; + } else if ((itype == ICLASS_V2LDST) && (GET_ATTRIB(opcode, A_STORE))) { + return SLOTS_01; + } else if ((itype == ICLASS_V2LDST) && (!GET_ATTRIB(opcode, A_STORE))) { + return SLOTS_01; + } else if (GET_ATTRIB(opcode, A_CRSLOT23)) { + return SLOTS_23; + } else if (GET_ATTRIB(opcode, A_RESTRICT_PREFERSLOT0)) { + return SLOTS_0; + } else if (GET_ATTRIB(opcode, A_SUBINSN)) { + return SLOTS_01; + } else if (GET_ATTRIB(opcode, A_CALL)) { + return SLOTS_23; + } else if ((opcode == J4_jumpseti) || (opcode == J4_jumpsetr)) { + return SLOTS_23; + } else { + return iclass_info[itype]; + } +} diff --git a/target/hexagon/imported/iclass.def b/target/hexagon/imported/iclass.def new file mode 100644 index 0000000..92b0406 --- /dev/null +++ b/target/hexagon/imported/iclass.def @@ -0,0 +1,51 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* DEF_*(TYPE,SLOTS,UNITS) */ +DEF_PP_ICLASS32(EXTENDER,0123,LDST|SUNIT|MUNIT) /* 0 */ +DEF_PP_ICLASS32(CJ,0123,CTRLFLOW) /* 1 */ +DEF_PP_ICLASS32(NCJ,01,LDST|CTRLFLOW) /* 2 */ +DEF_PP_ICLASS32(V4LDST,01,LDST) /* 3 */ +DEF_PP_ICLASS32(V2LDST,01,LDST) /* 4 */ +DEF_PP_ICLASS32(J,0123,CTRLFLOW) /* 5 */ +DEF_PP_ICLASS32(CR,3,SUNIT) /* 6 */ +DEF_PP_ICLASS32(ALU32_2op,0123,LDST|SUNIT|MUNIT) /* 7 */ +DEF_PP_ICLASS32(S_2op,23,SUNIT|MUNIT) /* 8 */ +DEF_PP_ICLASS32(LD,01,LDST) /* 9 */ +DEF_PP_ICLASS32(ST,01,LDST) /* 10 */ +DEF_PP_ICLASS32(ALU32_ADDI,0123,LDST|SUNIT|MUNIT) /* 11 */ +DEF_PP_ICLASS32(S_3op,23,SUNIT|MUNIT) /* 12 */ +DEF_PP_ICLASS32(ALU64,23,SUNIT|MUNIT) /* 13 */ +DEF_PP_ICLASS32(M,23,SUNIT|MUNIT) /* 14 */ +DEF_PP_ICLASS32(ALU32_3op,0123,LDST|SUNIT|MUNIT) /* 15 */ + +DEF_EE_ICLASS32(EE0,01,INVALID) /* 0 */ +DEF_EE_ICLASS32(EE1,01,INVALID) /* 1 */ +DEF_EE_ICLASS32(EE2,01,INVALID) /* 2 */ +DEF_EE_ICLASS32(EE3,01,INVALID) /* 3 */ +DEF_EE_ICLASS32(EE4,01,INVALID) /* 4 */ +DEF_EE_ICLASS32(EE5,01,INVALID) /* 5 */ +DEF_EE_ICLASS32(EE6,01,INVALID) /* 6 */ +DEF_EE_ICLASS32(EE7,01,INVALID) /* 7 */ +DEF_EE_ICLASS32(EE8,01,INVALID) /* 8 */ +DEF_EE_ICLASS32(EE9,01,INVALID) /* 9 */ +DEF_EE_ICLASS32(EEA,01,INVALID) /* 10 */ +DEF_EE_ICLASS32(EEB,01,INVALID) /* 11 */ +DEF_EE_ICLASS32(EEC,01,INVALID) /* 12 */ +DEF_EE_ICLASS32(EED,01,INVALID) /* 13 */ +DEF_EE_ICLASS32(EEE,01,INVALID) /* 14 */ +DEF_EE_ICLASS32(EEF,01,INVALID) /* 15 */ From patchwork Thu Oct 29 23:58:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316581 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE7C7C4742C for ; Fri, 30 Oct 2020 00:09:30 +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 17BF620756 for ; Fri, 30 Oct 2020 00:09:30 +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="G0fmgBPx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 17BF620756 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60034 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYHyy-0003eL-Vi for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:09:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37402) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHpU-0000by-PY for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:42 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:9898) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHpR-0004Lk-St for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015977; x=1635551977; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EEzL3rhGnVtZiY8emjGk7wiV7wZzkWzvxkVbFB212XY=; b=G0fmgBPxUKYDzturwnhqGq+FGD54JE8RU0AZP8GZZjOVCejBY6zDsv7t MW4IQejaL9Ol9vVq7rv4PKto4GHfcWoaQ4CiJkDQIT/BnnEiJEl6dvfcg cJ7PH1LwHeYV24uti1RrTqkrDPJUYmoKZ+XHBxpiDNQzR1ztODbmQSezr 4=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:56 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 8B2594119; Thu, 29 Oct 2020 18:58:55 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 26/33] Hexagon (target/hexagon) TCG generation Date: Thu, 29 Oct 2020 18:58:43 -0500 Message-Id: <1604015931-23005-27-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Include the generated files and set up the data structures Signed-off-by: Taylor Simpson --- target/hexagon/genptr.h | 25 ++++++ target/hexagon/genptr.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 target/hexagon/genptr.h create mode 100644 target/hexagon/genptr.c diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h new file mode 100644 index 0000000..4e8f903 --- /dev/null +++ b/target/hexagon/genptr.h @@ -0,0 +1,25 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_GENPTR_H +#define HEXAGON_GENPTR_H + +#include "insn.h" + +extern const SemanticInsn opcode_genptr[]; + +#endif diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c new file mode 100644 index 0000000..ba233a4 --- /dev/null +++ b/target/hexagon/genptr.c @@ -0,0 +1,234 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#define QEMU_GENERATE +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "cpu.h" +#include "internal.h" +#include "tcg/tcg-op.h" +#include "insn.h" +#include "opcodes.h" +#include "translate.h" +#include "macros.h" +#include "gen_tcg.h" + +static inline TCGv gen_read_reg(TCGv result, int num) +{ + tcg_gen_mov_tl(result, hex_gpr[num]); + return result; +} + +static inline TCGv gen_read_preg(TCGv pred, uint8_t num) +{ + tcg_gen_mov_tl(pred, hex_pred[num]); + return pred; +} + +static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot) +{ + TCGv one = tcg_const_tl(1); + TCGv zero = tcg_const_tl(0); + TCGv slot_mask = tcg_temp_new(); + + tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero, + val, hex_new_value[rnum]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], slot_mask, zero, + one, hex_reg_written[rnum]); +#endif + + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(slot_mask); +} + +static inline void gen_log_reg_write(int rnum, TCGv val) +{ + tcg_gen_mov_tl(hex_new_value[rnum], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum], 1); +#endif +} + +static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot) +{ + TCGv val32 = tcg_temp_new(); + TCGv one = tcg_const_tl(1); + TCGv zero = tcg_const_tl(0); + TCGv slot_mask = tcg_temp_new(); + + tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot); + /* Low word */ + tcg_gen_extrl_i64_i32(val32, val); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero, + val32, hex_new_value[rnum]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], + slot_mask, zero, + one, hex_reg_written[rnum]); +#endif + + /* High word */ + tcg_gen_extrh_i64_i32(val32, val); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum + 1], + slot_mask, zero, + val32, hex_new_value[rnum + 1]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum + 1], + slot_mask, zero, + one, hex_reg_written[rnum + 1]); +#endif + + tcg_temp_free(val32); + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(slot_mask); +} + +static void gen_log_reg_write_pair(int rnum, TCGv_i64 val) +{ + /* Low word */ + tcg_gen_extrl_i64_i32(hex_new_value[rnum], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum], 1); +#endif + + /* High word */ + tcg_gen_extrh_i64_i32(hex_new_value[rnum + 1], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum + 1], 1); +#endif +} + +static inline void gen_log_pred_write(int pnum, TCGv val) +{ + TCGv zero = tcg_const_tl(0); + TCGv base_val = tcg_temp_new(); + TCGv and_val = tcg_temp_new(); + TCGv pred_written = tcg_temp_new(); + + /* Multiple writes to the same preg are and'ed together */ + tcg_gen_andi_tl(base_val, val, 0xff); + tcg_gen_and_tl(and_val, base_val, hex_new_pred_value[pnum]); + tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pnum); + tcg_gen_movcond_tl(TCG_COND_NE, hex_new_pred_value[pnum], + pred_written, zero, + and_val, base_val); + tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum); + + tcg_temp_free(zero); + tcg_temp_free(base_val); + tcg_temp_free(and_val); + tcg_temp_free(pred_written); +} + +static inline void gen_read_p3_0(TCGv control_reg) +{ + tcg_gen_movi_tl(control_reg, 0); + for (int i = 0; i < NUM_PREGS; i++) { + tcg_gen_deposit_tl(control_reg, control_reg, hex_pred[i], i * 8, 8); + } +} + +static inline void gen_write_p3_0(TCGv control_reg) +{ + for (int i = 0; i < NUM_PREGS; i++) { + tcg_gen_extract_tl(hex_pred[i], control_reg, i * 8, 8); + } +} + +static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index) +{ + tcg_gen_qemu_ld32u(dest, vaddr, mem_index); + tcg_gen_mov_tl(hex_llsc_addr, vaddr); + tcg_gen_mov_tl(hex_llsc_val, dest); +} + +static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index) +{ + tcg_gen_qemu_ld64(dest, vaddr, mem_index); + tcg_gen_mov_tl(hex_llsc_addr, vaddr); + tcg_gen_mov_i64(hex_llsc_val_i64, dest); +} + +static inline void gen_store_conditional4(CPUHexagonState *env, + DisasContext *ctx, int prednum, + TCGv pred, TCGv vaddr, TCGv src) +{ + TCGLabel *fail = gen_new_label(); + TCGLabel *done = gen_new_label(); + + tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail); + + TCGv one = tcg_const_tl(0xff); + TCGv zero = tcg_const_tl(0); + TCGv tmp = tcg_temp_new(); + tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src, + ctx->mem_idx, MO_32); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_pred[prednum], tmp, hex_llsc_val, + one, zero); + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(tmp); + tcg_gen_br(done); + + gen_set_label(fail); + tcg_gen_movi_tl(pred, 0); + + gen_set_label(done); + tcg_gen_movi_tl(hex_llsc_addr, ~0); +} + +static inline void gen_store_conditional8(CPUHexagonState *env, + DisasContext *ctx, int prednum, + TCGv pred, TCGv vaddr, TCGv_i64 src) +{ + TCGLabel *fail = gen_new_label(); + TCGLabel *done = gen_new_label(); + + tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail); + + TCGv_i64 one = tcg_const_i64(0xff); + TCGv_i64 zero = tcg_const_i64(0); + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_atomic_cmpxchg_i64(tmp, hex_llsc_addr, hex_llsc_val_i64, src, + ctx->mem_idx, MO_64); + tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64, + one, zero); + tcg_gen_extrl_i64_i32(hex_pred[prednum], tmp); + tcg_temp_free_i64(one); + tcg_temp_free_i64(zero); + tcg_temp_free_i64(tmp); + tcg_gen_br(done); + + gen_set_label(fail); + tcg_gen_movi_tl(pred, 0); + + gen_set_label(done); + tcg_gen_movi_tl(hex_llsc_addr, ~0); +} + +#include "tcg_funcs_generated.h" +#include "tcg_func_table_generated.h" From patchwork Thu Oct 29 23:58:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316580 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21E56C2D0A3 for ; Fri, 30 Oct 2020 00:12:25 +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 5A466206B2 for ; Fri, 30 Oct 2020 00:12:24 +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="IEChSnKc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5A466206B2 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38362 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYI1n-0006cm-4P for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:12:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37424) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHpc-0000hn-SP for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:48 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:48752) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHpU-0004LT-Gj for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015980; x=1635551980; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Xr0dSzItmvM5bSRls/4sIMpBdyRC7yrAqq7p4Jv+3Z4=; b=IEChSnKcYDjYQEVH2MMmzqIJyaWY/r1Y1ERccvuAqafvWG1AOOtrH+hw EWv9ShM/47LBvdxgSeaDx9n8+lIAL7yQV6YLbs/L0d0v+6OQ4F/JVrPuv Hs8q6lmhcPFS83EzXPucDSgjavIDgW097HEQsqcifL2mtC4VH3xRV4bDe s=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 29 Oct 2020 16:58:56 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg04-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:55 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 9FB8D411A; Thu, 29 Oct 2020 18:58:55 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 27/33] Hexagon (target/hexagon) TCG for instructions with multiple definitions Date: Thu, 29 Oct 2020 18:58:44 -0500 Message-Id: <1604015931-23005-28-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Helpers won't work if there are multiple definitions, so we override these instructions using #define fGEN_TCG_. Signed-off-by: Taylor Simpson --- target/hexagon/gen_tcg.h | 198 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 target/hexagon/gen_tcg.h diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h new file mode 100644 index 0000000..35568d1 --- /dev/null +++ b/target/hexagon/gen_tcg.h @@ -0,0 +1,198 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_GEN_TCG_H +#define HEXAGON_GEN_TCG_H + +/* + * Here is a primer to understand the tag names for load/store instructions + * + * Data types + * b signed byte r0 = memb(r2+#0) + * ub unsigned byte r0 = memub(r2+#0) + * h signed half word (16 bits) r0 = memh(r2+#0) + * uh unsigned half word r0 = memuh(r2+#0) + * i integer (32 bits) r0 = memw(r2+#0) + * d double word (64 bits) r1:0 = memd(r2+#0) + * + * Addressing modes + * _io indirect with offset r0 = memw(r1+#4) + * _ur absolute with register offset r0 = memw(r1<<#4+##variable) + * _rr indirect with register offset r0 = memw(r1+r4<<#2) + * gp global pointer relative r0 = memw(gp+#200) + * _sp stack pointer relative r0 = memw(r29+#12) + * _ap absolute set r0 = memw(r1=##variable) + * _pr post increment register r0 = memw(r1++m1) + * _pi post increment immediate r0 = memb(r1++#1) + */ + +/* Macros for complex addressing modes */ +#define GET_EA_ap \ + do { \ + fEA_IMM(UiV); \ + tcg_gen_movi_tl(ReV, UiV); \ + } while (0) +#define GET_EA_pr \ + do { \ + fEA_REG(RxV); \ + fPM_M(RxV, MuV); \ + } while (0) +#define GET_EA_pi \ + do { \ + fEA_REG(RxV); \ + fPM_I(RxV, siV); \ + } while (0) + + +/* Instructions with multiple definitions */ +#define fGEN_TCG_LOAD_AP(RES, SIZE, SIGN) \ + do { \ + fMUST_IMMEXT(UiV); \ + fEA_IMM(UiV); \ + fLOAD(1, SIZE, SIGN, EA, RES); \ + tcg_gen_movi_tl(ReV, UiV); \ + } while (0) + +#define fGEN_TCG_L4_loadrub_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 1, u) +#define fGEN_TCG_L4_loadrb_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 1, s) +#define fGEN_TCG_L4_loadruh_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 2, u) +#define fGEN_TCG_L4_loadrh_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 2, s) +#define fGEN_TCG_L4_loadri_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 4, u) +#define fGEN_TCG_L4_loadrd_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RddV, 8, u) + +#define fGEN_TCG_L2_loadrub_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrub_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrb_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrb_pi(SHORTCODE) SHORTCODE; +#define fGEN_TCG_L2_loadruh_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadruh_pi(SHORTCODE) SHORTCODE; +#define fGEN_TCG_L2_loadrh_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrh_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadri_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadri_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrd_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrd_pi(SHORTCODE) SHORTCODE + +/* + * Predicated loads + * Here is a primer to understand the tag names + * + * Predicate used + * t true "old" value if (p0) r0 = memb(r2+#0) + * f false "old" value if (!p0) r0 = memb(r2+#0) + * tnew true "new" value if (p0.new) r0 = memb(r2+#0) + * fnew false "new" value if (!p0.new) r0 = memb(r2+#0) + */ +#define fGEN_TCG_PRED_LOAD(GET_EA, PRED, SIZE, SIGN) \ + do { \ + TCGv LSB = tcg_temp_local_new(); \ + TCGLabel *label = gen_new_label(); \ + GET_EA; \ + PRED; \ + PRED_LOAD_CANCEL(LSB, EA); \ + tcg_gen_movi_tl(RdV, 0); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ + fLOAD(1, SIZE, SIGN, EA, RdV); \ + gen_set_label(label); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_L2_ploadrubt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, u) +#define fGEN_TCG_L2_ploadrubf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, u) +#define fGEN_TCG_L2_ploadrubtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, u) +#define fGEN_TCG_L2_ploadrubfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 1, u) +#define fGEN_TCG_L2_ploadrbt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, s) +#define fGEN_TCG_L2_ploadrbf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, s) +#define fGEN_TCG_L2_ploadrbtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, s) +#define fGEN_TCG_L2_ploadrbfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD({ fEA_REG(RxV); fPM_I(RxV, siV); }, \ + fLSBNEWNOT(PtN), 1, s) + +#define fGEN_TCG_L2_ploadruht_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, u) +#define fGEN_TCG_L2_ploadruhf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, u) +#define fGEN_TCG_L2_ploadruhtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, u) +#define fGEN_TCG_L2_ploadruhfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, u) +#define fGEN_TCG_L2_ploadrht_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, s) +#define fGEN_TCG_L2_ploadrhf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, s) +#define fGEN_TCG_L2_ploadrhtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, s) +#define fGEN_TCG_L2_ploadrhfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, s) + +#define fGEN_TCG_L2_ploadrit_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 4, u) +#define fGEN_TCG_L2_ploadrif_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 4, u) +#define fGEN_TCG_L2_ploadritnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 4, u) +#define fGEN_TCG_L2_ploadrifnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 4, u) + +/* Predicated loads into a register pair */ +#define fGEN_TCG_PRED_LOAD_PAIR(GET_EA, PRED) \ + do { \ + TCGv LSB = tcg_temp_local_new(); \ + TCGLabel *label = gen_new_label(); \ + GET_EA; \ + PRED; \ + PRED_LOAD_CANCEL(LSB, EA); \ + tcg_gen_movi_i64(RddV, 0); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ + fLOAD(1, 8, u, EA, RddV); \ + gen_set_label(label); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_L2_ploadrdt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLD(PtV)) +#define fGEN_TCG_L2_ploadrdf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLDNOT(PtV)) +#define fGEN_TCG_L2_ploadrdtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEW(PtN)) +#define fGEN_TCG_L2_ploadrdfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEWNOT(PtN)) + +/* load-locked and store-locked */ +#define fGEN_TCG_L2_loadw_locked(SHORTCODE) \ + SHORTCODE +#define fGEN_TCG_L4_loadd_locked(SHORTCODE) \ + SHORTCODE +#define fGEN_TCG_S2_storew_locked(SHORTCODE) \ + do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) +#define fGEN_TCG_S4_stored_locked(SHORTCODE) \ + do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) + +#endif From patchwork Thu Oct 29 23:58:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 316578 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C9D9C2D0A3 for ; Fri, 30 Oct 2020 00:16:03 +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 5EE84206ED for ; Fri, 30 Oct 2020 00:16:02 +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="a1v3GSNt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EE84206ED 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+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:47686 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kYI5J-00021f-5g for qemu-devel@archiver.kernel.org; Thu, 29 Oct 2020 20:16:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37244) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kYHp0-0008Of-AH for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:10 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:59773) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kYHou-0004LG-8T for qemu-devel@nongnu.org; Thu, 29 Oct 2020 19:59:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1604015944; x=1635551944; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Z3GOQvRilMdBUGTcqnDiNcEczOVfMXGBe+bBnRUXG8U=; b=a1v3GSNt3i+jcmr8o319nRk2lDsukRQBcqcmKXtZ2Z2djTE7DcJ8kB7q 8pSy982Fyih3f+c0f/gb4+Yb+gDTqtKDjWEPVEBR0XFkEJn7gVkHZU8SK y4QJw8L4RkZRVHnlRqVqr9rHt3F8Orj/v2TTSxs4pOOdlLSod/9yQ0zPU s=; Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by alexa-out-sd-01.qualcomm.com with ESMTP; 29 Oct 2020 16:58:56 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg01-sd.qualcomm.com with ESMTP; 29 Oct 2020 16:58:56 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 2B7374119; Thu, 29 Oct 2020 18:58:56 -0500 (CDT) From: Taylor Simpson To: tsimpson@quicinc.com Subject: [RFC PATCH v5 30/33] Hexagon (linux-user/hexagon) Linux user emulation Date: Thu, 29 Oct 2020 18:58:47 -0500 Message-Id: <1604015931-23005-31-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> References: <1604015931-23005-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.38; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-01.qualcomm.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/29 19:58:53 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: Laurent Vivier , "open list:All patches CC here" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Implementation of Linux user emulation for Hexagon Some common files modified in addition to new files in linux-user/hexagon Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson --- linux-user/hexagon/sockbits.h | 18 ++ linux-user/hexagon/syscall_nr.h | 322 ++++++++++++++++++++++++++++++++++++ linux-user/hexagon/target_cpu.h | 44 +++++ linux-user/hexagon/target_elf.h | 40 +++++ linux-user/hexagon/target_fcntl.h | 18 ++ linux-user/hexagon/target_signal.h | 34 ++++ linux-user/hexagon/target_structs.h | 46 ++++++ linux-user/hexagon/target_syscall.h | 36 ++++ linux-user/hexagon/termbits.h | 18 ++ linux-user/qemu.h | 2 + linux-user/syscall_defs.h | 33 ++++ linux-user/elfload.c | 16 ++ linux-user/hexagon/cpu_loop.c | 99 +++++++++++ linux-user/hexagon/signal.c | 276 +++++++++++++++++++++++++++++++ scripts/gensyscalls.sh | 1 + 15 files changed, 1003 insertions(+) create mode 100644 linux-user/hexagon/sockbits.h create mode 100644 linux-user/hexagon/syscall_nr.h create mode 100644 linux-user/hexagon/target_cpu.h create mode 100644 linux-user/hexagon/target_elf.h create mode 100644 linux-user/hexagon/target_fcntl.h create mode 100644 linux-user/hexagon/target_signal.h create mode 100644 linux-user/hexagon/target_structs.h create mode 100644 linux-user/hexagon/target_syscall.h create mode 100644 linux-user/hexagon/termbits.h create mode 100644 linux-user/hexagon/cpu_loop.c create mode 100644 linux-user/hexagon/signal.c diff --git a/linux-user/hexagon/sockbits.h b/linux-user/hexagon/sockbits.h new file mode 100644 index 0000000..a6e8966 --- /dev/null +++ b/linux-user/hexagon/sockbits.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../generic/sockbits.h" diff --git a/linux-user/hexagon/syscall_nr.h b/linux-user/hexagon/syscall_nr.h new file mode 100644 index 0000000..da1314f --- /dev/null +++ b/linux-user/hexagon/syscall_nr.h @@ -0,0 +1,322 @@ +/* + * This file contains the system call numbers. + * Do not modify. + * This file is generated by scripts/gensyscalls.sh + */ +#ifndef LINUX_USER_HEXAGON_SYSCALL_NR_H +#define LINUX_USER_HEXAGON_SYSCALL_NR_H + +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr 14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait 22 +#define TARGET_NR_dup 23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl64 25 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat 33 +#define TARGET_NR_mkdirat 34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_renameat 38 +#define TARGET_NR_umount2 39 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs64 43 +#define TARGET_NR_fstatfs64 44 +#define TARGET_NR_truncate64 45 +#define TARGET_NR_ftruncate64 46 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup 58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR_llseek 62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread64 67 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev 70 +#define TARGET_NR_sendfile64 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee 77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_fstatat64 79 +#define TARGET_NR_fstat64 80 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range 84 +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime 86 +#define TARGET_NR_timerfd_gettime 87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget 90 +#define TARGET_NR_capset 91 +#define TARGET_NR_personality 92 +#define TARGET_NR_exit 93 +#define TARGET_NR_exit_group 94 +#define TARGET_NR_waitid 95 +#define TARGET_NR_set_tid_address 96 +#define TARGET_NR_unshare 97 +#define TARGET_NR_futex 98 +#define TARGET_NR_set_robust_list 99 +#define TARGET_NR_get_robust_list 100 +#define TARGET_NR_nanosleep 101 +#define TARGET_NR_getitimer 102 +#define TARGET_NR_setitimer 103 +#define TARGET_NR_kexec_load 104 +#define TARGET_NR_init_module 105 +#define TARGET_NR_delete_module 106 +#define TARGET_NR_timer_create 107 +#define TARGET_NR_timer_gettime 108 +#define TARGET_NR_timer_getoverrun 109 +#define TARGET_NR_timer_settime 110 +#define TARGET_NR_timer_delete 111 +#define TARGET_NR_clock_settime 112 +#define TARGET_NR_clock_gettime 113 +#define TARGET_NR_clock_getres 114 +#define TARGET_NR_clock_nanosleep 115 +#define TARGET_NR_syslog 116 +#define TARGET_NR_ptrace 117 +#define TARGET_NR_sched_setparam 118 +#define TARGET_NR_sched_setscheduler 119 +#define TARGET_NR_sched_getscheduler 120 +#define TARGET_NR_sched_getparam 121 +#define TARGET_NR_sched_setaffinity 122 +#define TARGET_NR_sched_getaffinity 123 +#define TARGET_NR_sched_yield 124 +#define TARGET_NR_sched_get_priority_max 125 +#define TARGET_NR_sched_get_priority_min 126 +#define TARGET_NR_sched_rr_get_interval 127 +#define TARGET_NR_restart_syscall 128 +#define TARGET_NR_kill 129 +#define TARGET_NR_tkill 130 +#define TARGET_NR_tgkill 131 +#define TARGET_NR_sigaltstack 132 +#define TARGET_NR_rt_sigsuspend 133 +#define TARGET_NR_rt_sigaction 134 +#define TARGET_NR_rt_sigprocmask 135 +#define TARGET_NR_rt_sigpending 136 +#define TARGET_NR_rt_sigtimedwait 137 +#define TARGET_NR_rt_sigqueueinfo 138 +#define TARGET_NR_rt_sigreturn 139 +#define TARGET_NR_setpriority 140 +#define TARGET_NR_getpriority 141 +#define TARGET_NR_reboot 142 +#define TARGET_NR_setregid 143 +#define TARGET_NR_setgid 144 +#define TARGET_NR_setreuid 145 +#define TARGET_NR_setuid 146 +#define TARGET_NR_setresuid 147 +#define TARGET_NR_getresuid 148 +#define TARGET_NR_setresgid 149 +#define TARGET_NR_getresgid 150 +#define TARGET_NR_setfsuid 151 +#define TARGET_NR_setfsgid 152 +#define TARGET_NR_times 153 +#define TARGET_NR_setpgid 154 +#define TARGET_NR_getpgid 155 +#define TARGET_NR_getsid 156 +#define TARGET_NR_setsid 157 +#define TARGET_NR_getgroups 158 +#define TARGET_NR_setgroups 159 +#define TARGET_NR_uname 160 +#define TARGET_NR_sethostname 161 +#define TARGET_NR_setdomainname 162 +#define TARGET_NR_getrlimit 163 +#define TARGET_NR_setrlimit 164 +#define TARGET_NR_getrusage 165 +#define TARGET_NR_umask 166 +#define TARGET_NR_prctl 167 +#define TARGET_NR_getcpu 168 +#define TARGET_NR_gettimeofday 169 +#define TARGET_NR_settimeofday 170 +#define TARGET_NR_adjtimex 171 +#define TARGET_NR_getpid 172 +#define TARGET_NR_getppid 173 +#define TARGET_NR_getuid 174 +#define TARGET_NR_geteuid 175 +#define TARGET_NR_getgid 176 +#define TARGET_NR_getegid 177 +#define TARGET_NR_gettid 178 +#define TARGET_NR_sysinfo 179 +#define TARGET_NR_mq_open 180 +#define TARGET_NR_mq_unlink 181 +#define TARGET_NR_mq_timedsend 182 +#define TARGET_NR_mq_timedreceive 183 +#define TARGET_NR_mq_notify 184 +#define TARGET_NR_mq_getsetattr 185 +#define TARGET_NR_msgget 186 +#define TARGET_NR_msgctl 187 +#define TARGET_NR_msgrcv 188 +#define TARGET_NR_msgsnd 189 +#define TARGET_NR_semget 190 +#define TARGET_NR_semctl 191 +#define TARGET_NR_semtimedop 192 +#define TARGET_NR_semop 193 +#define TARGET_NR_shmget 194 +#define TARGET_NR_shmctl 195 +#define TARGET_NR_shmat 196 +#define TARGET_NR_shmdt 197 +#define TARGET_NR_socket 198 +#define TARGET_NR_socketpair 199 +#define TARGET_NR_bind 200 +#define TARGET_NR_listen 201 +#define TARGET_NR_accept 202 +#define TARGET_NR_connect 203 +#define TARGET_NR_getsockname 204 +#define TARGET_NR_getpeername 205 +#define TARGET_NR_sendto 206 +#define TARGET_NR_recvfrom 207 +#define TARGET_NR_setsockopt 208 +#define TARGET_NR_getsockopt 209 +#define TARGET_NR_shutdown 210 +#define TARGET_NR_sendmsg 211 +#define TARGET_NR_recvmsg 212 +#define TARGET_NR_readahead 213 +#define TARGET_NR_brk 214 +#define TARGET_NR_munmap 215 +#define TARGET_NR_mremap 216 +#define TARGET_NR_add_key 217 +#define TARGET_NR_request_key 218 +#define TARGET_NR_keyctl 219 +#define TARGET_NR_clone 220 +#define TARGET_NR_execve 221 +#define TARGET_NR_mmap2 222 +#define TARGET_NR_fadvise64_64 223 +#define TARGET_NR_swapon 224 +#define TARGET_NR_swapoff 225 +#define TARGET_NR_mprotect 226 +#define TARGET_NR_msync 227 +#define TARGET_NR_mlock 228 +#define TARGET_NR_munlock 229 +#define TARGET_NR_mlockall 230 +#define TARGET_NR_munlockall 231 +#define TARGET_NR_mincore 232 +#define TARGET_NR_madvise 233 +#define TARGET_NR_remap_file_pages 234 +#define TARGET_NR_mbind 235 +#define TARGET_NR_get_mempolicy 236 +#define TARGET_NR_set_mempolicy 237 +#define TARGET_NR_migrate_pages 238 +#define TARGET_NR_move_pages 239 +#define TARGET_NR_rt_tgsigqueueinfo 240 +#define TARGET_NR_perf_event_open 241 +#define TARGET_NR_accept4 242 +#define TARGET_NR_recvmmsg 243 +#define TARGET_NR_arch_specific_syscall 244 +#define TARGET_NR_wait4 260 +#define TARGET_NR_prlimit64 261 +#define TARGET_NR_fanotify_init 262 +#define TARGET_NR_fanotify_mark 263 +#define TARGET_NR_name_to_handle_at 264 +#define TARGET_NR_open_by_handle_at 265 +#define TARGET_NR_clock_adjtime 266 +#define TARGET_NR_syncfs 267 +#define TARGET_NR_setns 268 +#define TARGET_NR_sendmmsg 269 +#define TARGET_NR_process_vm_readv 270 +#define TARGET_NR_process_vm_writev 271 +#define TARGET_NR_kcmp 272 +#define TARGET_NR_finit_module 273 +#define TARGET_NR_sched_setattr 274 +#define TARGET_NR_sched_getattr 275 +#define TARGET_NR_renameat2 276 +#define TARGET_NR_seccomp 277 +#define TARGET_NR_getrandom 278 +#define TARGET_NR_memfd_create 279 +#define TARGET_NR_bpf 280 +#define TARGET_NR_execveat 281 +#define TARGET_NR_userfaultfd 282 +#define TARGET_NR_membarrier 283 +#define TARGET_NR_mlock2 284 +#define TARGET_NR_copy_file_range 285 +#define TARGET_NR_preadv2 286 +#define TARGET_NR_pwritev2 287 +#define TARGET_NR_pkey_mprotect 288 +#define TARGET_NR_pkey_alloc 289 +#define TARGET_NR_pkey_free 290 +#define TARGET_NR_statx 291 +#define TARGET_NR_io_pgetevents 292 +#define TARGET_NR_rseq 293 +#define TARGET_NR_kexec_file_load 294 +#define TARGET_NR_clock_gettime64 403 +#define TARGET_NR_clock_settime64 404 +#define TARGET_NR_clock_adjtime64 405 +#define TARGET_NR_clock_getres_time64 406 +#define TARGET_NR_clock_nanosleep_time64 407 +#define TARGET_NR_timer_gettime64 408 +#define TARGET_NR_timer_settime64 409 +#define TARGET_NR_timerfd_gettime64 410 +#define TARGET_NR_timerfd_settime64 411 +#define TARGET_NR_utimensat_time64 412 +#define TARGET_NR_pselect6_time64 413 +#define TARGET_NR_ppoll_time64 414 +#define TARGET_NR_io_pgetevents_time64 416 +#define TARGET_NR_recvmmsg_time64 417 +#define TARGET_NR_mq_timedsend_time64 418 +#define TARGET_NR_mq_timedreceive_time64 419 +#define TARGET_NR_semtimedop_time64 420 +#define TARGET_NR_rt_sigtimedwait_time64 421 +#define TARGET_NR_futex_time64 422 +#define TARGET_NR_sched_rr_get_interval_time64 423 +#define TARGET_NR_pidfd_send_signal 424 +#define TARGET_NR_io_uring_setup 425 +#define TARGET_NR_io_uring_enter 426 +#define TARGET_NR_io_uring_register 427 +#define TARGET_NR_open_tree 428 +#define TARGET_NR_move_mount 429 +#define TARGET_NR_fsopen 430 +#define TARGET_NR_fsconfig 431 +#define TARGET_NR_fsmount 432 +#define TARGET_NR_fspick 433 +#define TARGET_NR_pidfd_open 434 +#define TARGET_NR_syscalls 436 + +#endif /* LINUX_USER_HEXAGON_SYSCALL_NR_H */ diff --git a/linux-user/hexagon/target_cpu.h b/linux-user/hexagon/target_cpu.h new file mode 100644 index 0000000..53d45f5 --- /dev/null +++ b/linux-user/hexagon/target_cpu.h @@ -0,0 +1,44 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_CPU_H +#define HEXAGON_TARGET_CPU_H + +static inline void cpu_clone_regs_child(CPUHexagonState *env, + target_ulong newsp, unsigned flags) +{ + if (newsp) { + env->gpr[HEX_REG_SP] = newsp; + } + env->gpr[0] = 0; +} + +static inline void cpu_clone_regs_parent(CPUHexagonState *env, unsigned flags) +{ +} + +static inline void cpu_set_tls(CPUHexagonState *env, target_ulong newtls) +{ + env->gpr[HEX_REG_UGP] = newtls; +} + +static inline abi_ulong get_sp_from_cpustate(CPUHexagonState *state) +{ + return state->gpr[HEX_REG_SP]; +} + +#endif diff --git a/linux-user/hexagon/target_elf.h b/linux-user/hexagon/target_elf.h new file mode 100644 index 0000000..0058b94 --- /dev/null +++ b/linux-user/hexagon/target_elf.h @@ -0,0 +1,40 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_ELF_H +#define HEXAGON_TARGET_ELF_H + +static inline const char *cpu_get_model(uint32_t eflags) +{ + /* For now, treat anything newer than v5 as a v67 */ + /* FIXME - Disable instructions that are newer than the specified arch */ + if (eflags == 0x04 || /* v5 */ + eflags == 0x05 || /* v55 */ + eflags == 0x60 || /* v60 */ + eflags == 0x61 || /* v61 */ + eflags == 0x62 || /* v62 */ + eflags == 0x65 || /* v65 */ + eflags == 0x66 || /* v66 */ + eflags == 0x67 || /* v67 */ + eflags == 0x8067 /* v67t */ + ) { + return "v67"; + } + return "unknown"; +} + +#endif diff --git a/linux-user/hexagon/target_fcntl.h b/linux-user/hexagon/target_fcntl.h new file mode 100644 index 0000000..08162e6 --- /dev/null +++ b/linux-user/hexagon/target_fcntl.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../generic/fcntl.h" diff --git a/linux-user/hexagon/target_signal.h b/linux-user/hexagon/target_signal.h new file mode 100644 index 0000000..12a6187 --- /dev/null +++ b/linux-user/hexagon/target_signal.h @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_SIGNAL_H +#define HEXAGON_TARGET_SIGNAL_H + +typedef struct target_sigaltstack { + abi_ulong ss_sp; + abi_int ss_flags; + abi_ulong ss_size; +} target_stack_t; + +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ 2048 + +#include "../generic/signal.h" + +#endif /* TARGET_SIGNAL_H */ diff --git a/linux-user/hexagon/target_structs.h b/linux-user/hexagon/target_structs.h new file mode 100644 index 0000000..2e06227 --- /dev/null +++ b/linux-user/hexagon/target_structs.h @@ -0,0 +1,46 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Hexagon specific structures for linux-user + */ +#ifndef HEXAGON_TARGET_STRUCTS_H +#define HEXAGON_TARGET_STRUCTS_H + +struct target_ipc_perm { + abi_int __key; + abi_int uid; + abi_int gid; + abi_int cuid; + abi_int cgid; + abi_ushort mode; + abi_ushort __pad1; + abi_ushort __seq; +}; + +struct target_shmid_ds { + struct target_ipc_perm shm_perm; + abi_long shm_segsz; + abi_ulong shm_atime; + abi_ulong shm_dtime; + abi_ulong shm_ctime; + abi_int shm_cpid; + abi_int shm_lpid; + abi_ulong shm_nattch; +}; + +#endif diff --git a/linux-user/hexagon/target_syscall.h b/linux-user/hexagon/target_syscall.h new file mode 100644 index 0000000..68f8baa --- /dev/null +++ b/linux-user/hexagon/target_syscall.h @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_SYSCALL_H +#define HEXAGON_TARGET_SYSCALL_H + +struct target_pt_regs { + abi_long sepc; + abi_long sp; +}; + +#define UNAME_MACHINE "hexagon" +#define UNAME_MINIMUM_RELEASE "4.15.0" + +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 + +#define TARGET_MCL_CURRENT 1 +#define TARGET_MCL_FUTURE 2 +#define TARGET_MCL_ONFAULT 4 + +#endif diff --git a/linux-user/hexagon/termbits.h b/linux-user/hexagon/termbits.h new file mode 100644 index 0000000..c5f92f1 --- /dev/null +++ b/linux-user/hexagon/termbits.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../i386/termbits.h" diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 534753c..7445147 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -742,6 +742,8 @@ static inline int regpairs_aligned(void *cpu_env, int num) } #elif defined(TARGET_XTENSA) static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } +#elif defined(TARGET_HEXAGON) +static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } #else static inline int regpairs_aligned(void *cpu_env, int num) { return 0; } #endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index cabbfb7..e318d51 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -104,6 +104,14 @@ #define TARGET_IOC_WRITE 2U #define TARGET_IOC_READ 1U +#elif defined(TARGET_HEXAGON) + +#define TARGET_IOC_SIZEBITS 14 + +#define TARGET_IOC_NONE 0U +#define TARGET_IOC_WRITE 1U +#define TARGET_IOC_READ 2U + #else #error unsupported CPU #endif @@ -2220,6 +2228,31 @@ struct target_stat64 { uint64_t st_ino; }; +#elif defined(TARGET_HEXAGON) + +struct target_stat { + unsigned long long st_dev; + unsigned long long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long long st_rdev; + target_ulong __pad1; + long long st_size; + target_long st_blksize; + int __pad2; + long long st_blocks; + + target_long target_st_atime; + target_long target_st_atime_nsec; + target_long target_st_mtime; + target_long target_st_mtime_nsec; + target_long target_st_ctime; + target_long target_st_ctime_nsec; + int __unused[2]; +}; + #else #error unsupported CPU #endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index bf8c1bd..46b899f 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1485,6 +1485,22 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, #endif /* TARGET_XTENSA */ +#ifdef TARGET_HEXAGON + +#define ELF_START_MMAP 0x20000000 + +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_HEXAGON + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + regs->sepc = infop->entry; + regs->sp = infop->start_stack; +} + +#endif /* TARGET_HEXAGON */ + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c new file mode 100644 index 0000000..f40a844 --- /dev/null +++ b/linux-user/hexagon/cpu_loop.c @@ -0,0 +1,99 @@ +/* + * qemu user cpu loop + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "cpu_loop-common.h" +#include "internal.h" + +void cpu_loop(CPUHexagonState *env) +{ + CPUState *cs = CPU(hexagon_env_get_cpu(env)); + int trapnr, signum, sigcode; + target_ulong sigaddr; + target_ulong syscallnum; + target_ulong ret; + + for (;;) { + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + signum = 0; + sigcode = 0; + sigaddr = 0; + + switch (trapnr) { + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case HEX_EXCP_TRAP0: + syscallnum = env->gpr[6]; + env->gpr[HEX_REG_PC] += 4; + ret = do_syscall(env, + syscallnum, + env->gpr[0], + env->gpr[1], + env->gpr[2], + env->gpr[3], + env->gpr[4], + env->gpr[5], + 0, 0); + if (ret == -TARGET_ERESTARTSYS) { + env->gpr[HEX_REG_PC] -= 4; + } else if (ret != -TARGET_QEMU_ESIGRETURN) { + env->gpr[0] = ret; + } + break; + case HEX_EXCP_FETCH_NO_UPAGE: + case HEX_EXCP_PRIV_NO_UREAD: + case HEX_EXCP_PRIV_NO_UWRITE: + signum = TARGET_SIGSEGV; + sigcode = TARGET_SEGV_MAPERR; + break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; + default: + EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n", + trapnr); + exit(EXIT_FAILURE); + } + + if (signum) { + target_siginfo_t info = { + .si_signo = signum, + .si_errno = 0, + .si_code = sigcode, + ._sifields._sigfault._addr = sigaddr + }; + queue_signal(env, info.si_signo, QEMU_SI_KILL, &info); + } + + process_pending_signals(env); + } +} + +void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) +{ + env->gpr[HEX_REG_PC] = regs->sepc; + env->gpr[HEX_REG_SP] = regs->sp; +} diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c new file mode 100644 index 0000000..99837e1 --- /dev/null +++ b/linux-user/hexagon/signal.c @@ -0,0 +1,276 @@ +/* + * Emulation of Linux signals + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright(c) 2019-2020 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "qemu/osdep.h" +#include "qemu.h" +#include "signal-common.h" +#include "linux-user/trace.h" + +struct target_sigcontext { + target_ulong r0, r1, r2, r3; + target_ulong r4, r5, r6, r7; + target_ulong r8, r9, r10, r11; + target_ulong r12, r13, r14, r15; + target_ulong r16, r17, r18, r19; + target_ulong r20, r21, r22, r23; + target_ulong r24, r25, r26, r27; + target_ulong r28, r29, r30, r31; + target_ulong sa0; + target_ulong lc0; + target_ulong sa1; + target_ulong lc1; + target_ulong m0; + target_ulong m1; + target_ulong usr; + target_ulong p3_0; + target_ulong gp; + target_ulong ugp; + target_ulong pc; + target_ulong cause; + target_ulong badva; + target_ulong pad1; + target_ulong pad2; + target_ulong pad3; +}; + +struct target_ucontext { + unsigned long uc_flags; + target_ulong uc_link; /* target pointer */ + target_stack_t uc_stack; + struct target_sigcontext uc_mcontext; + target_sigset_t uc_sigmask; +}; + +struct target_rt_sigframe { + uint32_t tramp[2]; + struct target_siginfo info; + struct target_ucontext uc; +}; + +static abi_ulong get_sigframe(struct target_sigaction *ka, + CPUHexagonState *regs, size_t framesize) +{ + abi_ulong sp = get_sp_from_cpustate(regs); + + /* This is the X/Open sanctioned signal stack switching. */ + sp = target_sigsp(sp, ka) - framesize; + + sp = QEMU_ALIGN_DOWN(sp, 8); + + return sp; +} + +static void setup_sigcontext(struct target_sigcontext *sc, CPUHexagonState *env) +{ + __put_user(env->gpr[HEX_REG_R00], &sc->r0); + __put_user(env->gpr[HEX_REG_R01], &sc->r1); + __put_user(env->gpr[HEX_REG_R02], &sc->r2); + __put_user(env->gpr[HEX_REG_R03], &sc->r3); + __put_user(env->gpr[HEX_REG_R04], &sc->r4); + __put_user(env->gpr[HEX_REG_R05], &sc->r5); + __put_user(env->gpr[HEX_REG_R06], &sc->r6); + __put_user(env->gpr[HEX_REG_R07], &sc->r7); + __put_user(env->gpr[HEX_REG_R08], &sc->r8); + __put_user(env->gpr[HEX_REG_R09], &sc->r9); + __put_user(env->gpr[HEX_REG_R10], &sc->r10); + __put_user(env->gpr[HEX_REG_R11], &sc->r11); + __put_user(env->gpr[HEX_REG_R12], &sc->r12); + __put_user(env->gpr[HEX_REG_R13], &sc->r13); + __put_user(env->gpr[HEX_REG_R14], &sc->r14); + __put_user(env->gpr[HEX_REG_R15], &sc->r15); + __put_user(env->gpr[HEX_REG_R16], &sc->r16); + __put_user(env->gpr[HEX_REG_R17], &sc->r17); + __put_user(env->gpr[HEX_REG_R18], &sc->r18); + __put_user(env->gpr[HEX_REG_R19], &sc->r19); + __put_user(env->gpr[HEX_REG_R20], &sc->r20); + __put_user(env->gpr[HEX_REG_R21], &sc->r21); + __put_user(env->gpr[HEX_REG_R22], &sc->r22); + __put_user(env->gpr[HEX_REG_R23], &sc->r23); + __put_user(env->gpr[HEX_REG_R24], &sc->r24); + __put_user(env->gpr[HEX_REG_R25], &sc->r25); + __put_user(env->gpr[HEX_REG_R26], &sc->r26); + __put_user(env->gpr[HEX_REG_R27], &sc->r27); + __put_user(env->gpr[HEX_REG_R28], &sc->r28); + __put_user(env->gpr[HEX_REG_R29], &sc->r29); + __put_user(env->gpr[HEX_REG_R30], &sc->r30); + __put_user(env->gpr[HEX_REG_R31], &sc->r31); + __put_user(env->gpr[HEX_REG_SA0], &sc->sa0); + __put_user(env->gpr[HEX_REG_LC0], &sc->lc0); + __put_user(env->gpr[HEX_REG_SA1], &sc->sa1); + __put_user(env->gpr[HEX_REG_LC1], &sc->lc1); + __put_user(env->gpr[HEX_REG_M0], &sc->m0); + __put_user(env->gpr[HEX_REG_M1], &sc->m1); + __put_user(env->gpr[HEX_REG_USR], &sc->usr); + __put_user(env->gpr[HEX_REG_P3_0], &sc->p3_0); + __put_user(env->gpr[HEX_REG_GP], &sc->gp); + __put_user(env->gpr[HEX_REG_UGP], &sc->ugp); + __put_user(env->gpr[HEX_REG_PC], &sc->pc); +} + +static void setup_ucontext(struct target_ucontext *uc, + CPUHexagonState *env, target_sigset_t *set) +{ + __put_user(0, &(uc->uc_flags)); + __put_user(0, &(uc->uc_link)); + + target_save_altstack(&uc->uc_stack, env); + + int i; + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __put_user(set->sig[i], &(uc->uc_sigmask.sig[i])); + } + + setup_sigcontext(&uc->uc_mcontext, env); +} + +static inline void install_sigtramp(uint32_t *tramp) +{ + __put_user(0x7800d166, tramp + 0); /* { r6=#__NR_rt_sigreturn } */ + __put_user(0x5400c004, tramp + 1); /* { trap0(#1) } */ +} + +void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUHexagonState *env) +{ + abi_ulong frame_addr; + struct target_rt_sigframe *frame; + + frame_addr = get_sigframe(ka, env, sizeof(*frame)); + trace_user_setup_rt_frame(env, frame_addr); + + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto badframe; + } + + setup_ucontext(&frame->uc, env, set); + tswap_siginfo(&frame->info, info); + install_sigtramp(frame->tramp); + + env->gpr[HEX_REG_PC] = ka->_sa_handler; + env->gpr[HEX_REG_SP] = frame_addr; + env->gpr[HEX_REG_R00] = sig; + env->gpr[HEX_REG_R01] = + frame_addr + offsetof(struct target_rt_sigframe, info); + env->gpr[HEX_REG_R02] = + frame_addr + offsetof(struct target_rt_sigframe, uc); + env->gpr[HEX_REG_LR] = + frame_addr + offsetof(struct target_rt_sigframe, tramp); + + return; + +badframe: + unlock_user_struct(frame, frame_addr, 1); + if (sig == TARGET_SIGSEGV) { + ka->_sa_handler = TARGET_SIG_DFL; + } + force_sig(TARGET_SIGSEGV); +} + +static void restore_sigcontext(CPUHexagonState *env, + struct target_sigcontext *sc) +{ + __get_user(env->gpr[HEX_REG_R00], &sc->r0); + __get_user(env->gpr[HEX_REG_R01], &sc->r1); + __get_user(env->gpr[HEX_REG_R02], &sc->r2); + __get_user(env->gpr[HEX_REG_R03], &sc->r3); + __get_user(env->gpr[HEX_REG_R04], &sc->r4); + __get_user(env->gpr[HEX_REG_R05], &sc->r5); + __get_user(env->gpr[HEX_REG_R06], &sc->r6); + __get_user(env->gpr[HEX_REG_R07], &sc->r7); + __get_user(env->gpr[HEX_REG_R08], &sc->r8); + __get_user(env->gpr[HEX_REG_R09], &sc->r9); + __get_user(env->gpr[HEX_REG_R10], &sc->r10); + __get_user(env->gpr[HEX_REG_R11], &sc->r11); + __get_user(env->gpr[HEX_REG_R12], &sc->r12); + __get_user(env->gpr[HEX_REG_R13], &sc->r13); + __get_user(env->gpr[HEX_REG_R14], &sc->r14); + __get_user(env->gpr[HEX_REG_R15], &sc->r15); + __get_user(env->gpr[HEX_REG_R16], &sc->r16); + __get_user(env->gpr[HEX_REG_R17], &sc->r17); + __get_user(env->gpr[HEX_REG_R18], &sc->r18); + __get_user(env->gpr[HEX_REG_R19], &sc->r19); + __get_user(env->gpr[HEX_REG_R20], &sc->r20); + __get_user(env->gpr[HEX_REG_R21], &sc->r21); + __get_user(env->gpr[HEX_REG_R22], &sc->r22); + __get_user(env->gpr[HEX_REG_R23], &sc->r23); + __get_user(env->gpr[HEX_REG_R24], &sc->r24); + __get_user(env->gpr[HEX_REG_R25], &sc->r25); + __get_user(env->gpr[HEX_REG_R26], &sc->r26); + __get_user(env->gpr[HEX_REG_R27], &sc->r27); + __get_user(env->gpr[HEX_REG_R28], &sc->r28); + __get_user(env->gpr[HEX_REG_R29], &sc->r29); + __get_user(env->gpr[HEX_REG_R30], &sc->r30); + __get_user(env->gpr[HEX_REG_R31], &sc->r31); + __get_user(env->gpr[HEX_REG_SA0], &sc->sa0); + __get_user(env->gpr[HEX_REG_LC0], &sc->lc0); + __get_user(env->gpr[HEX_REG_SA1], &sc->sa1); + __get_user(env->gpr[HEX_REG_LC1], &sc->lc1); + __get_user(env->gpr[HEX_REG_M0], &sc->m0); + __get_user(env->gpr[HEX_REG_M1], &sc->m1); + __get_user(env->gpr[HEX_REG_USR], &sc->usr); + __get_user(env->gpr[HEX_REG_P3_0], &sc->p3_0); + __get_user(env->gpr[HEX_REG_GP], &sc->gp); + __get_user(env->gpr[HEX_REG_UGP], &sc->ugp); + __get_user(env->gpr[HEX_REG_PC], &sc->pc); +} + +static void restore_ucontext(CPUHexagonState *env, struct target_ucontext *uc) +{ + sigset_t blocked; + target_sigset_t target_set; + int i; + + target_sigemptyset(&target_set); + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __get_user(target_set.sig[i], &(uc->uc_sigmask.sig[i])); + } + + target_to_host_sigset_internal(&blocked, &target_set); + set_sigmask(&blocked); + + restore_sigcontext(env, &uc->uc_mcontext); +} + +long do_rt_sigreturn(CPUHexagonState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr; + + frame_addr = env->gpr[HEX_REG_SP]; + trace_user_do_sigreturn(env, frame_addr); + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + + restore_ucontext(env, &frame->uc); + + if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, + uc.uc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) { + goto badframe; + } + + unlock_user_struct(frame, frame_addr, 0); + return -TARGET_QEMU_ESIGRETURN; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} diff --git a/scripts/gensyscalls.sh b/scripts/gensyscalls.sh index bba9fb0..8fb450e 100755 --- a/scripts/gensyscalls.sh +++ b/scripts/gensyscalls.sh @@ -98,4 +98,5 @@ generate_syscall_nr openrisc 32 "$output/linux-user/openrisc/syscall_nr.h" generate_syscall_nr riscv 32 "$output/linux-user/riscv/syscall32_nr.h" generate_syscall_nr riscv 64 "$output/linux-user/riscv/syscall64_nr.h" +generate_syscall_nr hexagon 32 "$output/linux-user/hexagon/syscall_nr.h" rm -fr "$TMP"