From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224155; cv=none; d=zohomail.com; s=zohoarc; b=cYtKsM6HIlRtLNGgR4UJudwmmetReqnOOYsWBA03FqmxVzgIa1vB/MaSbn7fSJde46WM4lpjjLtxZ1jqacVeYgU3YRm9XPlzcL863VOFLkHH6X87YgEjS9/hcNm1Krzx09z7xgZ+D6Fp1fcO9EmxzMYQGTRiD67SZUiPL5GLVW4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224155; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0RhnNilE/Y4fcreluTj/jcfMvebQt1jjc4i40G3c3mY=; b=a5kK6A9hXK2lKdUMWeaqWxOFtYZ1RlFV3IaVtY3O8CL1jzybHfDygNno5OkIqukYRfyqQ2/Pdp1oeLVjmPIECJAtr57pN2FDajhJfD46tGsJoJHtiiBnH6VpqZBRojwBIcDW8u2dK2S0TJC2lsJ4vYzXu82IPU5XlaVlovgrGpA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224155919455.91767251954695; Fri, 16 Dec 2022 12:55:55 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He2-0002n7-4q; Fri, 16 Dec 2022 15:49:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He0-0002lO-0n for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:24 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004Ou-La for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:23 -0500 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKlKs2018881; Fri, 16 Dec 2022 20:49:14 GMT Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg8e6bpq5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA02.qualcomm.com [127.0.0.1]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKii2t006136; Fri, 16 Dec 2022 20:49:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 3mgard52nf-1; Fri, 16 Dec 2022 20:49:13 +0000 Received: from NALASPPMTA02.qualcomm.com (NALASPPMTA02.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgZmi004345; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 2BGKnCwU011998; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id D90745000A8; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=0RhnNilE/Y4fcreluTj/jcfMvebQt1jjc4i40G3c3mY=; b=RZ/gCliWiINk0F2GSqV2BYDZZcP7LDN3opNMy6MF5OcyG7cZc5OJIDkp95EuzQ7+8oek 8UPwrYEYt2RLjX2QB2+0YD6LGd/LH18ppt86KyuRscR7V8l5Hnkev8rVk28onPHT4Zax ynIxA/+ohjEnYKhtgbiMitaZde6eiD8B4Qy6eqLJ5vSiMWefX/VfN/h7gO65CEZFKEEJ bStHg7gFrJDSW5DLKIvdHXpoCKAcndVZpjfEoAVIO34+jdEGFy6mm+OLOascASXPn55h Qj9kHXseitO97hkOwLLr4Sdqfx87qBopa7aP6IDpts2/RRqE+8KFn99kvv7d6CLBouXj PQ== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 01/21] Hexagon (target/hexagon) Add pkt and insn to DisasContext Date: Fri, 16 Dec 2022 12:48:25 -0800 Message-Id: <20221216204845.19290-2-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 6QIXklD9TOOVilpN-TMRhVMpFVZkf-06 X-Proofpoint-ORIG-GUID: 6QIXklD9TOOVilpN-TMRhVMpFVZkf-06 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=368 priorityscore=1501 lowpriorityscore=0 spamscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxscore=0 adultscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224157961100003 This enables us to reduce the number of parameters to many functions In particular, the generated functions previously took all 3 as arguments Not only does this simplify the code, it improves the translation time Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-2-tsimpson@quicinc.com> --- target/hexagon/gen_tcg_hvx.h | 6 +- target/hexagon/insn.h | 7 +- target/hexagon/macros.h | 10 +-- target/hexagon/mmvec/macros.h | 4 +- target/hexagon/translate.h | 9 ++- target/hexagon/genptr.c | 6 +- target/hexagon/translate.c | 120 +++++++++++++++++--------------- target/hexagon/gen_tcg_funcs.py | 15 ++-- 8 files changed, 89 insertions(+), 88 deletions(-) diff --git a/target/hexagon/gen_tcg_hvx.h b/target/hexagon/gen_tcg_hvx.h index cdcc9382bb..083f4d92c6 100644 --- a/target/hexagon/gen_tcg_hvx.h +++ b/target/hexagon/gen_tcg_hvx.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. * * 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 @@ -697,7 +697,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx) #define fGEN_TCG_NEWVAL_VEC_STORE(GET_EA, INC) \ do { \ GET_EA; \ - gen_vreg_store(ctx, insn, pkt, EA, OsN_off, insn->slot, true); \ + gen_vreg_store(ctx, EA, OsN_off, insn->slot, true); \ INC; \ } while (0) =20 @@ -736,7 +736,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx) PRED; \ tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, false_label); \ tcg_temp_free(LSB); \ - gen_vreg_store(ctx, insn, pkt, EA, SRCOFF, insn->slot, ALIGN); \ + gen_vreg_store(ctx, EA, SRCOFF, insn->slot, ALIGN); \ INC; \ tcg_gen_br(end_label); \ gen_set_label(false_label); \ diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h index aa26389147..cb92586802 100644 --- a/target/hexagon/insn.h +++ b/target/hexagon/insn.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. * * 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 @@ -28,10 +28,7 @@ struct Instruction; struct Packet; struct DisasContext; =20 -typedef void (*SemanticInsn)(CPUHexagonState *env, - struct DisasContext *ctx, - struct Instruction *insn, - struct Packet *pkt); +typedef void (*SemanticInsn)(struct DisasContext *ctx); =20 struct Instruction { SemanticInsn generate; /* pointer to genptr routine */ diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index c8805bdaeb..93ee4739a1 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -94,9 +94,9 @@ */ #define CHECK_NOSHUF(VA, SIZE) \ do { \ - if (insn->slot =3D=3D 0 && pkt->pkt_has_store_s1) { \ + if (insn->slot =3D=3D 0 && ctx->pkt->pkt_has_store_s1) { \ probe_noshuf_load(VA, SIZE, ctx->mem_idx); \ - process_store(ctx, pkt, 1); \ + process_store(ctx, 1); \ } \ } while (0) =20 @@ -105,12 +105,12 @@ TCGLabel *label =3D gen_new_label(); \ tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, label); \ GET_EA; \ - if (insn->slot =3D=3D 0 && pkt->pkt_has_store_s1) { \ + if (insn->slot =3D=3D 0 && ctx->pkt->pkt_has_store_s1) { \ probe_noshuf_load(EA, SIZE, ctx->mem_idx); \ } \ gen_set_label(label); \ - if (insn->slot =3D=3D 0 && pkt->pkt_has_store_s1) { \ - process_store(ctx, pkt, 1); \ + if (insn->slot =3D=3D 0 && ctx->pkt->pkt_has_store_s1) { \ + process_store(ctx, 1); \ } \ } while (0) =20 diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h index 8345753580..8c864e8c68 100644 --- a/target/hexagon/mmvec/macros.h +++ b/target/hexagon/mmvec/macros.h @@ -288,7 +288,7 @@ #endif #ifdef QEMU_GENERATE #define fSTOREMMV(EA, SRC) \ - gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, true) + gen_vreg_store(ctx, EA, SRC##_off, insn->slot, true) #endif #ifdef QEMU_GENERATE #define fSTOREMMVQ(EA, SRC, MASK) \ @@ -300,7 +300,7 @@ #endif #ifdef QEMU_GENERATE #define fSTOREMMVU(EA, SRC) \ - gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, false) + gen_vreg_store(ctx, EA, SRC##_off, insn->slot, false) #endif #define fVFOREACH(WIDTH, VAR) for (VAR =3D 0; VAR < fVELEM(WIDTH); VAR++) #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \ diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index a245172827..115e29b84f 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. * * 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 @@ -23,10 +23,13 @@ #include "cpu.h" #include "exec/translator.h" #include "tcg/tcg-op.h" +#include "insn.h" #include "internal.h" =20 typedef struct DisasContext { DisasContextBase base; + Packet *pkt; + Insn *insn; uint32_t mem_idx; uint32_t num_packets; uint32_t num_insns; @@ -147,6 +150,6 @@ extern TCGv hex_vstore_addr[VSTORES_MAX]; extern TCGv hex_vstore_size[VSTORES_MAX]; extern TCGv hex_vstore_pending[VSTORES_MAX]; =20 -bool is_gather_store_insn(Insn *insn, Packet *pkt); -void process_store(DisasContext *ctx, Packet *pkt, int slot_num); +bool is_gather_store_insn(DisasContext *ctx); +void process_store(DisasContext *ctx, int slot_num); #endif diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 806d0974ff..85416dd530 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -551,13 +551,13 @@ static void gen_vreg_load(DisasContext *ctx, intptr_t= dstoff, TCGv src, tcg_temp_free_i64(tmp); } =20 -static void gen_vreg_store(DisasContext *ctx, Insn *insn, Packet *pkt, - TCGv EA, intptr_t srcoff, int slot, bool aligne= d) +static void gen_vreg_store(DisasContext *ctx, TCGv EA, intptr_t srcoff, + int slot, bool aligned) { intptr_t dstoff =3D offsetof(CPUHexagonState, vstore[slot].data); intptr_t maskoff =3D offsetof(CPUHexagonState, vstore[slot].mask); =20 - if (is_gather_store_insn(insn, pkt)) { + if (is_gather_store_insn(ctx)) { TCGv sl =3D tcg_constant_tl(slot); gen_helper_gather_store(cpu_env, EA, sl); return; diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 2329177537..0940d0f2c1 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -209,8 +209,9 @@ static bool need_pred_written(Packet *pkt) return check_for_attrib(pkt, A_WRITES_PRED_REG); } =20 -static void gen_start_packet(DisasContext *ctx, Packet *pkt) +static void gen_start_packet(DisasContext *ctx) { + Packet *pkt =3D ctx->pkt; target_ulong next_PC =3D ctx->base.pc_next + pkt->encod_pkt_size_in_by= tes; int i; =20 @@ -260,8 +261,10 @@ static void gen_start_packet(DisasContext *ctx, Packet= *pkt) } } =20 -bool is_gather_store_insn(Insn *insn, Packet *pkt) +bool is_gather_store_insn(DisasContext *ctx) { + Packet *pkt =3D ctx->pkt; + Insn *insn =3D ctx->insn; if (GET_ATTRIB(insn->opcode, A_CVI_NEW) && insn->new_value_producer_slot =3D=3D 1) { /* Look for gather instruction */ @@ -280,15 +283,15 @@ bool is_gather_store_insn(Insn *insn, Packet *pkt) * However, there are some implicit writes marked as attributes * of the applicable instructions. */ -static void mark_implicit_reg_write(DisasContext *ctx, Insn *insn, - int attrib, int rnum) +static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnu= m) { - if (GET_ATTRIB(insn->opcode, attrib)) { + uint16_t opcode =3D ctx->insn->opcode; + if (GET_ATTRIB(opcode, attrib)) { /* * USR is used to set overflow and FP exceptions, * so treat it as conditional */ - bool is_predicated =3D GET_ATTRIB(insn->opcode, A_CONDEXEC) || + bool is_predicated =3D GET_ATTRIB(opcode, A_CONDEXEC) || rnum =3D=3D HEX_REG_USR; if (is_predicated && !is_preloaded(ctx, rnum)) { tcg_gen_mov_tl(hex_new_value[rnum], hex_gpr[rnum]); @@ -298,39 +301,38 @@ static void mark_implicit_reg_write(DisasContext *ctx= , Insn *insn, } } =20 -static void mark_implicit_pred_write(DisasContext *ctx, Insn *insn, - int attrib, int pnum) +static void mark_implicit_pred_write(DisasContext *ctx, int attrib, int pn= um) { - if (GET_ATTRIB(insn->opcode, attrib)) { + if (GET_ATTRIB(ctx->insn->opcode, attrib)) { ctx_log_pred_write(ctx, pnum); } } =20 -static void mark_implicit_reg_writes(DisasContext *ctx, Insn *insn) +static void mark_implicit_reg_writes(DisasContext *ctx) { - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_FP, HEX_REG_FP); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SP, HEX_REG_SP); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LR, HEX_REG_LR); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC0, HEX_REG_LC0); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1); - mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_USR, HEX_REG_USR); - mark_implicit_reg_write(ctx, insn, A_FPOP, HEX_REG_USR); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_FP, HEX_REG_FP); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SP, HEX_REG_SP); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LR, HEX_REG_LR); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC0, HEX_REG_LC0); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1); + mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_USR, HEX_REG_USR); + mark_implicit_reg_write(ctx, A_FPOP, HEX_REG_USR); } =20 -static void mark_implicit_pred_writes(DisasContext *ctx, Insn *insn) +static void mark_implicit_pred_writes(DisasContext *ctx) { - mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P0, 0); - mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P1, 1); - mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P2, 2); - mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P3, 3); + mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P0, 0); + mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P1, 1); + mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P2, 2); + mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P3, 3); } =20 -static void mark_store_width(DisasContext *ctx, Insn *insn) +static void mark_store_width(DisasContext *ctx) { - uint16_t opcode =3D insn->opcode; - uint32_t slot =3D insn->slot; + uint16_t opcode =3D ctx->insn->opcode; + uint32_t slot =3D ctx->insn->slot; uint8_t width =3D 0; =20 if (GET_ATTRIB(opcode, A_SCALAR_STORE)) { @@ -351,14 +353,13 @@ static void mark_store_width(DisasContext *ctx, Insn = *insn) } } =20 -static void gen_insn(CPUHexagonState *env, DisasContext *ctx, - Insn *insn, Packet *pkt) +static void gen_insn(DisasContext *ctx) { - if (insn->generate) { - mark_implicit_reg_writes(ctx, insn); - insn->generate(env, ctx, insn, pkt); - mark_implicit_pred_writes(ctx, insn); - mark_store_width(ctx, insn); + if (ctx->insn->generate) { + mark_implicit_reg_writes(ctx); + ctx->insn->generate(ctx); + mark_implicit_pred_writes(ctx); + mark_store_width(ctx); } else { gen_exception_end_tb(ctx, HEX_EXCP_INVALID_OPCODE); } @@ -378,7 +379,7 @@ static void gen_reg_writes(DisasContext *ctx) } } =20 -static void gen_pred_writes(DisasContext *ctx, Packet *pkt) +static void gen_pred_writes(DisasContext *ctx) { int i; =20 @@ -393,7 +394,7 @@ static void gen_pred_writes(DisasContext *ctx, Packet *= pkt) * instructions, we can use the non-conditional * write of the predicates. */ - if (pkt->pkt_has_endloop) { + if (ctx->pkt->pkt_has_endloop) { TCGv zero =3D tcg_constant_tl(0); TCGv pred_written =3D tcg_temp_new(); for (i =3D 0; i < ctx->preg_log_idx; i++) { @@ -439,9 +440,9 @@ static bool slot_is_predicated(Packet *pkt, int slot_nu= m) g_assert_not_reached(); } =20 -void process_store(DisasContext *ctx, Packet *pkt, int slot_num) +void process_store(DisasContext *ctx, int slot_num) { - bool is_predicated =3D slot_is_predicated(pkt, slot_num); + bool is_predicated =3D slot_is_predicated(ctx->pkt, slot_num); TCGLabel *label_end =3D NULL; =20 /* @@ -517,27 +518,28 @@ void process_store(DisasContext *ctx, Packet *pkt, in= t slot_num) } } =20 -static void process_store_log(DisasContext *ctx, Packet *pkt) +static void process_store_log(DisasContext *ctx) { /* * When a packet has two stores, the hardware processes * slot 1 and then slot 0. This will be important when * the memory accesses overlap. */ + Packet *pkt =3D ctx->pkt; if (pkt->pkt_has_store_s1) { g_assert(!pkt->pkt_has_dczeroa); - process_store(ctx, pkt, 1); + process_store(ctx, 1); } if (pkt->pkt_has_store_s0) { g_assert(!pkt->pkt_has_dczeroa); - process_store(ctx, pkt, 0); + process_store(ctx, 0); } } =20 /* Zero out a 32-bit cache line */ -static void process_dczeroa(DisasContext *ctx, Packet *pkt) +static void process_dczeroa(DisasContext *ctx) { - if (pkt->pkt_has_dczeroa) { + if (ctx->pkt->pkt_has_dczeroa) { /* Store 32 bytes of zero starting at (addr & ~0x1f) */ TCGv addr =3D tcg_temp_new(); TCGv_i64 zero =3D tcg_constant_i64(0); @@ -567,7 +569,7 @@ static bool pkt_has_hvx_store(Packet *pkt) return false; } =20 -static void gen_commit_hvx(DisasContext *ctx, Packet *pkt) +static void gen_commit_hvx(DisasContext *ctx) { int i; =20 @@ -637,13 +639,14 @@ static void gen_commit_hvx(DisasContext *ctx, Packet = *pkt) } } =20 - if (pkt_has_hvx_store(pkt)) { + if (pkt_has_hvx_store(ctx->pkt)) { gen_helper_commit_hvx_stores(cpu_env); } } =20 -static void update_exec_counters(DisasContext *ctx, Packet *pkt) +static void update_exec_counters(DisasContext *ctx) { + Packet *pkt =3D ctx->pkt; int num_insns =3D pkt->num_insns; int num_real_insns =3D 0; int num_hvx_insns =3D 0; @@ -664,8 +667,7 @@ static void update_exec_counters(DisasContext *ctx, Pac= ket *pkt) ctx->num_hvx_insns +=3D num_hvx_insns; } =20 -static void gen_commit_packet(CPUHexagonState *env, DisasContext *ctx, - Packet *pkt) +static void gen_commit_packet(DisasContext *ctx) { /* * If there is more than one store in a packet, make sure they are all= OK @@ -684,6 +686,7 @@ static void gen_commit_packet(CPUHexagonState *env, Dis= asContext *ctx, * store. Therefore, we call process_store_log before anything else * involved in committing the packet. */ + Packet *pkt =3D ctx->pkt; bool has_store_s0 =3D pkt->pkt_has_store_s0; bool has_store_s1 =3D (pkt->pkt_has_store_s1 && !ctx->s1_store_process= ed); bool has_hvx_store =3D pkt_has_hvx_store(pkt); @@ -693,7 +696,7 @@ static void gen_commit_packet(CPUHexagonState *env, Dis= asContext *ctx, * a store in slot 1 or an HVX store. */ g_assert(!has_store_s1 && !has_hvx_store); - process_dczeroa(ctx, pkt); + process_dczeroa(ctx); } else if (has_hvx_store) { TCGv mem_idx =3D tcg_constant_tl(ctx->mem_idx); =20 @@ -724,14 +727,14 @@ static void gen_commit_packet(CPUHexagonState *env, D= isasContext *ctx, gen_helper_probe_pkt_scalar_store_s0(cpu_env, mem_idx); } =20 - process_store_log(ctx, pkt); + process_store_log(ctx); =20 gen_reg_writes(ctx); - gen_pred_writes(ctx, pkt); + gen_pred_writes(ctx); if (pkt->pkt_has_hvx) { - gen_commit_hvx(ctx, pkt); + gen_commit_hvx(ctx); } - update_exec_counters(ctx, pkt); + update_exec_counters(ctx); if (HEX_DEBUG) { TCGv has_st0 =3D tcg_constant_tl(pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa= ); @@ -744,7 +747,8 @@ static void gen_commit_packet(CPUHexagonState *env, Dis= asContext *ctx, =20 if (pkt->vhist_insn !=3D NULL) { ctx->pre_commit =3D false; - pkt->vhist_insn->generate(env, ctx, pkt->vhist_insn, pkt); + ctx->insn =3D pkt->vhist_insn; + pkt->vhist_insn->generate(ctx); } =20 if (pkt->pkt_has_cof) { @@ -767,11 +771,13 @@ static void decode_and_translate_packet(CPUHexagonSta= te *env, DisasContext *ctx) =20 if (decode_packet(nwords, words, &pkt, false) > 0) { HEX_DEBUG_PRINT_PKT(&pkt); - gen_start_packet(ctx, &pkt); + ctx->pkt =3D &pkt; + gen_start_packet(ctx); for (i =3D 0; i < pkt.num_insns; i++) { - gen_insn(env, ctx, &pkt.insn[i], &pkt); + ctx->insn =3D &pkt.insn[i]; + gen_insn(ctx); } - gen_commit_packet(env, ctx, &pkt); + gen_commit_packet(ctx); ctx->base.pc_next +=3D pkt.encod_pkt_size_in_bytes; } else { gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET); diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index 6dea02b0b9..02a6565685 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -561,11 +561,7 @@ def genptr_dst_write_opn(f,regtype, regid, tag): ## Generate the TCG code to call the helper ## For A2_add: Rd32=3Dadd(Rs32,Rt32), { RdV=3DRsV+RtV;} ## We produce: -## static void generate_A2_add() -## CPUHexagonState *env -## DisasContext *ctx, -## Insn *insn, -## Packet *pkt) +## static void generate_A2_add(DisasContext *ctx) ## { ## TCGv RdV =3D tcg_temp_local_new(); ## const int RdN =3D insn->regno[0]; @@ -584,12 +580,11 @@ def genptr_dst_write_opn(f,regtype, regid, tag): ## is gen_helper_A2_add(RdV, cpu_env, RsV, RtV); ## def gen_tcg_func(f, tag, regs, imms): - f.write("static void generate_%s(\n" %tag) - f.write(" CPUHexagonState *env,\n") - f.write(" DisasContext *ctx,\n") - f.write(" Insn *insn,\n") - f.write(" Packet *pkt)\n") + f.write("static void generate_%s(DisasContext *ctx)\n" %tag) f.write('{\n') + + f.write(" Insn *insn __attribute__((unused)) =3D ctx->insn;\n") + if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag) i=3D0 ## Declare all the operands (regs and immediates) --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224634; cv=none; d=zohomail.com; s=zohoarc; b=E2Ql3SNa28ma7NJu8Am+ogZGBkgsUl6Hs8LDqIrhOB44qyaroNotDmK5Ubb3sav3MjAgYPQsbFbQ4Tp35ssR1KgiMR49JEPKdFIkkErlui4r2drQsNOh3uQ1kwJLI+cThWvaWOlyCEJXJkBRDmF8NXwulQGBf1skgty7sKqa9xM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224634; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DJz1mPXG682KSaV30XcjWSYc44MybFJA/jwGuiilIp8=; b=KWHhNAMqnXwg6uJL5IxerS6M9m7Sm1LTlhXzQYvWKaEFPduywBP670qSGRPJG9XjbJqrDVD0eYpwuJX+4gYYmk3cRIBYw0jpGDm2I2Dl5725/It5gOhs/gulhv+IdmL8awGgEEsPuXQlclFCdVob8RJc7S0xSF7SbT6d/GjVhJI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224634434974.5104001788354; Fri, 16 Dec 2022 13:03:54 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He2-0002nA-HA; Fri, 16 Dec 2022 15:49:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdy-0002ka-Js for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:22 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004Ox-MR for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:22 -0500 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGGlG8i005784; Fri, 16 Dec 2022 20:49:14 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg6y7v5sy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgMC0029916; Fri, 16 Dec 2022 20:49:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6a-1; Fri, 16 Dec 2022 20:49:13 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg1ki029697; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnCpp005662; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id DBE0F5000AE; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=DJz1mPXG682KSaV30XcjWSYc44MybFJA/jwGuiilIp8=; b=T/CvLFHaUAGAIZQJem5beme8a/C+U+Uz616RBdQsWWnjzUkJabYdBLsjItB26bNnP+dv uyYCYLDK7x1DS3Pp5Ox9o6fMLm3xEnBQpvBMc28ObQzDEzc256HsYLuuZ3oBNhSi1JfB 9T/asRrDlKJrSTtS7rtAWYle7QIWWR09p7iyOsN0L6HqbNNrwPJRGFbHtCgvW471/B5k rTMdft6GmbBYbh1wDm1/9Wg66/Fqu8EUEJ16JlwPw6hcYG6doIt3F0bWJD+0fVO4aah7 5fkGBJsc/P2Tk04TkHdqIFD90v+n4f8jb8PcZE2gTZxFOjYzua7gcS1aJEh2fEtEifpL rg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 02/21] Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur Date: Fri, 16 Dec 2022 12:48:26 -0800 Message-Id: <20221216204845.19290-3-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 6fWe9kMmjDfemkH1AGV_Ctv8itKRNWby X-Proofpoint-GUID: 6fWe9kMmjDfemkH1AGV_Ctv8itKRNWby X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 mlxlogscore=652 clxscore=1015 phishscore=0 suspectscore=0 spamscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224635069100001 Here are example instructions with a predicated .tmp/.cur assignment if (p1) v12.tmp =3D vmem(r7 + #0) if (p0) v12.cur =3D vmem(r9 + #0) The .tmp/.cur indicates that references to v12 in the same packet take the result of the load. However, when the predicate is false, the value at the start of the packet should be used. After the packet commits, the .tmp value is dropped, but the .cur value is maintained. To fix this bug, we preload the original value from the HVX register into the temporary used for the result. Test cases added to tests/tcg/hexagon/hvx_misc.c Acked-by: Richard Henderson Co-authored-by: Matheus Tavares Bernardino Signed-off-by: Matheus Tavares Bernardino Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-3-tsimpson@quicinc.com> --- target/hexagon/translate.h | 6 +++ tests/tcg/hexagon/hvx_misc.c | 72 +++++++++++++++++++++++++++++++++ target/hexagon/gen_tcg_funcs.py | 12 ++++++ 3 files changed, 90 insertions(+) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index 115e29b84f..b8fcf615e8 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -86,6 +86,12 @@ static inline bool is_preloaded(DisasContext *ctx, int n= um) return test_bit(num, ctx->regs_written); } =20 +static inline bool is_vreg_preloaded(DisasContext *ctx, int num) +{ + return test_bit(num, ctx->vregs_updated) || + test_bit(num, ctx->vregs_updated_tmp); +} + intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum, int num, bool alloc_ok); intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum, diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c index 6e2c9ab3cd..53d5c9b44f 100644 --- a/tests/tcg/hexagon/hvx_misc.c +++ b/tests/tcg/hexagon/hvx_misc.c @@ -541,6 +541,75 @@ static void test_vshuff(void) check_output_b(__LINE__, 1); } =20 +static void test_load_tmp_predicated(void) +{ + void *p0 =3D buffer0; + void *p1 =3D buffer1; + void *pout =3D output; + bool pred =3D true; + + for (int i =3D 0; i < BUFSIZE; i++) { + /* + * Load into v12 as .tmp with a predicate + * When the predicate is true, we get the vector from buffer1[i] + * When the predicate is false, we get a vector of all 1's + * Regardless of the predicate, the next packet should have + * a vector of all 1's + */ + asm("v3 =3D vmem(%0 + #0)\n\t" + "r1 =3D #1\n\t" + "v12 =3D vsplat(r1)\n\t" + "p1 =3D !cmp.eq(%3, #0)\n\t" + "{\n\t" + " if (p1) v12.tmp =3D vmem(%1 + #0)\n\t" + " v4.w =3D vadd(v12.w, v3.w)\n\t" + "}\n\t" + "v4.w =3D vadd(v4.w, v12.w)\n\t" + "vmem(%2 + #0) =3D v4\n\t" + : : "r"(p0), "r"(p1), "r"(pout), "r"(pred) + : "r1", "p1", "v12", "v3", "v4", "v6", "memory"); + p0 +=3D sizeof(MMVector); + p1 +=3D sizeof(MMVector); + pout +=3D sizeof(MMVector); + + for (int j =3D 0; j < MAX_VEC_SIZE_BYTES / 4; j++) { + expect[i].w[j] =3D + pred ? buffer0[i].w[j] + buffer1[i].w[j] + 1 + : buffer0[i].w[j] + 2; + } + pred =3D !pred; + } + + check_output_w(__LINE__, BUFSIZE); +} + +static void test_load_cur_predicated(void) +{ + bool pred =3D true; + for (int i =3D 0; i < BUFSIZE; i++) { + asm volatile("p0 =3D !cmp.eq(%3, #0)\n\t" + "v3 =3D vmem(%0+#0)\n\t" + /* + * Preload v4 to make sure that the assignment from t= he + * packet below is not being ignored when pred is fal= se. + */ + "r0 =3D #0x01237654\n\t" + "v4 =3D vsplat(r0)\n\t" + "{\n\t" + " if (p0) v3.cur =3D vmem(%1+#0)\n\t" + " v4 =3D v3\n\t" + "}\n\t" + "vmem(%2+#0) =3D v4\n\t" + : + : "r"(&buffer0[i]), "r"(&buffer1[i]), + "r"(&output[i]), "r"(pred) + : "r0", "p0", "v3", "v4", "memory"); + expect[i] =3D pred ? buffer1[i] : buffer0[i]; + pred =3D !pred; + } + check_output_w(__LINE__, BUFSIZE); +} + int main() { init_buffers(); @@ -578,6 +647,9 @@ int main() =20 test_vshuff(); =20 + test_load_tmp_predicated(); + test_load_cur_predicated(); + puts(err ? "FAIL" : "PASS"); return err ? 1 : 0; } diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index 02a6565685..ca5fde91cc 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -173,6 +173,18 @@ def genptr_decl(f, tag, regtype, regid, regno): f.write(" ctx_future_vreg_off(ctx, %s%sN," % \ (regtype, regid)) f.write(" 1, true);\n"); + if 'A_CONDEXEC' in hex_common.attribdict[tag]: + f.write(" if (!is_vreg_preloaded(ctx, %s)) {\n" % (regN= )) + f.write(" intptr_t src_off =3D") + f.write(" offsetof(CPUHexagonState, VRegs[%s%sN]);\n"% \ + (regtype, regid)) + f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \ + (regtype, regid)) + f.write(" src_off,\n") + f.write(" sizeof(MMVector),\n") + f.write(" sizeof(MMVector));\n") + f.write(" }\n") + if (not hex_common.skip_qemu_helper(tag)): f.write(" TCGv_ptr %s%sV =3D tcg_temp_new_ptr();\n" % \ (regtype, regid)) --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224556; cv=none; d=zohomail.com; s=zohoarc; b=PXqRGMjsBpsSB+z8Rs7D0w9impQY4uG1jXvdS13inwIj7YUPTKT4DhPjpWeILw+9TWTzj971hFn7EMGM/kc/UBGgM4iWLv4b6idxxDHqb8OotMK7iM96PlQcd4OGMeFEv3j+d0LJtbEXZBQs8G39SJ/B7nRBffWD6qOIv/Jud9I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224556; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=W51p8EOlSaGA1nIaLBycnyPb9PFIcrtmpS+q7fUTaUE=; b=VSdJIqUKFlWe+V51TyL2WvquGr/llSVC56EN3WTW8hZa89KfsSbXUn5jiS3ZhBupLjGFntdo5oQJzpKfuYH+mypM3BpfccekprF/ZyJ0oysLP94KlM11WsQWdZgAEiYs6ETAbBgxegTL4lp2YQ937YGMerzV+ZSKEOGESIw06pQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224556293607.2558362806145; Fri, 16 Dec 2022 13:02:36 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He0-0002mH-Pw; Fri, 16 Dec 2022 15:49:24 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdy-0002kD-4I for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:22 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004P3-LO for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKQmXv002965; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg6y7v5t0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA03.qualcomm.com [127.0.0.1]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKdZp9021736; Fri, 16 Dec 2022 20:49:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 3mgw6trnf5-1; Fri, 16 Dec 2022 20:49:13 +0000 Received: from NALASPPMTA03.qualcomm.com (NALASPPMTA03.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKlA36031201; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 2BGKnC0q000413; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id DEE0B5000AF; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=W51p8EOlSaGA1nIaLBycnyPb9PFIcrtmpS+q7fUTaUE=; b=LIhscZZFTQID/uCKw2dwJp3A5bIAURODEz6vyHSdEMhA3ntPbIOz8ceUOfFalhbVRBpK 2BAeivHTTUicLQ9bgYQS3C10LqeRQdetgxro51RlTsKJhC3Xh57KxmJad2lM3VaCXik7 G2OFAwjBa4fPEkWVnk2/qL1DdUg8CjS3oUwfh6YbVhSgIfs4zKdG1R8/TYYbXA67jUe0 17upkKOozS6C1FB1dDvvU7BiXu7lOXOsoJXEWGQQ2WCsPUPiMyXDemgudRjO6S07za7J rOsZfseM2toLRY0iWgkoYu+Hwvpb80Uv1gW9ygz7tbXFmjCwPczyUqnitEne2g1CcwOu uA== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 03/21] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat Date: Fri, 16 Dec 2022 12:48:27 -0800 Message-Id: <20221216204845.19290-4-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: rPLkS2EDC5tln-T2Rgk5hQn2KQWHs79L X-Proofpoint-GUID: rPLkS2EDC5tln-T2Rgk5hQn2KQWHs79L X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 mlxlogscore=796 clxscore=1015 phishscore=0 suspectscore=0 spamscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224556750100001 These instructions will not be generated by idef-parser, so we override them manually. Test cases added to tests/tcg/hexagon/usr.c Co-authored-by: Matheus Tavares Bernardino Signed-off-by: Matheus Tavares Bernardino Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <20221108162906.3166-4-tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 10 +++- target/hexagon/genptr.c | 104 +++++++++++++++++++++++++++++++++++++++ tests/tcg/hexagon/usr.c | 34 ++++++++++--- 3 files changed, 141 insertions(+), 7 deletions(-) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index 50634ac459..b5fe22a07a 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. * * 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 @@ -612,6 +612,14 @@ tcg_temp_free(tmp); \ } while (0) =20 +/* r0 =3D asr(r1, r2):sat */ +#define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \ + gen_asr_r_r_sat(RdV, RsV, RtV) + +/* r0 =3D asl(r1, r2):sat */ +#define fGEN_TCG_S2_asl_r_r_sat(SHORTCODE) \ + gen_asl_r_r_sat(RdV, RsV, RtV) + /* Floating point */ #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \ gen_helper_conv_sf2df(RddV, cpu_env, RsV) diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 85416dd530..cd3d74525e 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -456,6 +456,110 @@ static TCGv gen_8bitsof(TCGv result, TCGv value) return result; } =20 +/* Shift left with saturation */ +static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt) +{ + TCGv sh32 =3D tcg_temp_new(); + TCGv dst_sar =3D tcg_temp_new(); + TCGv ovf =3D tcg_temp_new(); + TCGv satval =3D tcg_temp_new(); + TCGv min =3D tcg_constant_tl(0x80000000); + TCGv max =3D tcg_constant_tl(0x7fffffff); + + /* + * Possible values for shift_amt are 0 .. 64 + * We need special handling for values above 31 + * + * sh32 =3D shift & 31; + * dst =3D sh32 =3D=3D shift ? src : 0; + * dst <<=3D sh32; + * dst_sar =3D dst >> sh32; + * satval =3D src < 0 ? min : max; + * if (dst_asr !=3D src) { + * usr.OVF |=3D 1; + * dst =3D satval; + * } + */ + + tcg_gen_andi_tl(sh32, shift_amt, 31); + tcg_gen_movcond_tl(TCG_COND_EQ, dst, sh32, shift_amt, + src, tcg_constant_tl(0)); + tcg_gen_shl_tl(dst, dst, sh32); + tcg_gen_sar_tl(dst_sar, dst, sh32); + tcg_gen_movcond_tl(TCG_COND_LT, satval, src, tcg_constant_tl(0), min, = max); + + tcg_gen_setcond_tl(TCG_COND_NE, ovf, dst_sar, src); + tcg_gen_shli_tl(ovf, ovf, reg_field_info[USR_OVF].offset); + tcg_gen_or_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR], = ovf); + + tcg_gen_movcond_tl(TCG_COND_EQ, dst, dst_sar, src, dst, satval); + + tcg_temp_free(sh32); + tcg_temp_free(dst_sar); + tcg_temp_free(ovf); + tcg_temp_free(satval); +} + +static void gen_sar(TCGv dst, TCGv src, TCGv shift_amt) +{ + /* + * Shift arithmetic right + * Robust when shift_amt is >31 bits + */ + TCGv tmp =3D tcg_temp_new(); + tcg_gen_umin_tl(tmp, shift_amt, tcg_constant_tl(31)); + tcg_gen_sar_tl(dst, src, tmp); + tcg_temp_free(tmp); +} + +/* Bidirectional shift right with saturation */ +static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV) +{ + TCGv shift_amt =3D tcg_temp_local_new(); + TCGLabel *positive =3D gen_new_label(); + TCGLabel *done =3D gen_new_label(); + + tcg_gen_sextract_i32(shift_amt, RtV, 0, 7); + tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 0, positive); + + /* Negative shift amount =3D> shift left */ + tcg_gen_neg_tl(shift_amt, shift_amt); + gen_shl_sat(RdV, RsV, shift_amt); + tcg_gen_br(done); + + gen_set_label(positive); + /* Positive shift amount =3D> shift right */ + gen_sar(RdV, RsV, shift_amt); + + gen_set_label(done); + + tcg_temp_free(shift_amt); +} + +/* Bidirectional shift left with saturation */ +static void gen_asl_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV) +{ + TCGv shift_amt =3D tcg_temp_local_new(); + TCGLabel *positive =3D gen_new_label(); + TCGLabel *done =3D gen_new_label(); + + tcg_gen_sextract_i32(shift_amt, RtV, 0, 7); + tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 0, positive); + + /* Negative shift amount =3D> shift right */ + tcg_gen_neg_tl(shift_amt, shift_amt); + gen_sar(RdV, RsV, shift_amt); + tcg_gen_br(done); + + gen_set_label(positive); + /* Positive shift amount =3D> shift left */ + gen_shl_sat(RdV, RsV, shift_amt); + + gen_set_label(done); + + tcg_temp_free(shift_amt); +} + static intptr_t vreg_src_off(DisasContext *ctx, int num) { intptr_t offset =3D offsetof(CPUHexagonState, VRegs[num]); diff --git a/tests/tcg/hexagon/usr.c b/tests/tcg/hexagon/usr.c index fb4514989c..5f68c539dd 100644 --- a/tests/tcg/hexagon/usr.c +++ b/tests/tcg/hexagon/usr.c @@ -429,6 +429,7 @@ FUNC_P_OP_P(vabshsat, "%0 =3D vabsh(%2):sat") FUNC_P_OP_PP(vnavgwr, "%0 =3D vnavgw(%2, %3):rnd:sat") FUNC_R_OP_RI(round_ri_sat, "%0 =3D round(%2, #%3):sat") FUNC_R_OP_RR(asr_r_r_sat, "%0 =3D asr(%2, %3):sat") +FUNC_R_OP_RR(asl_r_r_sat, "%0 =3D asl(%2, %3):sat") =20 FUNC_XPp_OP_PP(ACS, "%0, p2 =3D vacsh(%3, %4)") =20 @@ -907,12 +908,33 @@ int main() TEST_R_OP_RI(round_ri_sat, 0x0000ffff, 2, 0x00004000, USR_CLEA= R); TEST_R_OP_RI(round_ri_sat, 0x7fffffff, 2, 0x1fffffff, USR_OVF); =20 - TEST_R_OP_RR(asr_r_r_sat, 0x0000ffff, 0x00000002, 0x00003fff, - USR_CLEAR); - TEST_R_OP_RR(asr_r_r_sat, 0x00ffffff, 0xfffffff5, 0x7fffffff, - USR_OVF); - TEST_R_OP_RR(asr_r_r_sat, 0x80000000, 0xfffffff5, 0x80000000, - USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 0x0000ffff, 0x02, 0x00003fff, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, 0x80000000, 0x01, 0xc0000000, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, 0xffffffff, 0x01, 0xffffffff, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, 0x00ffffff, 0xf5, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 0x80000000, 0xf5, 0x80000000, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 0x7fff0000, 0x42, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 0xff000000, 0x42, 0x80000000, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 4096, 32, 0x00000000, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, 4096, -32, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, -4096, 32, 0xffffffff, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, -4096, -32, 0x80000000, USR_OVF); + TEST_R_OP_RR(asr_r_r_sat, 0, -32, 0x00000000, USR_CLEAR); + TEST_R_OP_RR(asr_r_r_sat, 1, -32, 0x7fffffff, USR_OVF); + + TEST_R_OP_RR(asl_r_r_sat, 0x00000000, 0x40, 0x00000000, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, 0x80000000, 0xff, 0xc0000000, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, 0xffffffff, 0xff, 0xffffffff, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, 0x00ffffff, 0x0b, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, 0x80000000, 0x0b, 0x80000000, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, 0x7fff0000, 0xbe, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, 0xff000000, 0xbe, 0x80000000, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, 4096, 32, 0x7fffffff, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, 4096, -32, 0x00000000, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, -4096, 32, 0x80000000, USR_OVF); + TEST_R_OP_RR(asl_r_r_sat, -4096, -32, 0xffffffff, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, 0, 32, 0x00000000, USR_CLEAR); + TEST_R_OP_RR(asl_r_r_sat, 1, 32, 0x7fffffff, USR_OVF); =20 TEST_XPp_OP_PP(ACS, 0x0004000300020001ULL, 0x0001000200030004ULL, 0x0000000000000000ULL, 0x0004000300030004ULL, 0xf0, --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224047; cv=none; d=zohomail.com; s=zohoarc; b=AhGob8ch92hJJNOrA5+WTYmts4nt02i7MG1mp6iVeCZVYpaA0aOIEARIMxgk0HFCca3/Qm9Ms4CztKAYoJ666v/N7p7CBuPjdRgCGCml+uZoKz5apGPvodRRp41a5UXMwgUrW20DFj/RolkNnRQ8zOkIS9H8FC9RsrMqiAlAKn8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224047; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Hp+0KLi4gPerds21gmZb+8CWAGNC08NRPqNARHVjC98=; b=jP2XHVaWZ2KlpnM3+WwnB16Uo/JYkhTxlz+ltehxqqkn1SQL8DC4fPTz8ZYMf/QS0urzXl9jLib+XYCsjPO8K2N6DsX4yCaTKnSBwbkpxdMx0lC+i5QSJY9zeLpW9mhIak80efoVoSkSNCcsj3V9/PBo1c6vfUlvl8VJW19Z490= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224047100930.3491373989815; Fri, 16 Dec 2022 12:54:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He3-0002nW-D3; Fri, 16 Dec 2022 15:49:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdz-0002l9-RP for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:23 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004Ow-La for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:23 -0500 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGGlRAT027802; Fri, 16 Dec 2022 20:49:14 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg06rws58-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKdxx3026803; Fri, 16 Dec 2022 20:49:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6b-1; Fri, 16 Dec 2022 20:49:13 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKnDZ0005666; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnCRp005663; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id E1B4B5000B0; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=Hp+0KLi4gPerds21gmZb+8CWAGNC08NRPqNARHVjC98=; b=GxuD+8MZrdtLgl0eCWqPMH+NNtTLCbw6YUx+kjc4HmwmPJP+li6H2kxGwgF2jiHN9wtb Nh7MGsbwHrRWtyx6O0lGKHn+aCCKeT7qAopkj+d9+KPCNyIG8Q61/scRzzdkhmX1LYZb Le5a5apgey2Bnv8KI+SaIZJwFWxz5U2n4zNU+OJczApdlMCXRtPLSWAqIWtw97kd71gx BZ6rJFOwvc3bKbI+m69l1+LaNPSLlJcBRM4MPMZ1dkj4oNMIPKMJmynRbEk+CD4E6/ce hlsy5h1f/c6AYtnDgq8oRZYXhKqzqM7n2cDhdVqtiQDpHDZHHzf7xpAuvgTopDIgCWSm hA== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 04/21] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof Date: Fri, 16 Dec 2022 12:48:28 -0800 Message-Id: <20221216204845.19290-5-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: k2pCKDWx5hFfn8hjMRmH0aqQXWud6zZC X-Proofpoint-ORIG-GUID: k2pCKDWx5hFfn8hjMRmH0aqQXWud6zZC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 spamscore=0 mlxlogscore=914 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 suspectscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224049102100003 When a packet has more than one change-of-flow instruction, only the first one to branch is considered. We use the branch_taken variable to keep track of this. However, when there is a single cof instruction, we don't need the same amount of bookkeeping. We add the pkt_has_multi_cof member to the Packet structure, and pass this information to the needed functions. When there is a generated helper function with cof, the generator will pass this pkt_has_multi_cof as a runtime value. Acked-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-5-tsimpson@quicinc.com> --- target/hexagon/insn.h | 1 + target/hexagon/macros.h | 2 +- target/hexagon/decode.c | 15 +++++++++++++-- target/hexagon/op_helper.c | 24 +++++++++++++++--------- target/hexagon/translate.c | 4 +++- target/hexagon/gen_helper_funcs.py | 5 ++++- target/hexagon/gen_helper_protos.py | 8 ++++++-- target/hexagon/gen_tcg_funcs.py | 5 +++++ target/hexagon/hex_common.py | 3 +++ 9 files changed, 51 insertions(+), 16 deletions(-) diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h index cb92586802..775c4c183d 100644 --- a/target/hexagon/insn.h +++ b/target/hexagon/insn.h @@ -57,6 +57,7 @@ struct Packet { =20 /* Pre-decodes about COF */ bool pkt_has_cof; /* Has any change-of-flow */ + bool pkt_has_multi_cof; /* Has more than one change-of-flow */ bool pkt_has_endloop; =20 bool pkt_has_dczeroa; diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 93ee4739a1..8fd8123cec 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -407,7 +407,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val,= int shift) =20 #define fCHECK_PCALIGN(A) =20 -#define fWRITE_NPC(A) write_new_pc(env, A) +#define fWRITE_NPC(A) write_new_pc(env, pkt_has_multi_cof !=3D 0, A) =20 #define fBRANCH(LOC, TYPE) fWRITE_NPC(LOC) #define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR) diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index 6b73b5c60c..041c8de751 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -388,6 +388,7 @@ static void decode_set_insn_attr_fields(Packet *pkt) uint16_t opcode; =20 pkt->pkt_has_cof =3D false; + pkt->pkt_has_multi_cof =3D false; pkt->pkt_has_endloop =3D false; pkt->pkt_has_dczeroa =3D false; =20 @@ -412,13 +413,23 @@ static void decode_set_insn_attr_fields(Packet *pkt) } } =20 - pkt->pkt_has_cof |=3D decode_opcode_can_jump(opcode); + if (decode_opcode_can_jump(opcode)) { + if (pkt->pkt_has_cof) { + pkt->pkt_has_multi_cof =3D true; + } + pkt->pkt_has_cof =3D true; + } =20 pkt->insn[i].is_endloop =3D decode_opcode_ends_loop(opcode); =20 pkt->pkt_has_endloop |=3D pkt->insn[i].is_endloop; =20 - pkt->pkt_has_cof |=3D pkt->pkt_has_endloop; + if (pkt->pkt_has_endloop) { + if (pkt->pkt_has_cof) { + pkt->pkt_has_multi_cof =3D true; + } + pkt->pkt_has_cof =3D true; + } } } =20 diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 085afc3274..84391e25eb 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -104,20 +104,26 @@ static void log_store64(CPUHexagonState *env, target_= ulong addr, env->mem_log_stores[slot].data64 =3D val; } =20 -static void write_new_pc(CPUHexagonState *env, target_ulong addr) +static void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof, + target_ulong addr) { HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr); =20 - /* - * If more than one branch is taken in a packet, only the first one - * is actually done. - */ - if (env->branch_taken) { - HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, " - "ignoring the second one\n"); + if (pkt_has_multi_cof) { + /* + * If more than one branch is taken in a packet, only the first one + * is actually done. + */ + if (env->branch_taken) { + HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, " + "ignoring the second one\n"); + } else { + fCHECK_PCALIGN(addr); + env->next_PC =3D addr; + env->branch_taken =3D 1; + } } else { fCHECK_PCALIGN(addr); - env->branch_taken =3D 1; env->next_PC =3D addr; } } diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 0940d0f2c1..1d872d72b6 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -248,7 +248,9 @@ static void gen_start_packet(DisasContext *ctx) tcg_gen_movi_tl(hex_slot_cancelled, 0); } if (pkt->pkt_has_cof) { - tcg_gen_movi_tl(hex_branch_taken, 0); + if (pkt->pkt_has_multi_cof) { + tcg_gen_movi_tl(hex_branch_taken, 0); + } tcg_gen_movi_tl(hex_next_PC, next_PC); } if (need_pred_written(pkt)) { diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper= _funcs.py index a446c45384..c4fc609b31 100755 --- a/target/hexagon/gen_helper_funcs.py +++ b/target/hexagon/gen_helper_funcs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 =20 ## -## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. +## Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. ## ## 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 @@ -238,6 +238,9 @@ def gen_helper_function(f, tag, tagregs, tagimms): gen_helper_arg_imm(f,immlett) i +=3D 1 =20 + if (hex_common.need_pkt_has_multi_cof(tag)): + f.write(", uint32_t pkt_has_multi_cof") + if hex_common.need_slot(tag): if i > 0: f.write(", ") f.write("uint32_t slot") diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helpe= r_protos.py index 3b4e993fd1..8c6b36d8d8 100755 --- a/target/hexagon/gen_helper_protos.py +++ b/target/hexagon/gen_helper_protos.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 =20 ## -## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. +## Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Res= erved. ## ## 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 @@ -82,6 +82,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): ## Figure out how many arguments the helper will take if (numscalarresults =3D=3D 0): def_helper_size =3D len(regs)+len(imms)+numscalarreadwrite+1 + if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += =3D 1 if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) @@ -89,6 +90,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): f.write(', void' ) else: def_helper_size =3D len(regs)+len(imms)+numscalarreadwrite + if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += =3D 1 if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) @@ -126,7 +128,9 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): for immlett,bits,immshift in imms: f.write(", s32") =20 - ## Add the arguments for the instruction slot and part1 (if needed) + ## Add the arguments for the instruction pkt_has_multi_cof, slot a= nd + ## part1 (if needed) + if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32') if hex_common.need_slot(tag): f.write(', i32' ) if hex_common.need_part1(tag): f.write(' , i32' ) f.write(')\n') diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index ca5fde91cc..bd199dcbf1 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -622,6 +622,9 @@ def gen_tcg_func(f, tag, regs, imms): ## Generate the call to the helper for immlett,bits,immshift in imms: gen_helper_decl_imm(f,immlett) + if hex_common.need_pkt_has_multi_cof(tag): + f.write(" TCGv pkt_has_multi_cof =3D ") + f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n") if hex_common.need_part1(tag): f.write(" TCGv part1 =3D tcg_constant_tl(insn->part1);\n") if hex_common.need_slot(tag): @@ -654,6 +657,8 @@ def gen_tcg_func(f, tag, regs, imms): for immlett,bits,immshift in imms: gen_helper_call_imm(f,immlett) =20 + if hex_common.need_pkt_has_multi_cof(tag): + f.write(", pkt_has_multi_cof") if hex_common.need_slot(tag): f.write(", slot") if hex_common.need_part1(tag): f.write(", part1" ) f.write(");\n") diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index d9ba7df786..f5b58501db 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -207,6 +207,9 @@ def need_part1(tag): def need_ea(tag): return re.compile(r"\bEA\b").search(semdict[tag]) =20 +def need_pkt_has_multi_cof(tag): + return 'A_COF' in attribdict[tag] + def skip_qemu_helper(tag): return tag in overrides.keys() =20 --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671225091; cv=none; d=zohomail.com; s=zohoarc; b=TXSWN2LrBnoeFetvbrSg0e3F2bSubQ6E/tjnG49PFcxQKlgVGuiQCbnuwtwjku3uss6SsC0YDzFQqVxMMKCzOxHo7TczUC7fzKCa1oNYTUkpuIDi/V+PQ9kddMFybQP/JRmALfM/atp9MGC18lZgJcccJe2xoxLblXaHqmcdRek= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671225091; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=EGES4mBzUhGvh8ug5+tCb9rXluEflhw2s7RR6FHzPrE=; b=VhWTErVe7QShLOKAgKPIhL671QO+cp7+bZALE75hjHMfJ5AFRvoRkXYtil4JDXo3IBjYS/ADnsECnVMCLwYsocMxqBWONbfFZzbyYqDq0u3jYijAMBgdFcnd6LYJV+Ix49Fxz0OHSzhvkPyufRtLc1lQsiQMBQsr20u+jP82rSo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671225091495408.17751146257433; Fri, 16 Dec 2022 13:11:31 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He8-0002qC-LT; Fri, 16 Dec 2022 15:49:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He7-0002pO-6y for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:31 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PJ-Bw for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:30 -0500 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKlU5B026686; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg6y7v5t2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA02.qualcomm.com [127.0.0.1]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKhAlK004614; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 3mgard52nh-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA02.qualcomm.com (NALASPPMTA02.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKidXX006092; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 2BGKnDoY012008; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id E42495000B1; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=EGES4mBzUhGvh8ug5+tCb9rXluEflhw2s7RR6FHzPrE=; b=gANpbWxdqQkjkrEqrqVeeSodbEuuIPnkWPIB81RB6PzCTdUIyuumhRh9bD9htBFjSlF9 xfu3WCC/M924GHjPtvB/zUEuObtwD8T/a8PTazOdOff24NkBC2m2wKdXh8WuCwiGnMCO QMl9XWPlZgApTAw3xl6TJbT6KMoeS7YG+YWYWc+Qt5P9csOERv8Gg+iiY6YIXyx8pF7V aLPA2xEeVGjO+waKlX7Pj/EDyTEXI+EnsGxY/nvGdZoByDhruHfTbSqHGkw2KvIx9z5y +znZ+vXlQZsHuWleklpoDSeDWocRAlRhKBUCxF1oOP6gdqmJSrsAItqblOM85WB/j76x IA== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 05/21] Hexagon (target/hexagon) Remove PC from the runtime state Date: Fri, 16 Dec 2022 12:48:29 -0800 Message-Id: <20221216204845.19290-6-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: rmsAYqkXOTgaFl7khpTF34WZXBNFlzp- X-Proofpoint-GUID: rmsAYqkXOTgaFl7khpTF34WZXBNFlzp- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 mlxlogscore=587 clxscore=1015 phishscore=0 suspectscore=0 spamscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671225093635100003 Add pc field to Packet structure For helpers that need PC, pass an extra argument Remove slot arg from conditional jump helpers On a trap0, copy pkt->pc into hex_gpr[HEX_REG_PC] Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-6-tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 7 +++++++ target/hexagon/insn.h | 1 + target/hexagon/macros.h | 2 +- target/hexagon/translate.c | 9 +-------- target/hexagon/gen_helper_funcs.py | 4 ++++ target/hexagon/gen_helper_protos.py | 3 +++ target/hexagon/gen_tcg_funcs.py | 3 +++ target/hexagon/hex_common.py | 6 +++++- 8 files changed, 25 insertions(+), 10 deletions(-) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index b5fe22a07a..d38db72ce9 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -750,4 +750,11 @@ RsV =3D RsV; \ } while (0) =20 +#define fGEN_TCG_J2_trap0(SHORTCODE) \ + do { \ + uiV =3D uiV; \ + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->pkt->pc); \ + TCGv excp =3D tcg_constant_tl(HEX_EXCP_TRAP0); \ + gen_helper_raise_exception(cpu_env, excp); \ + } while (0) #endif diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h index 775c4c183d..3e7a22c91e 100644 --- a/target/hexagon/insn.h +++ b/target/hexagon/insn.h @@ -54,6 +54,7 @@ typedef struct Instruction Insn; struct Packet { uint16_t num_insns; uint16_t encod_pkt_size_in_bytes; + uint32_t pc; =20 /* Pre-decodes about COF */ bool pkt_has_cof; /* Has any change-of-flow */ diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 8fd8123cec..6e7a6a156a 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -398,7 +398,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val,= int shift) #else #define fREAD_GP() READ_REG(HEX_REG_GP) #endif -#define fREAD_PC() (READ_REG(HEX_REG_PC)) +#define fREAD_PC() (PC) =20 #define fREAD_NPC() (env->next_PC & (0xfffffffe)) =20 diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 1d872d72b6..9efc6c88aa 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -194,11 +194,6 @@ static bool check_for_attrib(Packet *pkt, int attrib) return false; } =20 -static bool need_pc(Packet *pkt) -{ - return check_for_attrib(pkt, A_IMPLICIT_READS_PC); -} - static bool need_slot_cancelled(Packet *pkt) { return check_for_attrib(pkt, A_CONDEXEC); @@ -241,9 +236,6 @@ static void gen_start_packet(DisasContext *ctx) } =20 /* Initialize the runtime state for packet semantics */ - if (need_pc(pkt)) { - tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next); - } if (need_slot_cancelled(pkt)) { tcg_gen_movi_tl(hex_slot_cancelled, 0); } @@ -772,6 +764,7 @@ static void decode_and_translate_packet(CPUHexagonState= *env, DisasContext *ctx) } =20 if (decode_packet(nwords, words, &pkt, false) > 0) { + pkt.pc =3D ctx->base.pc_next; HEX_DEBUG_PRINT_PKT(&pkt); ctx->pkt =3D &pkt; gen_start_packet(ctx); diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper= _funcs.py index c4fc609b31..024f70d166 100755 --- a/target/hexagon/gen_helper_funcs.py +++ b/target/hexagon/gen_helper_funcs.py @@ -241,6 +241,10 @@ def gen_helper_function(f, tag, tagregs, tagimms): if (hex_common.need_pkt_has_multi_cof(tag)): f.write(", uint32_t pkt_has_multi_cof") =20 + if hex_common.need_PC(tag): + if i > 0: f.write(", ") + f.write("target_ulong PC") + i +=3D 1 if hex_common.need_slot(tag): if i > 0: f.write(", ") f.write("uint32_t slot") diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helpe= r_protos.py index 8c6b36d8d8..00c48dff7c 100755 --- a/target/hexagon/gen_helper_protos.py +++ b/target/hexagon/gen_helper_protos.py @@ -85,6 +85,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += =3D 1 if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 + if hex_common.need_PC(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) ## The return type is void f.write(', void' ) @@ -93,6 +94,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += =3D 1 if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 + if hex_common.need_PC(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) =20 ## Generate the qemu DEF_HELPER type for each result @@ -131,6 +133,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): ## Add the arguments for the instruction pkt_has_multi_cof, slot a= nd ## part1 (if needed) if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32') + if hex_common.need_PC(tag): f.write(', i32') if hex_common.need_slot(tag): f.write(', i32' ) if hex_common.need_part1(tag): f.write(' , i32' ) f.write(')\n') diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index bd199dcbf1..7dbdde3191 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -629,6 +629,8 @@ def gen_tcg_func(f, tag, regs, imms): f.write(" TCGv part1 =3D tcg_constant_tl(insn->part1);\n") if hex_common.need_slot(tag): f.write(" TCGv slot =3D tcg_constant_tl(insn->slot);\n") + if hex_common.need_PC(tag): + f.write(" TCGv PC =3D tcg_constant_tl(ctx->pkt->pc);\n") f.write(" gen_helper_%s(" % (tag)) i=3D0 ## If there is a scalar result, it is the return type @@ -659,6 +661,7 @@ def gen_tcg_func(f, tag, regs, imms): =20 if hex_common.need_pkt_has_multi_cof(tag): f.write(", pkt_has_multi_cof") + if hex_common.need_PC(tag): f.write(", PC") if hex_common.need_slot(tag): f.write(", slot") if hex_common.need_part1(tag): f.write(", part1" ) f.write(");\n") diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index f5b58501db..cfe5fe7b35 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -194,7 +194,8 @@ def is_new_val(regtype, regid, tag): return regtype+regid+'N' in semdict[tag] =20 def need_slot(tag): - if ('A_CONDEXEC' in attribdict[tag] or + if (('A_CONDEXEC' in attribdict[tag] and + 'A_JUMP' not in attribdict[tag]) or 'A_STORE' in attribdict[tag] or 'A_LOAD' in attribdict[tag]): return 1 @@ -207,6 +208,9 @@ def need_part1(tag): def need_ea(tag): return re.compile(r"\bEA\b").search(semdict[tag]) =20 +def need_PC(tag): + return 'A_IMPLICIT_READS_PC' in attribdict[tag] + def need_pkt_has_multi_cof(tag): return 'A_COF' in attribdict[tag] =20 --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224933; cv=none; d=zohomail.com; s=zohoarc; b=g6n8u1edY5/3OhB4e60MG9UTW+Od92xfELW9jqEPvGZIMpOwlUgc+ey3QiSPuMLKEyd2tDHNUZWd79r2pnxY4Gvk86eRvRCIpKxaoaHna0hubAZL8JSHjRMV3cA8Yc9/ASR3PDWTNljMx5isqJN3GNg0TTdAWktCY/q+f6YAWgg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224933; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=WX091ZCtICcyzYOyFV5FmfAiF943n/jhqjWGLN4FvbM=; b=WZWebgDUeZMVpEgH7Hq2D7OtVrjbhBc/4DtDE1pD1jEjwk0w/gywjTw1Hwk/f/UyjhGoc/MkALHrt+iLZuVF2BZnBBhRBEh41ZzKGIk4ISuwq7Mi5gjfGp9Jlt28Wn8c5F9PYrvdJU+Qdtvi6zaq6hvZMspP5vqiR9UrqLFWaHo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224933791634.1085227592357; Fri, 16 Dec 2022 13:08:53 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He1-0002md-Ny; Fri, 16 Dec 2022 15:49:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdy-0002kF-7M for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:22 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004P7-LZ for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKfPF7019389; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mgmv11yr8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA05.qualcomm.com [127.0.0.1]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgb9m020655; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 3mgwb1gmpp-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA05.qualcomm.com (NALASPPMTA05.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg3r8019961; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 2BGKnDBu028291; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id E6C3D5000B9; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=WX091ZCtICcyzYOyFV5FmfAiF943n/jhqjWGLN4FvbM=; b=Ij+3cygB2vWApaAXxBZspTPSafaH20HGgaAIm5fw9VwX5lUJe/KXBtmJPtCieh/Rtgcw rOrZkV6XlhsIHxdpiAeGWqIgPQodmZugyNEzPqNNMVyvuUpsRkc4ERYmk/v7KKFeCSvw NK5MwND4FDtV9MMgAE2En5Z8vKUa8kl2bHJVdS+ZEJF3WuAUeb41GEc978HDaYNclBt1 xmhx/EEmbCHqTku6oHJgqd7GWC5cgFmvoqQVHRDGgeRQW25xiRZvHqGiukqyiWsMN+/Z MckgKJF9ZsKW2/ZjoPQc/GjigyDbAJjcXWPDFZrhBV0l12qtidzIe61pRJcG5JCn5/AL MA== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 06/21] Hexagon (target/hexagon) Remove next_PC from runtime state Date: Fri, 16 Dec 2022 12:48:30 -0800 Message-Id: <20221216204845.19290-7-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 9oGEfe0qEo_xhjO5xuUcxdCv1_E95O15 X-Proofpoint-ORIG-GUID: 9oGEfe0qEo_xhjO5xuUcxdCv1_E95O15 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxscore=0 mlxlogscore=958 adultscore=0 phishscore=0 impostorscore=0 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224935051100001 The imported files don't properly mark all CONDEXEC instructions, so we add some logic to hex_common.py to add the attribute. Acked-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-7-tsimpson@quicinc.com> --- target/hexagon/cpu.h | 1 - target/hexagon/gen_tcg.h | 6 ++++++ target/hexagon/macros.h | 2 +- target/hexagon/translate.h | 2 +- target/hexagon/op_helper.c | 6 +++--- target/hexagon/translate.c | 29 +++++++++++++++++++++++------ target/hexagon/gen_helper_funcs.py | 4 ++++ target/hexagon/gen_helper_protos.py | 3 +++ target/hexagon/gen_tcg_funcs.py | 3 +++ target/hexagon/hex_common.py | 21 +++++++++++++++++++++ 10 files changed, 65 insertions(+), 12 deletions(-) diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index 2a65a57bab..ff8c26272d 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -78,7 +78,6 @@ typedef struct CPUArchState { target_ulong gpr[TOTAL_PER_THREAD_REGS]; target_ulong pred[NUM_PREGS]; target_ulong branch_taken; - target_ulong next_PC; =20 /* For comparing with LLDB on target - see adjust_stack_ptrs function = */ target_ulong last_pc_dumped; diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index d38db72ce9..df279ab43b 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -612,6 +612,12 @@ tcg_temp_free(tmp); \ } while (0) =20 +#define fGEN_TCG_J2_pause(SHORTCODE) \ + do { \ + uiV =3D uiV; \ + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC); \ + } while (0) + /* r0 =3D asr(r1, r2):sat */ #define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \ gen_asr_r_r_sat(RdV, RsV, RtV) diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 6e7a6a156a..903503540e 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -400,7 +400,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val,= int shift) #endif #define fREAD_PC() (PC) =20 -#define fREAD_NPC() (env->next_PC & (0xfffffffe)) +#define fREAD_NPC() (next_PC & (0xfffffffe)) =20 #define fREAD_P0() (READ_PREG(0)) #define fREAD_P3() (READ_PREG(3)) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index b8fcf615e8..96509a4da7 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -30,6 +30,7 @@ typedef struct DisasContext { DisasContextBase base; Packet *pkt; Insn *insn; + uint32_t next_PC; uint32_t mem_idx; uint32_t num_packets; uint32_t num_insns; @@ -134,7 +135,6 @@ static inline void ctx_log_qreg_write(DisasContext *ctx, =20 extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; extern TCGv hex_pred[NUM_PREGS]; -extern TCGv hex_next_PC; extern TCGv hex_this_PC; extern TCGv hex_slot_cancelled; extern TCGv hex_branch_taken; diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 84391e25eb..aad0195eb6 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -119,12 +119,12 @@ static void write_new_pc(CPUHexagonState *env, bool p= kt_has_multi_cof, "ignoring the second one\n"); } else { fCHECK_PCALIGN(addr); - env->next_PC =3D addr; + env->gpr[HEX_REG_PC] =3D addr; env->branch_taken =3D 1; } } else { fCHECK_PCALIGN(addr); - env->next_PC =3D addr; + env->gpr[HEX_REG_PC] =3D addr; } } =20 @@ -299,7 +299,7 @@ void HELPER(debug_commit_end)(CPUHexagonState *env, int= has_st0, int has_st1) } } =20 - HEX_DEBUG_LOG("Next PC =3D " TARGET_FMT_lx "\n", env->next_PC); + HEX_DEBUG_LOG("Next PC =3D " TARGET_FMT_lx "\n", env->gpr[HEX_REG_PC]); HEX_DEBUG_LOG("Exec counters: pkt =3D " TARGET_FMT_lx ", insn =3D " TARGET_FMT_lx ", hvx =3D " TARGET_FMT_lx "\n", diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 9efc6c88aa..fa6415936c 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -31,7 +31,6 @@ =20 TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; TCGv hex_pred[NUM_PREGS]; -TCGv hex_next_PC; TCGv hex_this_PC; TCGv hex_slot_cancelled; TCGv hex_branch_taken; @@ -120,7 +119,6 @@ static void gen_exec_counters(DisasContext *ctx) static void gen_end_tb(DisasContext *ctx) { gen_exec_counters(ctx); - tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC); tcg_gen_exit_tb(NULL, 0); ctx->base.is_jmp =3D DISAS_NORETURN; } @@ -128,7 +126,7 @@ static void gen_end_tb(DisasContext *ctx) static void gen_exception_end_tb(DisasContext *ctx, int excp) { gen_exec_counters(ctx); - tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC); + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC); gen_exception_raw(excp); ctx->base.is_jmp =3D DISAS_NORETURN; =20 @@ -204,6 +202,24 @@ static bool need_pred_written(Packet *pkt) return check_for_attrib(pkt, A_WRITES_PRED_REG); } =20 +static bool need_next_PC(DisasContext *ctx) +{ + Packet *pkt =3D ctx->pkt; + + /* Check for conditional control flow or HW loop end */ + for (int i =3D 0; i < pkt->num_insns; i++) { + uint16_t opcode =3D pkt->insn[i].opcode; + if (GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode, A_COF)) { + return true; + } + if (GET_ATTRIB(opcode, A_HWLOOP0_END) || + GET_ATTRIB(opcode, A_HWLOOP1_END)) { + return true; + } + } + return false; +} + static void gen_start_packet(DisasContext *ctx) { Packet *pkt =3D ctx->pkt; @@ -211,6 +227,7 @@ static void gen_start_packet(DisasContext *ctx) int i; =20 /* Clear out the disassembly context */ + ctx->next_PC =3D next_PC; ctx->reg_log_idx =3D 0; bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS); ctx->preg_log_idx =3D 0; @@ -243,7 +260,9 @@ static void gen_start_packet(DisasContext *ctx) if (pkt->pkt_has_multi_cof) { tcg_gen_movi_tl(hex_branch_taken, 0); } - tcg_gen_movi_tl(hex_next_PC, next_PC); + if (need_next_PC(ctx)) { + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC); + } } if (need_pred_written(pkt)) { tcg_gen_movi_tl(hex_pred_written, 0); @@ -936,8 +955,6 @@ void hexagon_translate_init(void) } hex_pred_written =3D tcg_global_mem_new(cpu_env, offsetof(CPUHexagonState, pred_written), "pred_written"); - hex_next_PC =3D tcg_global_mem_new(cpu_env, - offsetof(CPUHexagonState, next_PC), "next_PC"); hex_this_PC =3D tcg_global_mem_new(cpu_env, offsetof(CPUHexagonState, this_PC), "this_PC"); hex_slot_cancelled =3D tcg_global_mem_new(cpu_env, diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper= _funcs.py index 024f70d166..00ee58f159 100755 --- a/target/hexagon/gen_helper_funcs.py +++ b/target/hexagon/gen_helper_funcs.py @@ -245,6 +245,10 @@ def gen_helper_function(f, tag, tagregs, tagimms): if i > 0: f.write(", ") f.write("target_ulong PC") i +=3D 1 + if hex_common.helper_needs_next_PC(tag): + if i > 0: f.write(", ") + f.write("target_ulong next_PC") + i +=3D 1 if hex_common.need_slot(tag): if i > 0: f.write(", ") f.write("uint32_t slot") diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helpe= r_protos.py index 00c48dff7c..ed4b9cf0d4 100755 --- a/target/hexagon/gen_helper_protos.py +++ b/target/hexagon/gen_helper_protos.py @@ -86,6 +86,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 if hex_common.need_PC(tag): def_helper_size +=3D 1 + if hex_common.helper_needs_next_PC(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) ## The return type is void f.write(', void' ) @@ -95,6 +96,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): if hex_common.need_part1(tag): def_helper_size +=3D 1 if hex_common.need_slot(tag): def_helper_size +=3D 1 if hex_common.need_PC(tag): def_helper_size +=3D 1 + if hex_common.helper_needs_next_PC(tag): def_helper_size +=3D 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) =20 ## Generate the qemu DEF_HELPER type for each result @@ -134,6 +136,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms): ## part1 (if needed) if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32') if hex_common.need_PC(tag): f.write(', i32') + if hex_common.helper_needs_next_PC(tag): f.write(', i32') if hex_common.need_slot(tag): f.write(', i32' ) if hex_common.need_part1(tag): f.write(' , i32' ) f.write(')\n') diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index 7dbdde3191..f4cea6dfc4 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -631,6 +631,8 @@ def gen_tcg_func(f, tag, regs, imms): f.write(" TCGv slot =3D tcg_constant_tl(insn->slot);\n") if hex_common.need_PC(tag): f.write(" TCGv PC =3D tcg_constant_tl(ctx->pkt->pc);\n") + if hex_common.helper_needs_next_PC(tag): + f.write(" TCGv next_PC =3D tcg_constant_tl(ctx->next_PC);\n= ") f.write(" gen_helper_%s(" % (tag)) i=3D0 ## If there is a scalar result, it is the return type @@ -662,6 +664,7 @@ def gen_tcg_func(f, tag, regs, imms): if hex_common.need_pkt_has_multi_cof(tag): f.write(", pkt_has_multi_cof") if hex_common.need_PC(tag): f.write(", PC") + if hex_common.helper_needs_next_PC(tag): f.write(", next_PC") if hex_common.need_slot(tag): f.write(", slot") if hex_common.need_part1(tag): f.write(", part1" ) f.write(");\n") diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index cfe5fe7b35..8e631b444f 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -66,6 +66,19 @@ def add_qemu_macro_attrib(name, attrib): macros[name].attribs.add(attrib) =20 immextre =3D re.compile(r'f(MUST_)?IMMEXT[(]([UuSsRr])') + +def is_cond_jump(tag): + if tag =3D=3D 'J2_rte': + return False + if ('A_HWLOOP0_END' in attribdict[tag] or + 'A_HWLOOP1_END' in attribdict[tag]): + return False + return \ + re.compile(r"(if.*fBRANCH)|(if.*fJUMPR)").search(semdict[tag]) != =3D None + +def is_cond_call(tag): + return re.compile(r"(if.*fCALL)").search(semdict[tag]) !=3D None + def calculate_attribs(): add_qemu_macro_attrib('fREAD_PC', 'A_IMPLICIT_READS_PC') add_qemu_macro_attrib('fTRAP', 'A_IMPLICIT_READS_PC') @@ -96,6 +109,11 @@ def calculate_attribs(): for regtype, regid, toss, numregs in regs: if regtype =3D=3D "P" and is_written(regid): attribdict[tag].add('A_WRITES_PRED_REG') + # Mark conditional jumps and calls + # Not all instructions are properly marked with A_CONDEXEC + for tag in tags: + if is_cond_jump(tag) or is_cond_call(tag): + attribdict[tag].add('A_CONDEXEC') =20 def SEMANTICS(tag, beh, sem): #print tag,beh,sem @@ -211,6 +229,9 @@ def need_ea(tag): def need_PC(tag): return 'A_IMPLICIT_READS_PC' in attribdict[tag] =20 +def helper_needs_next_PC(tag): + return 'A_CALL' in attribdict[tag] + def need_pkt_has_multi_cof(tag): return 'A_COF' in attribdict[tag] =20 --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671225276; cv=none; d=zohomail.com; s=zohoarc; b=f2a5Vl0Dju+BISObQMHrVRAg3X+cqslGlmAtD3V5CaLhv4VNh6x4xEE4EXeN34MJ2PMRdnTIBS27BDmDfvht1I9dplGA+am/z8soD1TB0kK8OXk7kmNw+DhCbLwboUmP+akuuf+f+ivFELk5wVC8cqjncCUjXmDQF51qZDpRFnw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671225276; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=HD6nkzBmJCbxhKNAI6KdbJOdH0+Ax+eOslL9GFMlOT0=; b=cCdsvoLn65EFcJBlAVo9esavAtyy+1WgegYcwnDlVH3ZodfyrXrqj+fM4kQFlRfnlgQsic30ZzwKBIcLhipHTI7NqZXIiVJZUlIUSY/DnzlxpPswR6RLUESPvu6NXZbgW1esA0I8LXvbRxWOTpplzp0FMfMHrn0cAKOQqsySmAs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671225276611267.11901924020765; Fri, 16 Dec 2022 13:14:36 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He0-0002mI-Ty; Fri, 16 Dec 2022 15:49:24 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdz-0002ks-8O for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:23 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004Oy-LZ for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:23 -0500 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKBt2i030294; Fri, 16 Dec 2022 20:49:14 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg06rws59-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKhYTB030818; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6k-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKnDZ2005666; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDDm005675; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id E9398500102; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=HD6nkzBmJCbxhKNAI6KdbJOdH0+Ax+eOslL9GFMlOT0=; b=Z4HpsW676nxao7fzioTMMn+I0gc8dev0EFnVEjSFF2FwFlvRlWNTReOOhISVrwdnxxVd bcG5dnqUi9DFzUwjwDxLjdxGLVAWO2Z8m/0JokiggP7gcbg3zzufgDe2x5pBpmLhS3gJ 4Um2+osE5tU/xcQVxTbW/nhiywug4VbgujaNzVlxQ5vQHiZtl5UeJ2y7EVIRlsUw//ww VcnWtkHB7d3m9YFGJsL6gdIdBaCPLAM5otnn9d79ZO8vK/D7BUR9J8p0BcvlW8SZ/78t EZlqWKNof2Ph6w++BCwezoY/lM4sFGzhTY+09HxeqSNrhBVEW6NFssTB8DPeUfDfaZvY vw== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 07/21] Hexagon (target/hexagon) Add overrides for direct call instructions Date: Fri, 16 Dec 2022 12:48:31 -0800 Message-Id: <20221216204845.19290-8-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: PMG9CzKcANmctmf0yI_u9DvSSA4409HB X-Proofpoint-ORIG-GUID: PMG9CzKcANmctmf0yI_u9DvSSA4409HB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 spamscore=0 mlxlogscore=623 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 suspectscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671225278701100001 Add overrides for J2_call J2_callt J2_callf Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-8-tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 8 ++++++ target/hexagon/genptr.c | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index df279ab43b..1bdc787a02 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -612,6 +612,14 @@ tcg_temp_free(tmp); \ } while (0) =20 +#define fGEN_TCG_J2_call(SHORTCODE) \ + gen_call(ctx, riV) + +#define fGEN_TCG_J2_callt(SHORTCODE) \ + gen_cond_call(ctx, PuV, TCG_COND_EQ, riV) +#define fGEN_TCG_J2_callf(SHORTCODE) \ + gen_cond_call(ctx, PuV, TCG_COND_NE, riV) + #define fGEN_TCG_J2_pause(SHORTCODE) \ do { \ uiV =3D uiV; \ diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index cd3d74525e..580c403879 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -456,6 +456,61 @@ static TCGv gen_8bitsof(TCGv result, TCGv value) return result; } =20 +static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr, + TCGCond cond, TCGv pred) +{ + TCGLabel *pred_false =3D NULL; + if (cond !=3D TCG_COND_ALWAYS) { + pred_false =3D gen_new_label(); + tcg_gen_brcondi_tl(cond, pred, 0, pred_false); + } + + if (ctx->pkt->pkt_has_multi_cof) { + /* If there are multiple branches in a packet, ignore the second o= ne */ + tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC], + hex_branch_taken, tcg_constant_tl(0), + hex_gpr[HEX_REG_PC], addr); + tcg_gen_movi_tl(hex_branch_taken, 1); + } else { + tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr); + } + + if (cond !=3D TCG_COND_ALWAYS) { + gen_set_label(pred_false); + } +} + +static void gen_write_new_pc_pcrel(DisasContext *ctx, int pc_off, + TCGCond cond, TCGv pred) +{ + target_ulong dest =3D ctx->pkt->pc + pc_off; + gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred); +} + +static void gen_call(DisasContext *ctx, int pc_off) +{ + TCGv next_PC =3D + tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes); + gen_log_reg_write(HEX_REG_LR, next_PC); + gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL); +} + +static void gen_cond_call(DisasContext *ctx, TCGv pred, + TCGCond cond, int pc_off) +{ + TCGv next_PC; + TCGv lsb =3D tcg_temp_local_new(); + TCGLabel *skip =3D gen_new_label(); + tcg_gen_andi_tl(lsb, pred, 1); + gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb); + tcg_gen_brcondi_tl(cond, lsb, 0, skip); + tcg_temp_free(lsb); + next_PC =3D + tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes); + gen_log_reg_write(HEX_REG_LR, next_PC); + gen_set_label(skip); +} + /* Shift left with saturation */ static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt) { --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224973; cv=none; d=zohomail.com; s=zohoarc; b=Cb52D+JQB7p7qbnKLeHG8K6tBrdM91PDW9DaOTifEjPdvJXxwNGf32kvnlFyEjPCkGRI2df1lHM5pFkZUha6wjPbktyB6tcrlvqIiBrcu5LE33HRIutl49P9PNXPD9I3eCq/nEyAb2mtL4J+VfYLOU0OfjBPZnL46ZYLh6rsUes= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224973; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=dr6QMwgvoS6tA0jzXCztY8EIsIpfxpIX6rIiyMnIq7Y=; b=U6Mg8dGloCVCrqveug3hSxl1yW8bRzeOPJITmXTLEezkqAUL4sa1hcWZ+Wd1QsgvWk24Nk9CwqmUk+t3a9HZpv42ByCBNn/X1UrFrPzxQIt5AazyKcgnp3qqB+cWHnxrNi7KjeouudoxnVfJPJxCWjzx/DKF5b4jmqL+XFiMaTQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224973646329.2752682169164; Fri, 16 Dec 2022 13:09:33 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He7-0002pB-3F; Fri, 16 Dec 2022 15:49:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He5-0002ob-Hh for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:29 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PE-5w for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:29 -0500 Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKJpU0009552; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg2vwd6cp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA04.qualcomm.com [127.0.0.1]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKhSFk016891; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 3mgw840n73-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA04.qualcomm.com (NALASPPMTA04.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKfsSv015741; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 2BGKnDwx024100; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id EBC87500105; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=dr6QMwgvoS6tA0jzXCztY8EIsIpfxpIX6rIiyMnIq7Y=; b=I+umJT3GkBNKJUISvG5dS8G8nUsZvnEpyMFB0mlpHLJ5NaXOxRy7HQGvKECATC7sH/D3 qiAwADdPxR7y9EPJqf+DvsPbzIzr2bW4joy4HFjtEMe2afyLftXYCGunGXNuE80tKuFv cNjSKxSE/V9LXR1CalugJhPB1b0O5nAfRFmak5D3umFytOcm/GW1KUgVg2LJXNUkTbGw Ps7pgPLjqI3t6XqzIz6NYYvasFjz0DBj/6iexKaYg0XTNmn6Tp9r69vHHGoVpI9mldsT WvAEJpNbHb786aJMhAj4uCOadppXGIR+MFQOc51SiMVOncgmY8mY497IKGsuXHeEp7OL rg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 08/21] Hexagon (target/hexagon) Add overrides for compound compare and jump Date: Fri, 16 Dec 2022 12:48:32 -0800 Message-Id: <20221216204845.19290-9-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: UIbKF8AAEn5OCmwtbkmmxe1CMfk4cgQf X-Proofpoint-ORIG-GUID: UIbKF8AAEn5OCmwtbkmmxe1CMfk4cgQf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 clxscore=1015 phishscore=0 malwarescore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 impostorscore=0 mlxlogscore=635 adultscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224974987100001 Acked-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-9-tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 177 +++++++++++++++++++++++++++++++++++++++ target/hexagon/genptr.c | 90 ++++++++++++++++++++ 2 files changed, 267 insertions(+) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index 1bdc787a02..506b454e4e 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -620,6 +620,183 @@ #define fGEN_TCG_J2_callf(SHORTCODE) \ gen_cond_call(ctx, PuV, TCG_COND_NE, riV) =20 +/* + * Compound compare and jump instructions + * Here is a primer to understand the tag names + * + * Comparison + * cmpeqi compare equal to an immediate + * cmpgti compare greater than an immediate + * cmpgtiu compare greater than an unsigned immediate + * cmpeqn1 compare equal to negative 1 + * cmpgtn1 compare greater than negative 1 + * cmpeq compare equal (two registers) + * cmpgtu compare greater than unsigned (two registers) + * tstbit0 test bit zero + * + * Condition + * tp0 p0 is true p0 =3D cmp.eq(r0,#5); if (p0.new) jump:nt = address + * fp0 p0 is false p0 =3D cmp.eq(r0,#5); if (!p0.new) jump:nt= address + * tp1 p1 is true p1 =3D cmp.eq(r0,#5); if (p1.new) jump:nt = address + * fp1 p1 is false p1 =3D cmp.eq(r0,#5); if (!p1.new) jump:nt= address + * + * Prediction (not modelled in qemu) + * _nt not taken + * _t taken + */ +#define fGEN_TCG_J4_cmpeq_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_EQ, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpeq_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_EQ, RsV, RtV, riV) + +#define fGEN_TCG_J4_cmpgt_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GT, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgt_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GT, RsV, RtV, riV) + +#define fGEN_TCG_J4_cmpgtu_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GTU, RsV, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GTU, RsV, RtV, riV) + +#define fGEN_TCG_J4_cmpeqi_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_EQ, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_EQ, RsV, UiV, riV) + +#define fGEN_TCG_J4_cmpgti_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_GT, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgti_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_GT, RsV, UiV, riV) + +#define fGEN_TCG_J4_cmpgtui_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_GTU, RsV, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_GTU, RsV, UiV, riV) + +#define fGEN_TCG_J4_cmpeqn1_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 0, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 0, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 0, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 0, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 1, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 1, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 1, TCG_COND_EQ, RsV, riV) +#define fGEN_TCG_J4_cmpeqn1_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 1, TCG_COND_EQ, RsV, riV) + +#define fGEN_TCG_J4_cmpgtn1_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 0, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 0, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 0, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 0, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 1, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_t(ctx, 1, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 1, TCG_COND_GT, RsV, riV) +#define fGEN_TCG_J4_cmpgtn1_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_cmp_n1_jmp_f(ctx, 1, TCG_COND_GT, RsV, riV) + +#define fGEN_TCG_J4_tstbit0_tp0_jump_nt(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_tp0_jump_t(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_fp0_jump_nt(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_NE, riV) +#define fGEN_TCG_J4_tstbit0_fp0_jump_t(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_NE, riV) +#define fGEN_TCG_J4_tstbit0_tp1_jump_nt(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_tp1_jump_t(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_fp1_jump_nt(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV) +#define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \ + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV) + #define fGEN_TCG_J2_pause(SHORTCODE) \ do { \ uiV =3D uiV; \ diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 580c403879..c003800247 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -487,6 +487,96 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, = int pc_off, gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred); } =20 +static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2) +{ + TCGv one =3D tcg_constant_tl(0xff); + TCGv zero =3D tcg_constant_tl(0); + + tcg_gen_movcond_tl(cond, res, arg1, arg2, one, zero); +} + +static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred, + int pc_off) +{ + gen_write_new_pc_pcrel(ctx, pc_off, cond, pred); +} + +static void gen_cmpnd_cmp_jmp(DisasContext *ctx, + int pnum, TCGCond cond1, TCGv arg1, TCGv arg= 2, + TCGCond cond2, int pc_off) +{ + if (ctx->insn->part1) { + TCGv pred =3D tcg_temp_new(); + gen_compare(cond1, pred, arg1, arg2); + gen_log_pred_write(ctx, pnum, pred); + tcg_temp_free(pred); + } else { + TCGv pred =3D tcg_temp_new(); + tcg_gen_mov_tl(pred, hex_new_pred_value[pnum]); + gen_cond_jump(ctx, cond2, pred, pc_off); + tcg_temp_free(pred); + } +} + +static void gen_cmpnd_cmp_jmp_t(DisasContext *ctx, + int pnum, TCGCond cond, TCGv arg1, TCGv ar= g2, + int pc_off) +{ + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_EQ, pc_off); +} + +static void gen_cmpnd_cmp_jmp_f(DisasContext *ctx, + int pnum, TCGCond cond, TCGv arg1, TCGv ar= g2, + int pc_off) +{ + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_NE, pc_off); +} + +static void gen_cmpnd_cmpi_jmp_t(DisasContext *ctx, + int pnum, TCGCond cond, TCGv arg1, int ar= g2, + int pc_off) +{ + TCGv tmp =3D tcg_constant_tl(arg2); + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_EQ, pc_off); +} + +static void gen_cmpnd_cmpi_jmp_f(DisasContext *ctx, + int pnum, TCGCond cond, TCGv arg1, int ar= g2, + int pc_off) +{ + TCGv tmp =3D tcg_constant_tl(arg2); + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_NE, pc_off); +} + +static void gen_cmpnd_cmp_n1_jmp_t(DisasContext *ctx, int pnum, TCGCond co= nd, + TCGv arg, int pc_off) +{ + gen_cmpnd_cmpi_jmp_t(ctx, pnum, cond, arg, -1, pc_off); +} + +static void gen_cmpnd_cmp_n1_jmp_f(DisasContext *ctx, int pnum, TCGCond co= nd, + TCGv arg, int pc_off) +{ + gen_cmpnd_cmpi_jmp_f(ctx, pnum, cond, arg, -1, pc_off); +} + +static void gen_cmpnd_tstbit0_jmp(DisasContext *ctx, + int pnum, TCGv arg, TCGCond cond, int pc= _off) +{ + if (ctx->insn->part1) { + TCGv pred =3D tcg_temp_new(); + tcg_gen_andi_tl(pred, arg, 1); + gen_8bitsof(pred, pred); + gen_log_pred_write(ctx, pnum, pred); + tcg_temp_free(pred); + } else { + TCGv pred =3D tcg_temp_new(); + tcg_gen_mov_tl(pred, hex_new_pred_value[pnum]); + gen_cond_jump(ctx, cond, pred, pc_off); + tcg_temp_free(pred); + } +} + static void gen_call(DisasContext *ctx, int pc_off) { TCGv next_PC =3D --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224704; cv=none; d=zohomail.com; s=zohoarc; b=noRbK/WvuxCEZtFBZPdG6Aipqyz0UsgrztAm2UbTgYLmfS2EijyF0beBWxptoMfo193rUAbFHsBnBIM8uE6l779bUWMauHBsPgn/2IrgIJosw9E2qMsGoALSxI6CGrkRkgSPHOrckUqVnZH55Eo7encl00m5KAqrsnDs/29s5Cc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224704; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=FaZY7WRbsmRZ6VHn6FO3daFaN4y3jgWKO3xZ1iOO5jA=; b=m2Nd/o2VswIhmjxxhQuEXvDZ/qvW+Q4Hw0DLf34v4ZdFyfvxksjVfitlB4ciuwzj0gW1Yml6kw1ud61eAlGpB2TnGxbR/dD9CEXhOS8LX7Jx0GbXfViJhE5J/j2jv2Q5cOztjctDBody9KwhgOvGGoP41d2jvMYi1hDtpQDJjio= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224704612341.8028845836287; Fri, 16 Dec 2022 13:05:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeD-0002r6-3K; Fri, 16 Dec 2022 15:49:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He5-0002oN-DK for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:29 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PH-8v for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:29 -0500 Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKnFLv017495; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg3f8w3dh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKdxx4026803; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6j-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgg7Z030048; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDgD005676; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id EE8A4500116; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=FaZY7WRbsmRZ6VHn6FO3daFaN4y3jgWKO3xZ1iOO5jA=; b=Hn96wMZdrBseNwJJ2fbNwgvnmDxxQZm4s9MYn/dngNfD1tceheF/un3CVseDBEdVw079 6I3SZSRQDdJItnP2WUAHIQY/R33Hb2LIG3gtaezjHgL8Qxy0ZR5EkiYUsqqVt9/LEkzU K/XMjqvtrMw6O8nzc/twRcTisw9vGGkJDgK2pbcy/Q8L+pLs2xoyy0aMk+NCzbYEG0aJ TEXyCNMGzCxE1wrKoTUFDzGh4UTbAO3/p3rgVyEB9qGZBj5VsrtFcoCpMP8bOwe2B2nf 9NmU9XBuShDzdl43DXZ+Ote96TQQCEG24bI90xfxQUX+mnHpveHupKJENW6VDO0yqo0I uQ== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 09/21] Hexagon (target/hexagon) Add overrides for various forms of jump Date: Fri, 16 Dec 2022 12:48:33 -0800 Message-Id: <20221216204845.19290-10-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: fsj4zZi4pOnaV4OKL1XX-IlkNT9hW2Ht X-Proofpoint-ORIG-GUID: fsj4zZi4pOnaV4OKL1XX-IlkNT9hW2Ht X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 lowpriorityscore=0 spamscore=0 impostorscore=0 mlxlogscore=604 adultscore=0 phishscore=0 bulkscore=0 mlxscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224705491100001 Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-10-tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 201 +++++++++++++++++++++++++++++++++++++++ target/hexagon/genptr.c | 43 +++++++++ 2 files changed, 244 insertions(+) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index 506b454e4e..3583f390e9 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -797,6 +797,207 @@ #define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \ gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV) =20 +#define fGEN_TCG_J2_jump(SHORTCODE) \ + gen_jump(ctx, riV) +#define fGEN_TCG_J2_jumpr(SHORTCODE) \ + gen_jumpr(ctx, RsV) +#define fGEN_TCG_J4_jumpseti(SHORTCODE) \ + do { \ + tcg_gen_movi_tl(RdV, UiV); \ + gen_jump(ctx, riV); \ + } while (0) + +#define fGEN_TCG_cond_jumpt(COND) \ + do { \ + TCGv LSB =3D tcg_temp_new(); \ + COND; \ + gen_cond_jump(ctx, TCG_COND_EQ, LSB, riV); \ + tcg_temp_free(LSB); \ + } while (0) +#define fGEN_TCG_cond_jumpf(COND) \ + do { \ + TCGv LSB =3D tcg_temp_new(); \ + COND; \ + gen_cond_jump(ctx, TCG_COND_NE, LSB, riV); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_J2_jumpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumptpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumpf(SHORTCODE) \ + fGEN_TCG_cond_jumpf(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumpfpt(SHORTCODE) \ + fGEN_TCG_cond_jumpf(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumptnew(SHORTCODE) \ + gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV) +#define fGEN_TCG_J2_jumptnewpt(SHORTCODE) \ + gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV) +#define fGEN_TCG_J2_jumpfnewpt(SHORTCODE) \ + fGEN_TCG_cond_jumpf(fLSBNEW(PuN)) +#define fGEN_TCG_J2_jumpfnew(SHORTCODE) \ + fGEN_TCG_cond_jumpf(fLSBNEW(PuN)) +#define fGEN_TCG_J2_jumprz(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprzpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprnz(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprnzpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprgtez(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprgtezpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprltez(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0)) +#define fGEN_TCG_J2_jumprltezpt(SHORTCODE) \ + fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0)) + +#define fGEN_TCG_cond_jumprt(COND) \ + do { \ + TCGv LSB =3D tcg_temp_new(); \ + COND; \ + gen_cond_jumpr(ctx, RsV, TCG_COND_EQ, LSB); \ + tcg_temp_free(LSB); \ + } while (0) +#define fGEN_TCG_cond_jumprf(COND) \ + do { \ + TCGv LSB =3D tcg_temp_new(); \ + COND; \ + gen_cond_jumpr(ctx, RsV, TCG_COND_NE, LSB); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_J2_jumprt(SHORTCODE) \ + fGEN_TCG_cond_jumprt(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumprtpt(SHORTCODE) \ + fGEN_TCG_cond_jumprt(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumprf(SHORTCODE) \ + fGEN_TCG_cond_jumprf(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumprfpt(SHORTCODE) \ + fGEN_TCG_cond_jumprf(fLSBOLD(PuV)) +#define fGEN_TCG_J2_jumprtnew(SHORTCODE) \ + fGEN_TCG_cond_jumprt(fLSBNEW(PuN)) +#define fGEN_TCG_J2_jumprtnewpt(SHORTCODE) \ + fGEN_TCG_cond_jumprt(fLSBNEW(PuN)) +#define fGEN_TCG_J2_jumprfnew(SHORTCODE) \ + fGEN_TCG_cond_jumprf(fLSBNEW(PuN)) +#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \ + fGEN_TCG_cond_jumprf(fLSBNEW(PuN)) + +/* + * New value compare & jump instructions + * if ([!]COND(r0.new, r1) jump:t address + * if ([!]COND(r0.new, #7) jump:t address + */ +#define fGEN_TCG_J4_cmpgt_t_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgt_t_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgt_f_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgt_f_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV) + +#define fGEN_TCG_J4_cmpeq_t_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpeq_t_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpeq_f_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpeq_f_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV) + +#define fGEN_TCG_J4_cmplt_t_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV) +#define fGEN_TCG_J4_cmplt_t_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV) +#define fGEN_TCG_J4_cmplt_f_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV) +#define fGEN_TCG_J4_cmplt_f_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV) + +#define fGEN_TCG_J4_cmpeqi_t_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_t_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_f_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpeqi_f_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, UiV, riV) + +#define fGEN_TCG_J4_cmpgti_t_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgti_t_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgti_f_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgti_f_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, UiV, riV) + +#define fGEN_TCG_J4_cmpltu_t_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LTU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpltu_t_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LTU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpltu_f_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GEU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpltu_f_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GEU, NsN, RtV, riV) + +#define fGEN_TCG_J4_cmpgtui_t_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GTU, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_t_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GTU, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_f_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LEU, NsN, UiV, riV) +#define fGEN_TCG_J4_cmpgtui_f_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LEU, NsN, UiV, riV) + +#define fGEN_TCG_J4_cmpgtu_t_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GTU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_t_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_GTU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_f_jumpnv_t(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LEU, NsN, RtV, riV) +#define fGEN_TCG_J4_cmpgtu_f_jumpnv_nt(SHORTCODE) \ + gen_cmp_jumpnv(ctx, TCG_COND_LEU, NsN, RtV, riV) + +#define fGEN_TCG_J4_cmpeqn1_t_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, -1, riV) +#define fGEN_TCG_J4_cmpeqn1_t_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, -1, riV) +#define fGEN_TCG_J4_cmpeqn1_f_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, -1, riV) +#define fGEN_TCG_J4_cmpeqn1_f_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, -1, riV) + +#define fGEN_TCG_J4_cmpgtn1_t_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, -1, riV) +#define fGEN_TCG_J4_cmpgtn1_t_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, -1, riV) +#define fGEN_TCG_J4_cmpgtn1_f_jumpnv_t(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, -1, riV) +#define fGEN_TCG_J4_cmpgtn1_f_jumpnv_nt(SHORTCODE) \ + gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, -1, riV) + +#define fGEN_TCG_J4_tstbit0_t_jumpnv_t(SHORTCODE) \ + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_t_jumpnv_nt(SHORTCODE) \ + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV) +#define fGEN_TCG_J4_tstbit0_f_jumpnv_t(SHORTCODE) \ + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV) +#define fGEN_TCG_J4_tstbit0_f_jumpnv_nt(SHORTCODE) \ + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV) + +/* r0 =3D r1 ; jump address */ +#define fGEN_TCG_J4_jumpsetr(SHORTCODE) \ + do { \ + tcg_gen_mov_tl(RdV, RsV); \ + gen_jump(ctx, riV); \ + } while (0) + #define fGEN_TCG_J2_pause(SHORTCODE) \ do { \ uiV =3D uiV; \ diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index c003800247..be9c715ea8 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -495,6 +495,12 @@ static void gen_compare(TCGCond cond, TCGv res, TCGv a= rg1, TCGv arg2) tcg_gen_movcond_tl(cond, res, arg1, arg2, one, zero); } =20 +static void gen_cond_jumpr(DisasContext *ctx, TCGv dst_pc, + TCGCond cond, TCGv pred) +{ + gen_write_new_pc_addr(ctx, dst_pc, cond, pred); +} + static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred, int pc_off) { @@ -577,6 +583,25 @@ static void gen_cmpnd_tstbit0_jmp(DisasContext *ctx, } } =20 +static void gen_testbit0_jumpnv(DisasContext *ctx, + TCGv arg, TCGCond cond, int pc_off) +{ + TCGv pred =3D tcg_temp_new(); + tcg_gen_andi_tl(pred, arg, 1); + gen_cond_jump(ctx, cond, pred, pc_off); + tcg_temp_free(pred); +} + +static void gen_jump(DisasContext *ctx, int pc_off) +{ + gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL); +} + +static void gen_jumpr(DisasContext *ctx, TCGv new_pc) +{ + gen_write_new_pc_addr(ctx, new_pc, TCG_COND_ALWAYS, NULL); +} + static void gen_call(DisasContext *ctx, int pc_off) { TCGv next_PC =3D @@ -601,6 +626,24 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred, gen_set_label(skip); } =20 +static void gen_cmp_jumpnv(DisasContext *ctx, + TCGCond cond, TCGv val, TCGv src, int pc_off) +{ + TCGv pred =3D tcg_temp_new(); + tcg_gen_setcond_tl(cond, pred, val, src); + gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off); + tcg_temp_free(pred); +} + +static void gen_cmpi_jumpnv(DisasContext *ctx, + TCGCond cond, TCGv val, int src, int pc_off) +{ + TCGv pred =3D tcg_temp_new(); + tcg_gen_setcondi_tl(cond, pred, val, src); + gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off); + tcg_temp_free(pred); +} + /* Shift left with saturation */ static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt) { --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223786; cv=none; d=zohomail.com; s=zohoarc; b=cAe083rI6gRdZgjx0lFyj4euBBkYghgx76JMf6qvIxzbpp/iQC3JxwLcY2WxQUj8pRZTUvd23Euj2jmc18HsyGhAUwHQKI5bCVjkr1pe5T4ZQ3misnlW2ianrOCkYMKxFXD20Pug7Z+wEF5E3uihbXNTchQq5oKe9B1+xvYrpYM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223786; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=f/5XoOWkY+B8MJbX/Rlms3w5yqUQ22WpwvmMVPaDPqg=; b=aw2MSQJMZI4jP7ecy+Db0o2CGEaA6MJidpR88j1OC00GAl3xrCpn3c1fkeQL+IBClTtaNXEYW3ePHkiz9FRoEKWEeEwuiFMehhSIoV9A2lcETX37INQ/BBkk2AKe27KBUziGr79rv9LapPl2pPY8bF06qEtwDv/PVUjRhRjqlwA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671223786557902.5542970454611; Fri, 16 Dec 2022 12:49:46 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Hdz-0002l3-SF; Fri, 16 Dec 2022 15:49:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdx-0002jz-Sg for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004PA-Lb for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGGl0eY027033; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg06rws5b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA03.qualcomm.com [127.0.0.1]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKglVA025334; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 3mgw6trnf9-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA03.qualcomm.com (NALASPPMTA03.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKjjqn028035; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 2BGKnDu5000424; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id F1053500117; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=f/5XoOWkY+B8MJbX/Rlms3w5yqUQ22WpwvmMVPaDPqg=; b=oXW0xyIcnuhS2jOmI4I0vCalGCfYHKNKtzwKa1SSgSqlq6jtakjsZRHeJ02HCLs10mgQ nKe0C4OF2zOqG8ikkbIk75qJds5HnGQFodd1WdfCX9zsVLkqJJ6VhDAWqNc1p8Vbetaf uRqidtLTadCCeE1PjhrioWISyXayfL/pv6s0IDM39BeBrzVvQUxTws179DqiwbfE2fpO E/Lfc9MxuyBzDq1xgCN75nYVu1p2cHvSNB72IS1xTOHGfCkQ0W2om4wzFpMvx/YsFz1a nfMP9A0ryijQ1Qk2oTxvEZZuHm8rVLfdedE1AWzRRGCEhgRV0bchGKa0eL+ON9rZURzt kg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 10/21] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch Date: Fri, 16 Dec 2022 12:48:34 -0800 Message-Id: <20221216204845.19290-11-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: WNkzhfHW_LeF9dhaFCbfA35QHJtdIIBq X-Proofpoint-ORIG-GUID: WNkzhfHW_LeF9dhaFCbfA35QHJtdIIBq X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 spamscore=0 mlxlogscore=807 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 suspectscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223787464100003 Direct block chaining is documented here https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining Recall that Hexagon allows packets with multiple jumps where only the first one with a true predicate will actually jump. We can use tcg_gen_goto_tb/tcg_gen_exit_tb when the packet contains a single PC-relative branch or jump. If not, we use tcg_gen_lookup_and_goto_ptr. We add the following to DisasContext in order to delay the branching until the end of packet commit (in gen_end_tb) branch_cond The TCGCond condition under which the branch is taken When branch_cond =3D=3D TCG_COND_NEVER, there isn't a single direct branch in this packet. When branch_cond !=3D TCG_COND_ALWAYS, the value is in hex_branch_taken branch_dest The destination of the branch Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-11-tsimpson@quicinc.com> --- target/hexagon/translate.h | 2 ++ target/hexagon/genptr.c | 12 +++++++++++- target/hexagon/translate.c | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index 96509a4da7..aacf0b0921 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -57,6 +57,8 @@ typedef struct DisasContext { bool qreg_is_predicated[NUM_QREGS]; int qreg_log_idx; bool pre_commit; + TCGCond branch_cond; + target_ulong branch_dest; } DisasContext; =20 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum) diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index be9c715ea8..ee0f86fab2 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -484,7 +484,17 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, = int pc_off, TCGCond cond, TCGv pred) { target_ulong dest =3D ctx->pkt->pc + pc_off; - gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred); + if (ctx->pkt->pkt_has_multi_cof) { + gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred); + } else { + /* Defer this jump to the end of the TB */ + ctx->branch_cond =3D TCG_COND_ALWAYS; + if (pred !=3D NULL) { + ctx->branch_cond =3D cond; + tcg_gen_mov_tl(hex_branch_taken, pred); + } + ctx->branch_dest =3D dest; + } } =20 static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2) diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index fa6415936c..f5ef54f039 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -116,10 +116,41 @@ static void gen_exec_counters(DisasContext *ctx) hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns); } =20 +static bool use_goto_tb(DisasContext *ctx, target_ulong dest) +{ + return translator_use_goto_tb(&ctx->base, dest); +} + +static void gen_goto_tb(DisasContext *ctx, int idx, target_ulong dest) +{ + if (use_goto_tb(ctx, dest)) { + tcg_gen_goto_tb(idx); + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest); + tcg_gen_exit_tb(ctx->base.tb, idx); + } else { + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest); + tcg_gen_lookup_and_goto_ptr(); + } +} + static void gen_end_tb(DisasContext *ctx) { gen_exec_counters(ctx); - tcg_gen_exit_tb(NULL, 0); + + if (ctx->branch_cond !=3D TCG_COND_NEVER) { + if (ctx->branch_cond !=3D TCG_COND_ALWAYS) { + TCGLabel *skip =3D gen_new_label(); + tcg_gen_brcondi_tl(ctx->branch_cond, hex_branch_taken, 0, skip= ); + gen_goto_tb(ctx, 0, ctx->branch_dest); + gen_set_label(skip); + gen_goto_tb(ctx, 1, ctx->next_PC); + } else { + gen_goto_tb(ctx, 0, ctx->branch_dest); + } + } else { + tcg_gen_lookup_and_goto_ptr(); + } + ctx->base.is_jmp =3D DISAS_NORETURN; } =20 @@ -807,6 +838,7 @@ static void hexagon_tr_init_disas_context(DisasContextB= ase *dcbase, ctx->num_packets =3D 0; ctx->num_insns =3D 0; ctx->num_hvx_insns =3D 0; + ctx->branch_cond =3D TCG_COND_NEVER; } =20 static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224152; cv=none; d=zohomail.com; s=zohoarc; b=F0GXw27TfACV7s3JUjAcncOP6RbN/DHj82mL7XSGMDDAxFrhQyC4LUWTWVak162aNBBXmS23d2pEjQz1GtaQeHFKdJuSp8ACSMGtZN1WkEPOmm0ZHELC/Q4opRmbvNBQLi3cNMmhl4l++tKc5Tn/trfagRYXORxNP7QQa49JalM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224152; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=N+lOjYqD3o/v7v1GRwB5KR2los9HFrQfm5Ekr3zArpk=; b=hkxNc6IuDzPEZIhFch1FeyCD3S/eJ60OpZeVriRsrjGO2YyEnXF8dz4DhgPdrF7gmnnqnBXlbQdXteaJ8esJBynlz/SctWKG1UxJ2P1aKWaKGuoCtW3z0QiEkngboz/yNNKQEGA2C/TTdMe4+iSUatp3VeRsxNJYwk2IGdcT8z8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224152559134.63233475701372; Fri, 16 Dec 2022 12:55:52 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Hdy-0002k2-0s; Fri, 16 Dec 2022 15:49:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdx-0002jo-2P for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004PC-La for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:20 -0500 Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKaUCo024937; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg2vwd6cn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA04.qualcomm.com [127.0.0.1]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgNrO016068; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 3mgw840n74-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA04.qualcomm.com (NALASPPMTA04.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKiGTo017732; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 2BGKnDhS024103; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id F39CA500118; Fri, 16 Dec 2022 12:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=N+lOjYqD3o/v7v1GRwB5KR2los9HFrQfm5Ekr3zArpk=; b=COUL0RCjUsMIic7akSzr4T2ST/emCMxJCrCgAugiXziXX3ovMpEzAguIu2rADLxtCVk/ YdOpaTWn8QTJU1iTq54SA/43SJmHYxURo6/GWTimO0gg+cDa+hduHNBfF+sEUhfySF3x OvGee0hnYGkZBYFoy64VTr+MB/cnwSF7MQRVTBxd4AoCVoWhyw214EzX6M/MmsStpFga IBkfGbFokfM+sT0ktFmVzJQppEC0uQfTwHvBuiFyJ/PTVgN95bwU7qyjgET50I8+Nrsw EXPJ93bCGNAURxIkRZNYA4+UELDjPd1VfolLdDNDSPPiKJYoPxjhz/otfzL/B4GZ1G29 dQ== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com Subject: [PULL 11/21] Hexagon (target/hexagon) Use direct block chaining for tight loops Date: Fri, 16 Dec 2022 12:48:35 -0800 Message-Id: <20221216204845.19290-12-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: uXZSkEGj1WzEhXkGzl_AD5Zu0E1O0uk0 X-Proofpoint-ORIG-GUID: uXZSkEGj1WzEhXkGzl_AD5Zu0E1O0uk0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 clxscore=1015 phishscore=0 malwarescore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 impostorscore=0 mlxlogscore=608 adultscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224153917100005 Direct block chaining is documented here https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining Hexagon inner loops end with the endloop0 instruction To go back to the beginning of the loop, this instructions writes to PC from register SA0 (start address 0). To use direct block chaining, we have to assign PC with a constant value. So, we specialize the code generation when the start of the translation block is equal to SA0. When this is the case, we defer the compare/branch from endloop0 to gen_end_tb. When this is done, we can assign the start address of the TB to PC. Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson Message-Id: <20221108162906.3166-12-tsimpson@quicinc.com> --- target/hexagon/cpu.h | 13 +++--- target/hexagon/gen_tcg.h | 3 ++ target/hexagon/translate.h | 1 + target/hexagon/genptr.c | 84 ++++++++++++++++++++++++++++++++++++++ target/hexagon/translate.c | 33 +++++++++++++++ 5 files changed, 129 insertions(+), 5 deletions(-) diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index ff8c26272d..1d89e11a1a 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -25,6 +25,7 @@ #include "mmvec/mmvec.h" #include "qom/object.h" #include "hw/core/cpu.h" +#include "hw/registerfields.h" =20 #define NUM_PREGS 4 #define TOTAL_PER_THREAD_REGS 64 @@ -152,16 +153,18 @@ struct ArchCPU { =20 #include "cpu_bits.h" =20 +FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1) + static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, target_ulong= *pc, target_ulong *cs_base, uint32_t *f= lags) { + uint32_t hex_flags =3D 0; *pc =3D env->gpr[HEX_REG_PC]; *cs_base =3D 0; -#ifdef CONFIG_USER_ONLY - *flags =3D 0; -#else -#error System mode not supported on Hexagon yet -#endif + if (*pc =3D=3D env->gpr[HEX_REG_SA0]) { + hex_flags =3D FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1); + } + *flags =3D hex_flags; } =20 static inline int cpu_mmu_index(CPUHexagonState *env, bool ifetch) diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index 3583f390e9..19697b42a5 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -620,6 +620,9 @@ #define fGEN_TCG_J2_callf(SHORTCODE) \ gen_cond_call(ctx, PuV, TCG_COND_NE, riV) =20 +#define fGEN_TCG_J2_endloop0(SHORTCODE) \ + gen_endloop0(ctx) + /* * Compound compare and jump instructions * Here is a primer to understand the tag names diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index aacf0b0921..d971f4f095 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -59,6 +59,7 @@ typedef struct DisasContext { bool pre_commit; TCGCond branch_cond; target_ulong branch_dest; + bool is_tight_loop; } DisasContext; =20 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum) diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index ee0f86fab2..a4a79c8454 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -497,6 +497,33 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, = int pc_off, } } =20 +static void gen_set_usr_field(int field, TCGv val) +{ + tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_U= SR], + val, + reg_field_info[field].offset, + reg_field_info[field].width); +} + +static void gen_set_usr_fieldi(int field, int x) +{ + if (reg_field_info[field].width =3D=3D 1) { + target_ulong bit =3D 1 << reg_field_info[field].offset; + if ((x & 1) =3D=3D 1) { + tcg_gen_ori_tl(hex_new_value[HEX_REG_USR], + hex_new_value[HEX_REG_USR], + bit); + } else { + tcg_gen_andi_tl(hex_new_value[HEX_REG_USR], + hex_new_value[HEX_REG_USR], + ~bit); + } + } else { + TCGv val =3D tcg_constant_tl(x); + gen_set_usr_field(field, val); + } +} + static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2) { TCGv one =3D tcg_constant_tl(0xff); @@ -636,6 +663,63 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred, gen_set_label(skip); } =20 +static void gen_endloop0(DisasContext *ctx) +{ + TCGv lpcfg =3D tcg_temp_local_new(); + + GET_USR_FIELD(USR_LPCFG, lpcfg); + + /* + * if (lpcfg =3D=3D 1) { + * hex_new_pred_value[3] =3D 0xff; + * hex_pred_written |=3D 1 << 3; + * } + */ + TCGLabel *label1 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_NE, lpcfg, 1, label1); + { + tcg_gen_movi_tl(hex_new_pred_value[3], 0xff); + tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << 3); + } + gen_set_label(label1); + + /* + * if (lpcfg) { + * SET_USR_FIELD(USR_LPCFG, lpcfg - 1); + * } + */ + TCGLabel *label2 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_EQ, lpcfg, 0, label2); + { + tcg_gen_subi_tl(lpcfg, lpcfg, 1); + SET_USR_FIELD(USR_LPCFG, lpcfg); + } + gen_set_label(label2); + + /* + * If we're in a tight loop, we'll do this at the end of the TB to take + * advantage of direct block chaining. + */ + if (!ctx->is_tight_loop) { + /* + * if (hex_gpr[HEX_REG_LC0] > 1) { + * PC =3D hex_gpr[HEX_REG_SA0]; + * hex_new_value[HEX_REG_LC0] =3D hex_gpr[HEX_REG_LC0] - 1; + * } + */ + TCGLabel *label3 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3); + { + gen_jumpr(ctx, hex_gpr[HEX_REG_SA0]); + tcg_gen_subi_tl(hex_new_value[HEX_REG_LC0], + hex_gpr[HEX_REG_LC0], 1); + } + gen_set_label(label3); + } + + tcg_temp_free(lpcfg); +} + static void gen_cmp_jumpnv(DisasContext *ctx, TCGCond cond, TCGv val, TCGv src, int pc_off) { diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index f5ef54f039..75f28e08ad 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -135,6 +135,8 @@ static void gen_goto_tb(DisasContext *ctx, int idx, tar= get_ulong dest) =20 static void gen_end_tb(DisasContext *ctx) { + Packet *pkt =3D ctx->pkt; + gen_exec_counters(ctx); =20 if (ctx->branch_cond !=3D TCG_COND_NEVER) { @@ -147,6 +149,18 @@ static void gen_end_tb(DisasContext *ctx) } else { gen_goto_tb(ctx, 0, ctx->branch_dest); } + } else if (ctx->is_tight_loop && + pkt->insn[pkt->num_insns - 1].opcode =3D=3D J2_endloop0) { + /* + * When we're in a tight loop, we defer the endloop0 processing + * to take advantage of direct block chaining + */ + TCGLabel *skip =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, skip); + tcg_gen_subi_tl(hex_gpr[HEX_REG_LC0], hex_gpr[HEX_REG_LC0], 1); + gen_goto_tb(ctx, 0, ctx->base.tb->pc); + gen_set_label(skip); + gen_goto_tb(ctx, 1, ctx->next_PC); } else { tcg_gen_lookup_and_goto_ptr(); } @@ -337,6 +351,15 @@ static void mark_implicit_reg_write(DisasContext *ctx,= int attrib, int rnum) */ bool is_predicated =3D GET_ATTRIB(opcode, A_CONDEXEC) || rnum =3D=3D HEX_REG_USR; + + /* LC0/LC1 is conditionally written by endloop instructions */ + if ((rnum =3D=3D HEX_REG_LC0 || rnum =3D=3D HEX_REG_LC1) && + (opcode =3D=3D J2_endloop0 || + opcode =3D=3D J2_endloop1 || + opcode =3D=3D J2_endloop01)) { + is_predicated =3D true; + } + if (is_predicated && !is_preloaded(ctx, rnum)) { tcg_gen_mov_tl(hex_new_value[rnum], hex_gpr[rnum]); } @@ -420,6 +443,14 @@ static void gen_reg_writes(DisasContext *ctx) int reg_num =3D ctx->reg_log[i]; =20 tcg_gen_mov_tl(hex_gpr[reg_num], hex_new_value[reg_num]); + + /* + * ctx->is_tight_loop is set when SA0 points to the beginning of t= he TB. + * If we write to SA0, we have to turn off tight loop handling. + */ + if (reg_num =3D=3D HEX_REG_SA0) { + ctx->is_tight_loop =3D false; + } } } =20 @@ -833,12 +864,14 @@ static void hexagon_tr_init_disas_context(DisasContex= tBase *dcbase, CPUState *cs) { DisasContext *ctx =3D container_of(dcbase, DisasContext, base); + uint32_t hex_flags =3D dcbase->tb->flags; =20 ctx->mem_idx =3D MMU_USER_IDX; ctx->num_packets =3D 0; ctx->num_insns =3D 0; ctx->num_hvx_insns =3D 0; ctx->branch_cond =3D TCG_COND_NEVER; + ctx->is_tight_loop =3D FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP); } =20 static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671225298; cv=none; d=zohomail.com; s=zohoarc; b=DXXwQfrZyNOOs98Dz9kn2bIdjvsweLzQIFz5+ZihEE6nJ1lB4GUuj6u5YLRTzCryAAot8f3VCgCKfoCiD8HxKEn+z5qd+oPECuf6hODa+I17KSIK9858gk0GyYPnAtTgFTGKNal/SYxLMozYyoRDkmP1jZhqbZvqU4sxB1N53u8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671225298; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=2n3vpXOFsoAMeZMe182TMAkb4qCUxFy3tNc4I4882m8=; b=R6Jfx9oW5yOMR9zB/fF4aAgfcJXR1/K5Omx4ukml3SpZQkOt2rkBQ6AS7nYZFHHOf5h6tA+6048BkLEHij+Hu9OQlmeifDj5lizvBjwJeE/7txG3n0OIICIP2IbssOXea77Um890RH7YjAnNZgj7leXxO24FdI6wy70zHqNZWgQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671225298058736.310846449488; Fri, 16 Dec 2022 13:14:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He7-0002ps-Uy; Fri, 16 Dec 2022 15:49:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He6-0002oz-Oy for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:30 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PU-Gu for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:30 -0500 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKDsNi003494; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg06rws5c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKeL61027274; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6q-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKlbCw004194; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDmb005677; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 0234D500119; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=2n3vpXOFsoAMeZMe182TMAkb4qCUxFy3tNc4I4882m8=; b=K9hR5DWBKY6Hf/KRGTfhbXkgP6h7iZRbM94JlWs4YrTi4BOCMJ236KrboFsmw+Kvoo9G +DgRX8SEuFrEp4RiW0p+g3kmZhjbUia0wk6xNELq4/zEtL6shxWCTnb787yJMGOMIZy3 xARsrJBlNebl2FvXk2Qoxh+J5h2yOCsC97shjY+Ao25dJFUFiOJv9XkAwkebWtFxdEO2 MIVZhWstctLgTuoRpSKwITrtC95l2M9RL0ZZL/DKhJjV62xcOtXIRtxEzJ767KjrRg6x QLWjv5sLFW01pzcBep6XDMxXK65wAgPOhMEvtndu9nI/Rvi+8QdVJX/mcZWa0NjiPNAf zQ== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Alessandro Di Federico , Anton Johansson Subject: [PULL 12/21] target/hexagon: update MAINTAINERS for idef-parser Date: Fri, 16 Dec 2022 12:48:36 -0800 Message-Id: <20221216204845.19290-13-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: yip_L8ho3KizDLL6SWsAQRypyG_sqCn6 X-Proofpoint-ORIG-GUID: yip_L8ho3KizDLL6SWsAQRypyG_sqCn6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 spamscore=0 mlxlogscore=792 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 suspectscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671225298398100001 From: Alessandro Di Federico Signed-off-by: Alessandro Di Federico Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-2-anjo@rev.ng> --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3bd433b65a..716d5a24ad 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -197,6 +197,8 @@ Hexagon TCG CPUs M: Taylor Simpson S: Supported F: target/hexagon/ +X: target/hexagon/idef-parser/ +X: target/hexagon/gen_idef_parser_funcs.py F: linux-user/hexagon/ F: tests/tcg/hexagon/ F: disas/hexagon.c @@ -204,6 +206,13 @@ F: configs/targets/hexagon-linux-user/default.mak F: docker/dockerfiles/debian-hexagon-cross.docker F: docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh =20 +Hexagon idef-parser +M: Alessandro Di Federico +M: Anton Johansson +S: Supported +F: target/hexagon/idef-parser/ +F: target/hexagon/gen_idef_parser_funcs.py + HPPA (PA-RISC) TCG CPUs M: Richard Henderson S: Maintained --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224621; cv=none; d=zohomail.com; s=zohoarc; b=M4kxjc4nwIyvB/QzoO8G0fw3MfXE66DCg8FM8vA4R0fYmPIo5NK5ltoRBj040UlrOJONDGr+qLqGxn7HXpWkMZuV03HAk2o2F9MBONW6irQDMvIFnPw7eExmXlBmvqZk4wnyIY4aV5sfa/DAdEd+Z/8YiPYRvPQj2vZp6qBVQWc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224621; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=QtslqPZTXkVY80tdVueOCG1zlXutbSZKknTlTmFm2Zc=; b=XsdSHwJagpaD1N2eNAKesIqMGBzLIYEtiFy1AKlFJ/CrHAJmQ5QnzSV888lCEOGfXuhaJeVvQ88zdZzG4Enss4u/+ptSa+o43MYlgoQx3bVamcrVQrRkHt+7pGRCx1vxLeEy6KkRcqT0lushUAC+z8x4g6qtBnZSkb04l0Ziaik= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224621264555.656619879054; Fri, 16 Dec 2022 13:03:41 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Hem-0003DV-OZ; Fri, 16 Dec 2022 15:50:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6HeC-0002r8-KK for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:36 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He4-0004QL-IE for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:36 -0500 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGIxdYR016288; Fri, 16 Dec 2022 20:49:16 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg8e6bpqc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:16 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg9Pn029818; Fri, 16 Dec 2022 20:49:15 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6t-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKlbD0004194; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDDq005678; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 04F3B50011A; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=QtslqPZTXkVY80tdVueOCG1zlXutbSZKknTlTmFm2Zc=; b=VCQuyLYbu0WaHumLvejrjED8KLcJBYkrOHf8cC1R/ukYh15TtW3hZEAcfJPAPWsNgh/a Cu2n28yPIU2mEUoipFo9IuqCs4oEBSmhY+CfMbYGRG+FyyHPpXKt0DCznvq0+Q2rY/PW ipwurYAbKCVEKrXNePHrj+TKO2Tl0DOwl010uSxQWAzlhbOxQd7zWi5LIHWfea9x1G50 3tcu+/9d3TVttngJIbzmJHbNMunC/Re4KIefwsUF7+nKp2/pGpEpLJXE3W461ESvtVHn tF9OZ5uOZpGO5/eHVpv28HyFSyztjeBqvzJNYyYqEgunG4+NIDu7I3n3DDLFGUjjMz30 Sw== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Alessandro Di Federico , Anton Johansson Subject: [PULL 13/21] target/hexagon: import README for idef-parser Date: Fri, 16 Dec 2022 12:48:37 -0800 Message-Id: <20221216204845.19290-14-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: Bu2c3_xfo56a8165icISIT1wY757qo8l X-Proofpoint-ORIG-GUID: Bu2c3_xfo56a8165icISIT1wY757qo8l X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 priorityscore=1501 lowpriorityscore=0 spamscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxscore=0 adultscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224623006100003 From: Alessandro Di Federico Signed-off-by: Alessandro Di Federico Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-3-anjo@rev.ng> --- target/hexagon/idef-parser/README.rst | 722 ++++++++++++++++++++++++++ target/hexagon/README | 5 + 2 files changed, 727 insertions(+) create mode 100644 target/hexagon/idef-parser/README.rst diff --git a/target/hexagon/idef-parser/README.rst b/target/hexagon/idef-pa= rser/README.rst new file mode 100644 index 0000000000..65e6bf4ee5 --- /dev/null +++ b/target/hexagon/idef-parser/README.rst @@ -0,0 +1,722 @@ +Hexagon ISA instruction definitions to tinycode generator compiler +------------------------------------------------------------------ + +idef-parser is a small compiler able to translate the Hexagon ISA descript= ion +language into tinycode generator code, that can be easily integrated into = QEMU. + +Compilation Example +------------------- + +To better understand the scope of the idef-parser, we'll explore an applic= ative +example. Let's start by one of the simplest Hexagon instruction: the ``add= ``. + +The ISA description language represents the ``add`` instruction as +follows: + +.. code:: c + + A2_add(RdV, in RsV, in RtV) { + { RdV=3DRsV+RtV;} + } + +idef-parser will compile the above code into the following code: + +.. code:: c + + /* A2_add */ + void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 R= dV, + TCGv_i32 RsV, TCGv_i32 RtV) + /* { RdV=3DRsV+RtV;} */ + { + TCGv_i32 tmp_0 =3D tcg_temp_new_i32(); + tcg_gen_add_i32(tmp_0, RsV, RtV); + tcg_gen_mov_i32(RdV, tmp_0); + tcg_temp_free_i32(tmp_0); + } + +The output of the compilation process will be a function, containing the +tinycode generator code, implementing the correct semantics. That function= will +not access any global variable, because all the accessed data structures w= ill be +passed explicitly as function parameters. Among the passed parameters we w= ill +have TCGv (tinycode variables) representing the input and output registers= of +the architecture, integers representing the immediates that come from the = code, +and other data structures which hold information about the disassemblation +context (``DisasContext`` struct). + +Let's begin by describing the input code. The ``add`` instruction is assoc= iated +with a unique identifier, in this case ``A2_add``, which allows to disting= uish +variants of the same instruction, and expresses the class to which the +instruction belongs, in this case ``A2`` corresponds to the Hexagon +``ALU32/ALU`` instruction subclass. + +After the instruction identifier, we have a series of parameters that repr= esents +TCG variables that will be passed to the generated function. Parameters ma= rked +with ``in`` are already initialized, while the others are output parameter= s. + +We will leverage this information to infer several information: + +- Fill in the output function signature with the correct TCGv registers +- Fill in the output function signature with the immediate integers +- Keep track of which registers, among the declared one, have been + initialized + +Let's now observe the actual instruction description code, in this case: + +.. code:: c + + { RdV=3DRsV+RtV;} + +This code is composed by a subset of the C syntax, and is the result of the +application of some macro definitions contained in the ``macros.h`` file. + +This file is used to reduce the complexity of the input language where com= plex +variants of similar constructs can be mapped to a unique primitive, so tha= t the +idef-parser has to handle a lower number of computation primitives. + +As you may notice, the description code modifies the registers which have = been +declared by the declaration statements. In this case all the three registe= rs +will be declared, ``RsV`` and ``RtV`` will also be read and ``RdV`` will be +written. + +Now let's have a quick look at the generated code, line by line. + +:: + + TCGv_i32 tmp_0 =3D tcg_temp_new_i32(); + +This code starts by declaring a temporary TCGv to hold the result from the= sum +operation. + +:: + + tcg_gen_add_i32(tmp_0, RsV, RtV); + +Then, we are generating the sum tinycode operator between the selected +registers, storing the result in the just declared temporary. + +:: + + tcg_gen_mov_i32(RdV, tmp_0); + +The result of the addition is now stored in the temporary, we move it into= the +correct destination register. This code may seem inefficient, but QEMU will +perform some optimizations on the tinycode, reducing the unnecessary copy. + +:: + + tcg_temp_free_i32(tmp_0); + +Finally, we free the temporary we used to hold the addition result. + +Parser Input +------------ + +Before moving on to the structure of idef-parser itself, let us spend some= words +on its' input. There are two preprocessing steps applied to the generated +instruction semantics in ``semantics_generated.pyinc`` that we need to con= sider. +Firstly, + +:: + + gen_idef_parser_funcs.py + +which takes instruction semantics in ``semantics_generated.pyinc`` to C-li= ke +pseudo code, output into ``idef_parser_input.h.inc``. For instance, the +``J2_jumpr`` instruction which jumps to an address stored in a register +argument. This is instruction is defined as + +:: + + SEMANTICS( \ + "J2_jumpr", \ + "jumpr Rs32", \ + """{fJUMPR(RsN,RsV,COF_TYPE_JUMPR);}""" \ + ) + +in ``semantics_generated.pyinc``. Running ``gen_idef_parser_funcs.py`` +we obtain the pseudo code + +:: + + J2_jumpr(in RsV) { + {fJUMPR(RsN,RsV,COF_TYPE_JUMPR);} + } + +with macros such as ``fJUMPR`` intact. + +The second step is to expand macros into a form suitable for our parser. +These macros are defined in ``idef-parser/macros.inc`` and the step is +carried out by the ``prepare`` script which runs the C preprocessor on +``idef_parser_input.h.inc`` to produce +``idef_parser_input.preprocessed.h.inc``. + +To finish the above example, after preprocessing ``J2_jumpr`` we obtain + +:: + + J2_jumpr(in RsV) { + {(PC =3D RsV);} + } + +where ``fJUMPR(RsN,RsV,COF_TYPE_JUMPR);`` was expanded to ``(PC =3D RsV)``, +signifying a write to the Program Counter ``PC``. Note, that ``PC`` in +this expression is not a variable in the strict C sense since it is not +declared anywhere, but rather a symbol which is easy to match in +idef-parser later on. + +Parser Structure +---------------- + +The idef-parser is built using the ``flex`` and ``bison``. + +``flex`` is used to split the input string into tokens, each described usi= ng a +regular expression. The token description is contained in the +``idef-parser.lex`` source file. The flex-generated scanner takes care als= o to +extract from the input text other meaningful information, e.g.,=C2=A0the n= umerical +value in case of an immediate constant, and decorates the token with the +extracted information. + +``bison`` is used to generate the actual parser, starting from the parsing +description contained in the ``idef-parser.y`` file. The generated parser +executes the ``main`` function at the end of the ``idef-parser.y`` file, w= hich +opens input and output files, creates the parsing context, and eventually = calls +the ``yyparse()`` function, which starts the execution of the LALR(1) pars= er +(see `Wikipedia `__ for more +information about LALR parsing techniques). The LALR(1) parser, whenever i= t has +to shift a token, calls the ``yylex()`` function, which is defined by the +flex-generated code, and reads the input file returning the next scanned t= oken. + +The tokens are mapped on the source language grammar, defined in the +``idef-parser.y`` file to build a unique syntactic tree, according to the +specified operator precedences and associativity rules. + +The grammar describes the whole file which contains the Hexagon instruction +descriptions, therefore it starts from the ``input`` nonterminal, which is= a +list of instructions, each instruction is represented by the following gra= mmar +rule, representing the structure of the input file shown above: + +:: + + instruction : INAME arguments code + | error + + arguments : '(' ')' + | '(' argument_list ')'; + + argument_list : argument_decl ',' argument_list + | argument_decl + + argument_decl : REG + | PRED + | IN REG + | IN PRED + | IMM + | var + ; + + code : '{' statements '}' + + statements : statements statement + | statement + + statement : control_statement + | var_decl ';' + | rvalue ';' + | code_block + | ';' + + code_block : '{' statements '}' + | '{' '}' + +With this initial portion of the grammar we are defining the instruction, = its' +arguments, and its' statements. Each argument is defined by the +``argument_decl`` rule, and can be either + +:: + + Description Example + ---------------------------------------- + output register RsV + output predicate register P0 + input register in RsV + input predicate register in P0 + immediate value 1234 + local variable EA + +Note, the only local variable allowed to be used as an argument is the eff= ective +address ``EA``. Similarly, each statement can be a ``control_statement``, a +variable declaration such as ``int a;``, a code block, which is just a +bracket-enclosed list of statements, a ``';'``, which is a ``nop`` instruc= tion, +and an ``rvalue ';'``. + +Expressions +~~~~~~~~~~~ + +Allowed in the input code are C language expressions with a few exceptions +to simplify parsing. For instance, variable names such as ``RdV``, ``RssV`= `, +``PdV``, ``CsV``, and other idiomatic register names from Hexagon, are +reserved specifically for register arguments. These arguments then map to +``TCGv_i32`` or ``TCGv_i64`` depending on the register size. Similarly, ``= UiV``, +``riV``, etc. refer to immediate arguments and will map to C integers. + +Also, as mentioned earlier, the names ``PC``, ``SP``, ``FP``, etc. are use= d to +refer to Hexagon registers such as the program counter, stack pointer, and= frame +pointer seen here. Writes to these registers then correspond to assignments +``PC =3D ...``, and reads correspond to uses of the variable ``PC``. + +Moreover, another example of one such exception is the selective expansion= of +macros present in ``macros.h``. As an example, consider the ``fABS`` macro= which +in plain C is defined as + +:: + + #define fABS(A) (((A) < 0) ? (-(A)) : (A)) + +and returns the absolute value of the argument ``A``. This macro is not in= cluded +in ``idef-parser/macros.inc`` and as such is not expanded and kept as a "c= all" +``fABS(...)``. Reason being, that ``fABS`` is easier to match and map to +``tcg_gen_abs_``, compared to the full ternary expression above. Lo= ads of +macros in ``macros.h`` are kept unexpanded to aid in parsing, as seen in t= he +example above, for more information see ``idef-parser/idef-parser.lex``. + +Finally, in mapping these input expressions to tinycode generators, idef-p= arser +tries to perform as much as possible in plain C. Such as, performing binary +operations in C instead of tinycode generators, thus effectively constant +folding the expression. + +Variables and Variable Declarations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Similarly to C, variables in the input code must be explicitly declared, s= uch as +``int var1;`` which declares an uninitialized variable ``var1``. Initializ= ation +``int var2 =3D 0;`` is also allowed and behaves as expected. In tinycode +generators the previous declarations are mapped to + +:: + + int var1; -> TCGv_i32 var1 =3D tcg_temp_local_new_i32(); + + int var2 =3D 0; -> TCGv_i32 var1 =3D tcg_temp_local_new_i32= (); + tcg_gen_movi_i32(j, ((int64_t) 0ULL)); + +which are later automatically freed at the end of the function they're dec= lared +in. Contrary to C, we only allow variables to be declared with an integer = type +specified in the following table (without permutation of keywords) + +:: + + type bit-width signedness + ---------------------------------------------------------- + int 32 signed + signed + signed int + + unsigned 32 unsigned + unsigned int + + long 64 signed + long int + signed long + signed long int + + unsigned long 64 unsigned + unsigned long int + + long long 64 signed + long long int + signed long long + signed long long int + + unsigned long long 64 unsigned + unsigned long long int + + size[1,2,4,8][s,u]_t 8-64 signed or unsigned + +In idef-parser, variable names are matched by a generic ``VARID`` token, +which will feature the variable name as a decoration. For a variable decla= ration +idef-parser calls ``gen_varid_allocate`` with the ``VARID`` token to save = the +name, size, and bit width of the newly declared variable. In addition, this +function also ensures that variables aren't declared multiple times, and p= rints +and error message if that is the case. Upon use of a variable, the ``VARID= `` +token is used to lookup the size and bit width of the variable. + +Type System +~~~~~~~~~~~ + +idef-parser features a simple type system which is used to correctly imple= ment +the signedness and bit width of the operations. + +The type of each ``rvalue`` is determined by two attributes: its bit width +(``unsigned bit_width``) and its signedness (``HexSignedness signedness``). + +For each operation, the type of ``rvalue``\ s influence the way in which t= he +operands are handled and emitted. For example a right shift between signed +operators will be an arithmetic shift, while one between unsigned operators +will be a logical shift. If one of the two operands is signed, and the oth= er +is unsigned, the operation will be signed. + +The bit width also influences the outcome of the operations, in particular= while +the input languages features a fine granularity type system, with types of= 8, +16, 32, 64 (and more for vectorial instructions) bits, the tinycode only +features 32 and 64 bit widths. We propagate as much as possible the fine +granularity type, until the value has to be used inside an operation betwe= en +``rvalue``\ s; in that case if one of the two operands is greater than 32 = bits +we promote the whole operation to 64 bit, taking care of properly extendin= g the +two operands. Fortunately, the most critical instructions already feature +explicit casts and zero/sign extensions which are properly propagated down= to +our parser. + +The combination of ``rvalue``\ s are handled through the use of the +``gen_bin_op`` and ``gen_bin_cmp`` helper functions. These two functions h= andle +the appropriate compile-time or run-time emission of operations to perform= the +required computation. + +Control Statements +~~~~~~~~~~~~~~~~~~ + +``control_statement``\ s are all the statements which modify the order of +execution of the generated code according to input parameters. They are ex= panded +by the following grammar rule: + +:: + + control_statement : frame_check + | cancel_statement + | if_statement + | for_statement + | fpart1_statement + +``if_statement``\ s require the emission of labels and branch instructions= which +effectively perform conditional jumps (``tcg_gen_brcondi``) according to t= he +value of an expression. Note, the tinycode generators we produce for condi= tional +statements do not perfectly mirror what would be expected in C, for instan= ce we +do not reproduce short-circuiting of the ``&&`` operator, and use of the `= `||`` +operator is disallowed. All the predicated instructions, and in general al= l the +instructions where there could be alternative values assigned to an ``lval= ue``, +like C-style ternary expressions: + +:: + + rvalue : rvalue QMARK rvalue COLON rvalue + +are handled using the conditional move tinycode instruction +(``tcg_gen_movcond``), which avoids the additional complexity of managing = labels +and jumps. + +Instead, regarding the ``for`` loops, exploiting the fact that they always +iterate on immediate values, therefore their iteration ranges are always k= nown +at compile time, we implemented those emitting plain C ``for`` loops. This= is +possible because the loops will be executed in the QEMU code, leading to t= he +consequential unrolling of the for loop, since the tinycode generator +instructions will be executed multiple times, and the respective generated +tinycode will represent the unrolled execution of the loop. + +Parsing Context +~~~~~~~~~~~~~~~ + +All the helper functions in ``idef-parser.y`` carry two fixed parameters, = which +are the parsing context ``c`` and the ``YYLLOC`` location information. The +context is explicitly passed to all the functions because the parser we ge= nerate +is a reentrant one, meaning that it does not have any global variable, and +therefore the instruction compilation could easily be parallelized in the +future. Finally for each rule we propagate information about the location = of the +involved tokens to generate pretty error reporting, able to highlight the +portion of the input code which generated each error. + +Debugging +--------- + +Developing the idef-parser can lead to two types of errors: compile-time e= rrors +and parsing errors. + +Compile-time errors in Bison-generated parsers are usually due to conflict= s in +the described grammar. Conflicts forbid the grammar to produce a unique +derivation tree, thus must be solved (except for the dangling else problem, +which is marked as expected through the ``%expect 1`` Bison option). + +For solving conflicts you need a basic understanding of `shift-reduce conf= licts +`__ +and `reduce-reduce conflicts +`__, +then, if you are using a Bison version > 3.7.1 you can ask Bison to genera= te +some counterexamples which highlight ambiguous derivations, passing the +``-Wcex`` option to Bison. In general shift/reduce conflicts are solved by +redesigning the grammar in an unambiguous way or by setting the token prio= rity +correctly, while reduce/reduce conflicts are solved by redesigning the +interested part of the grammar. + +Run-time errors can be divided between lexing and parsing errors, lexing e= rrors +are hard to detect, since the ``var`` token will catch everything which is= not +catched by other tokens, but easy to fix, because most of the time a simple +regex editing will be enough. + +idef-parser features a fancy parsing error reporting scheme, which for each +parsing error reports the fragment of the input text which was involved in= the +parsing rule that generated an error. + +Implementing an instruction goes through several sequential steps, here ar= e some +suggestions to make each instruction proceed to the next step. + +- not-emitted + + Means that the parsing of the input code relative to that instruction f= ailed, + this could be due to a lexical error or to some mismatch between the or= der of + valid tokens and a parser rule. You should check that tokens are correc= tly + identified and mapped, and that there is a rule matching the token sequ= ence + that you need to parse. + +- emitted + + This instruction class contains all the instructions which are emitted = but + fail to compile when included in QEMU. The compilation errors are shown= by + the QEMU building process and will lead to fixing the bug. Most common + errors regard the mismatch of parameters for tinycode generator functio= ns, + which boil down to errors in the idef-parser type system. + +- compiled + + These instruction generate valid tinycode generator code, which however= fail + the QEMU or the harness tests, these cases must be handled manually by + looking into the failing tests and looking at the generated tinycode + generator instruction and at the generated tinycode itself. Tip: handle= the + failing harness tests first, because they usually feature only a single + instruction, thus will require less execution trace navigation. If a + multi-threaded test fail, fixing all the other tests will be the easier + option, hoping that the multi-threaded one will be indirectly fixed. + + An example of debugging this type of failure is provided in the followi= ng + section. + +- tests-passed + + This is the final goal for each instruction, meaning that the instructi= on + passes the test suite. + +Another approach to fix QEMU system test, where many instructions might fa= il, is +to compare the execution trace of your implementation with the reference +implementations already present in QEMU. To do so you should obtain a QEMU= build +where the instruction pass the test, and run it with the following command: + +:: + + sudo unshare -p sudo -u bash -c \ + 'env -i -d cpu ' + +And do the same for your implementation, the generated execution traces wi= ll be +inherently aligned and can be inspected for behavioral differences using t= he +``diff`` tool. + +Example of debugging erroneous tinycode generator code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The goal of this section is to provide a complete example of debugging +incorrectly emitted tinycode generator for a single instruction. + +Let's first introduce a bug in the tinycode generator of the ``A2_add`` +instruction, + +:: + + void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 = RdV, + TCGv_i32 RsV, TCGv_i32 RtV) + /* RdV=3DRsV+RtV;} */ + { + TCGv_i32 tmp_0 =3D tcg_temp_new_i32(); + tcg_gen_add_i32(tmp_0, RsV, RsV); + tcg_gen_mov_i32(RdV, tmp_0); + tcg_temp_free_i32(tmp_0); + } + +Here the bug, albeit hard to spot, is in ``tcg_gen_add_i32(tmp_0, RsV, RsV= );`` +where we compute ``RsV + RsV`` instead of ``RsV + RtV``, as would be expec= ted. +This particular bug is a bit tricky to pinpoint when debugging, since the +``A2_add`` instruction is so ubiquitous. As a result, pretty much all test= s will +fail and therefore not provide a lot of information about the bug. + +For example, let's run the ``check-tcg`` tests + +:: + + make check-tcg TIMEOUT=3D1200 \ + DOCKER_IMAGE=3Ddebian-hexagon-cross \ + ENGINE=3Dpodman V=3D1 \ + DOCKER_CROSS_CC_GUEST=3Dhexagon-unknown-linux-musl-clang + +In the output, we find a failure in the very first test case ``float_convs= `` +due to a segmentation fault. Similarly, all harness and libc tests will fa= il as +well. At this point we have no clue where the actual bug lies, and need to= start +ruling out instructions. As such a good starting point is to utilize the d= ebug +options ``-d in_asm,cpu`` of QEMU to inspect the Hexagon instructions bein= g run, +alongside the CPU state. We additionally need a working version of the emu= lator +to compare our buggy CPU state against, running + +:: + + meson configure -Dhexagon_idef_parser_enabled=3Dfalse + +will disable the idef-parser for all instructions and fallback on manual +tinycode generator overrides, or on helper function implementations. Recom= piling +gives us ``qemu-hexagon`` which passes all tests. If ``qemu-heaxgon-buggy`= ` is +our binary with the incorrect tinycode generators, we can compare the CPU = state +between the two versions + +:: + + ./qemu-hexagon-buggy -d in_asm,cpu float_convs &> out_buggy + ./qemu-hexagon -d in_asm,cpu float_convs &> out_working + +Looking at ``diff -u out_buggy out_working`` shows us that the CPU state b= egins +to diverge on line 141, with an incorrect value in the ``R1`` register + +:: + + @@ -138,7 +138,7 @@ + + General Purpose Registers =3D { + r0 =3D 0x4100f9c0 + - r1 =3D 0x00042108 + + r1 =3D 0x00000000 + r2 =3D 0x00021084 + r3 =3D 0x00000000 + r4 =3D 0x00000000 + +If we also look into ``out_buggy`` directly we can inspect the input assem= bly +which the caused the incorrect CPU state, around line 141 we find + +:: + + 116 | ---------------- + 117 | IN: _start_c + 118 | 0x000210b0: 0xa09dc002 { allocframe(R29,#0x10):raw } + ... | ... + 137 | 0x000210fc: 0x5a00c4aa { call PC+2388 } + 138 | + 139 | General Purpose Registers =3D { + 140 | r0 =3D 0x4100fa70 + 141 | r1 =3D 0x00042108 + 142 | r2 =3D 0x00021084 + 143 | r3 =3D 0x00000000 + +Importantly, we see some Hexagon assembly followed by a dump of the CPU st= ate, +now the CPU state is actually dumped before the input assembly above is ra= n. +As such, we are actually interested in the instructions ran before this. + +Scrolling up a bit, we find + +:: + + 54 | ---------------- + 55 | IN: _start + 56 | 0x00021088: 0x6a09c002 { R2 =3D C9/pc } + 57 | 0x0002108c: 0xbfe2ff82 { R2 =3D add(R2,#0xfffffffc) } + 58 | 0x00021090: 0x9182c001 { R1 =3D memw(R2+#0x0) } + 59 | 0x00021094: 0xf302c101 { R1 =3D add(R2,R1) } + 60 | 0x00021098: 0x7800c01e { R30 =3D #0x0 } + 61 | 0x0002109c: 0x707dc000 { R0 =3D R29 } + 62 | 0x000210a0: 0x763dfe1d { R29 =3D and(R29,#0xfffffff0) } + 63 | 0x000210a4: 0xa79dfdfe { memw(R29+#0xfffffff8) =3D R29 } + 64 | 0x000210a8: 0xbffdff1d { R29 =3D add(R29,#0xfffffff8) } + 65 | 0x000210ac: 0x5a00c002 { call PC+4 } + 66 | + 67 | General Purpose Registers =3D { + 68 | r0 =3D 0x00000000 + 69 | r1 =3D 0x00000000 + 70 | r2 =3D 0x00000000 + 71 | r3 =3D 0x00000000 + +Remember, the instructions on lines 56-65 are ran on the CPU state shown b= elow +instructions, and as the CPU state has not diverged at this point, we know= the +starting state is accurate. The bug must then lie within the instructions = shown +here. Next we may notice that ``R1`` is only touched by lines 57 and 58, t= hat is +by + +:: + + 58 | 0x00021090: 0x9182c001 { R1 =3D memw(R2+#0x0) } + 59 | 0x00021094: 0xf302c101 { R1 =3D add(R2,R1) } + +Therefore, we are either dealing with an correct load instruction +``R1 =3D memw(R2+#0x0)`` or with an incorrect add ``R1 =3D add(R2,R1)``. A= t this +point it might be easy enough to go directly to the emitted code for the +instructions mentioned and look for bugs, but we could also run +``./qemu-heaxgon -d op,in_asm float_conv`` where we find for the following +tinycode for the Hexagon ``add`` instruction + +:: + + ---- 00021094 + mov_i32 pkt_has_store_s1,$0x0 + add_i32 tmp0,r2,r2 + mov_i32 loc2,tmp0 + mov_i32 new_r1,loc2 + mov_i32 r1,new_r1 + +Here we have finally located our bug ``add_i32 tmp0,r2,r2``. + +Limitations and Future Development +---------------------------------- + +The main limitation of the current parser is given by the syntax-driven na= ture +of the Bison-generated parsers. This has the severe implication of only be= ing +able to generate code in the order of evaluation of the various rules, wit= hout, +in any case, being able to backtrack and alter the generated code. + +An example limitation is highlighted by this statement of the input langua= ge: + +:: + + { (PsV=3D=3D0xff) ? (PdV=3D0xff) : (PdV=3D0x00); } + +This ternary assignment, when written in this form requires us to emit some +proper control flow statements, which emit a jump to the first or to the s= econd +code block, whose implementation is extremely convoluted, because when mat= ching +the ternary assignment, the code evaluating the two assignments will be al= ready +generated. + +Instead we pre-process that statement, making it become: + +:: + + { PdV =3D ((PsV=3D=3D0xff)) ? 0xff : 0x00; } + +Which can be easily matched by the following parser rules: + +:: + + statement | rvalue ';' + + rvalue : rvalue QMARK rvalue COLON rvalue + | rvalue EQ rvalue + | LPAR rvalue RPAR + | assign_statement + | IMM + + assign_statement : pred ASSIGN rvalue + +Another example that highlight the limitation of the flex/bison parser can= be +found even in the add operation we already saw: + +:: + + TCGv_i32 tmp_0 =3D tcg_temp_new_i32(); + tcg_gen_add_i32(tmp_0, RsV, RtV); + tcg_gen_mov_i32(RdV, tmp_0); + +The fact that we cannot directly use ``RdV`` as the destination of the sum= is a +consequence of the syntax-driven nature of the parser. In fact when we par= se the +assignment, the ``rvalue`` token, representing the sum has already been re= duced, +and thus its code emitted and unchangeable. We rely on the fact that QEMU = will +optimize our code reducing the useless move operations and the relative +temporaries. + +A possible improvement of the parser regards the support for vectorial +instructions and floating point instructions, which will require the exten= sion +of the scanner, the parser, and a partial re-design of the type system, al= lowing +to build the vectorial semantics over the available vectorial tinycode gen= erator +primitives. + +A more radical improvement will use the parser, not to generate directly t= he +tinycode generator code, but to generate an intermediate representation li= ke the +LLVM IR, which in turn could be compiled using the clang TCG backend. That= code +could be furtherly optimized, overcoming the limitations of the syntax-dri= ven +parsing and could lead to a more optimized generated code. diff --git a/target/hexagon/README b/target/hexagon/README index 372e24747c..6cb5affddb 100644 --- a/target/hexagon/README +++ b/target/hexagon/README @@ -27,6 +27,10 @@ Hexagon-specific code are encode*.def Encoding patterns for each instruction iclass.def Instruction class definitions used to dete= rmine legal VLIW slots for each instruction + qemu/target/hexagon/idef-parser + Parser that, given the high-level definitions of an instruction, + produces a C function generating equivalent tiny code instructions. + See README.rst. qemu/linux-user/hexagon Helpers for loading the ELF file and making Linux system calls, signals, etc @@ -47,6 +51,7 @@ header files in /target/hexagon gen_tcg_funcs.py -> tcg_funcs_generated.c.inc gen_tcg_func_table.py -> tcg_func_table_generated.c.inc gen_helper_funcs.py -> helper_funcs_generated.c.inc + gen_idef_parser_funcs.py -> idef_parser_input.h =20 Qemu helper functions have 3 parts DEF_HELPER declaration indicates the signature of the helper --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223933; cv=none; d=zohomail.com; s=zohoarc; b=mPIqly9TZ8h5nwgByHLk73noBerhrnDPfwKX4S0mE0crqba8Oz7ORM5uBWeHl78S0jXYf+/CxoeLEXNWW9/VvmBzAOnEHonvVXEyGke+9WZcnuxtxbZnW0AZFiLc//NZRnqgENAqiXKDlxnhf5l9tnPiV/JZzYgqV4FUsP8q/Vs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223933; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1pv6A7MoBkzjXsDL0IjGKUMxac2muHq/MHQLgAv1t4I=; b=DF7ObarI/FFN+d+NSguXvZ0sT68t7Vel4Ej+tuPCN1hklQk2+hLS2VBcbM2mtE8krD4DGBwobq2qxyY1QG4FcyJxByn4KwPotxCcMa85kasutM68neKAk4jg3AtxfYgzkFPHFR+7+pFJG4NKfUHRoPp96cOIS+QoA2r4DDUFTrU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167122393301547.074172471872544; Fri, 16 Dec 2022 12:52:13 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Hdz-0002kx-PH; Fri, 16 Dec 2022 15:49:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdx-0002jx-Ow for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6Hdu-0004P4-La for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:21 -0500 Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGGlYxR000436; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg3f8w3de-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:14 +0000 Received: from pps.filterd (NALASPPMTA05.qualcomm.com [127.0.0.1]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgROh020154; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 3mgwb1gmpq-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA05.qualcomm.com (NALASPPMTA05.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKhTx1021015; Fri, 16 Dec 2022 20:49:13 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 2BGKnDog028292; Fri, 16 Dec 2022 20:49:13 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 07A0750011B; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=1pv6A7MoBkzjXsDL0IjGKUMxac2muHq/MHQLgAv1t4I=; b=RFr2YZx+sW7wdeCWEgDxyVxdXVOIZ906BkhQf4B4d+mZbx4g5N49QKL7WpN3iltaYx7O c/M5Xi9T4tezyTspyWssSwZjhlm2zivuGmXn8iC6rvBM4FgU9f9YYvIZJ1whkVvt0Uvk C6sbuM87RU3zHbtkOo72b3QUfVUP2yLdtxAineo6sgmgcHCIatFrMJW/GjXyNUPDp3Ft 1SwJPiPpoYYaTUz4bVyWpJVfBxlBnZFUnVIBXCi+GFa2H5qDHEEkBnccZjc9ZoNBRdzD xTDKcg0aEbFF0cYS0hIG7xAY+TddxzAi5FpCrRwRVZjd1zOg3+c6NLOVJGIOMHaefR6I ow== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Paolo Montesel , Alessandro Di Federico Subject: [PULL 14/21] target/hexagon: make slot number an unsigned Date: Fri, 16 Dec 2022 12:48:38 -0800 Message-Id: <20221216204845.19290-15-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: _DiVcxt8Lcp_grnF5ED5T6lhr8e3o6m4 X-Proofpoint-ORIG-GUID: _DiVcxt8Lcp_grnF5ED5T6lhr8e3o6m4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1011 lowpriorityscore=0 spamscore=0 impostorscore=0 mlxlogscore=291 adultscore=0 phishscore=0 bulkscore=0 mlxscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223934250100003 From: Paolo Montesel Signed-off-by: Alessandro Di Federico Signed-off-by: Paolo Montesel Signed-off-by: Taylor Simpson Acked-by: Richard Henderson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-4-anjo@rev.ng> --- target/hexagon/macros.h | 2 +- target/hexagon/genptr.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 903503540e..1a31542010 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -202,7 +202,7 @@ #define LOAD_CANCEL(EA) do { CANCEL; } while (0) =20 #ifdef QEMU_GENERATE -static inline void gen_pred_cancel(TCGv pred, int slot_num) +static inline void gen_pred_cancel(TCGv pred, uint32_t slot_num) { TCGv slot_mask =3D tcg_temp_new(); TCGv tmp =3D tcg_temp_new(); diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index a4a79c8454..4cd2a2aeb9 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -30,7 +30,8 @@ #include "gen_tcg.h" #include "gen_tcg_hvx.h" =20 -static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int sl= ot) +static inline void gen_log_predicated_reg_write(int rnum, TCGv val, + uint32_t slot) { TCGv zero =3D tcg_constant_tl(0); TCGv slot_mask =3D tcg_temp_new(); @@ -62,7 +63,8 @@ static inline void gen_log_reg_write(int rnum, TCGv val) } } =20 -static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int = slot) +static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, + uint32_t slot) { TCGv val32 =3D tcg_temp_new(); TCGv zero =3D tcg_constant_tl(0); @@ -394,54 +396,54 @@ static inline void gen_store_conditional8(DisasContex= t *ctx, tcg_gen_movi_tl(hex_llsc_addr, ~0); } =20 -static inline void gen_store32(TCGv vaddr, TCGv src, int width, int slot) +static inline void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t s= lot) { tcg_gen_mov_tl(hex_store_addr[slot], vaddr); tcg_gen_movi_tl(hex_store_width[slot], width); tcg_gen_mov_tl(hex_store_val32[slot], src); } =20 -static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, int = slot) +static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) { gen_store32(vaddr, src, 1, slot); } =20 -static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = int slot) +static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store1(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, int = slot) +static inline void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) { gen_store32(vaddr, src, 2, slot); } =20 -static inline void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = int slot) +static inline void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store2(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, int = slot) +static inline void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) { gen_store32(vaddr, src, 4, slot); } =20 -static inline void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = int slot) +static inline void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store4(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, = int slot) +static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, = uint32_t slot) { tcg_gen_mov_tl(hex_store_addr[slot], vaddr); tcg_gen_movi_tl(hex_store_width[slot], 8); tcg_gen_mov_i64(hex_store_val64[slot], src); } =20 -static inline void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, = int slot) +static inline void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, = uint32_t slot) { TCGv_i64 tmp =3D tcg_constant_i64(src); gen_store8(cpu_env, vaddr, tmp, slot); --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223829; cv=none; d=zohomail.com; s=zohoarc; b=nwZk6XXW9xeeHQaB/x82UQsQkpjRIP4U8x6ReCH5rGu2bRKGnVeRFq3OzAZ/vPlWTkf5Pw9ahrsRmA4O1ftLCGVQ5CGnrstLORn009xf1C7C7ZDk+EbgbiH6Y35H8rfnFCtKv3rIwpAAf+Nbm+qBD7X2vRjT2Xyh05QjGUCQHCs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223829; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=n5zduhjD3QRby0v1NqV/tM1QXrh/j4ZQCTnGMhAmn90=; b=N1M7LGSG+f/P1Q+gVMKpqFLTGHJgkMvj+V3925kvoq67pBvVndhyOQisiSEps+ykrlbDc7ICPGmV/3twc9kQbKMYAs7fmM/xGnxoyy5aFg8T92klEyZkGtco3rPYnyN+xejhk4jlvpjCGDQvUlaYtjX2AMLghwfoRTxzFmY97Kk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167122382974712.710808965374326; Fri, 16 Dec 2022 12:50:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeJ-0002vy-1p; Fri, 16 Dec 2022 15:49:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He9-0002qU-Ci for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He4-0004Q2-0t for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKUk7D023984; Fri, 16 Dec 2022 20:49:16 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mgmv11yrd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKhYTC030818; Fri, 16 Dec 2022 20:49:15 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6w-1; Fri, 16 Dec 2022 20:49:15 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgg7b030048; Fri, 16 Dec 2022 20:49:15 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDgF005676; Fri, 16 Dec 2022 20:49:15 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 0A83850011C; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=n5zduhjD3QRby0v1NqV/tM1QXrh/j4ZQCTnGMhAmn90=; b=dFXrTU0GHzwHVle07Ix6T5AHpq99L8IJsq7FGM8idNgDBvMpCbPLYuEK2+p43pr3EcLl 3UqXXBoXScZZTeJrIk1UvZmwLVbQE3YVn6M66GnsNbkuPufJrrynaYF+v7jxa332y5Fw ROaUDp58cbv9N6ZtUByY1bqzRJzQaoRJXquZU8LZ++cD/zHVDGaJDWo6nP9ykPBr6zya WfF+4UIiR4QNFyBArGSDqZhWczN7wDKd4Y1tksNsFZDZojta48RDLm/BHJkptdjGhLYS BYf2v+/vm+PST4aDVNXseRle03PB4AzM3MMhC1F0QrhdsdH8XVLqJxzpGdALDJE1ILcJ xg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Paolo Montesel , Alessandro Di Federico Subject: [PULL 15/21] target/hexagon: make helper functions non-static Date: Fri, 16 Dec 2022 12:48:39 -0800 Message-Id: <20221216204845.19290-16-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: xjjOgp1-wvlwyC1vb0mOLn0Pt8zBuquY X-Proofpoint-ORIG-GUID: xjjOgp1-wvlwyC1vb0mOLn0Pt8zBuquY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxscore=0 mlxlogscore=713 adultscore=0 phishscore=0 impostorscore=0 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223831786100003 From: Paolo Montesel Make certain helper functions non-static, making them available outside genptr.c. These functions are required by code generated by the idef-parser. This commit also makes some functions in op_helper.c non-static in order to avoid having them marked as unused when using the idef-parser generated code. Signed-off-by: Alessandro Di Federico Signed-off-by: Paolo Montesel Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-5-anjo@rev.ng> --- target/hexagon/genptr.h | 23 +++++++++++++++++++ target/hexagon/op_helper.h | 37 +++++++++++++++++++++++++++++++ target/hexagon/genptr.c | 45 ++++++++++++++++++++++---------------- target/hexagon/op_helper.c | 29 +++++++++++------------- 4 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 target/hexagon/op_helper.h diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h index c158005d2a..e126c46255 100644 --- a/target/hexagon/genptr.h +++ b/target/hexagon/genptr.h @@ -19,7 +19,30 @@ #define HEXAGON_GENPTR_H =20 #include "insn.h" +#include "tcg/tcg.h" +#include "translate.h" =20 extern const SemanticInsn opcode_genptr[]; =20 +void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot); +void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot); +void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot); +void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot); +void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, uint32_t slot); +void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot); +void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot); +void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot); +void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, uint32_t slot); +TCGv gen_read_preg(TCGv pred, uint8_t num); +void gen_log_reg_write(int rnum, TCGv val); +void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val); +TCGv gen_8bitsof(TCGv result, TCGv value); +void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src); +TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign); +TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign); +TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign); +void gen_set_half(int N, TCGv result, TCGv src); +void gen_set_half_i64(int N, TCGv_i64 result, TCGv src); +void probe_noshuf_load(TCGv va, int s, int mi); + #endif diff --git a/target/hexagon/op_helper.h b/target/hexagon/op_helper.h new file mode 100644 index 0000000000..02347edee8 --- /dev/null +++ b/target/hexagon/op_helper.h @@ -0,0 +1,37 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * + * 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_OP_HELPER_H +#define HEXAGON_OP_HELPER_H + +/* Misc functions */ +void cancel_slot(CPUHexagonState *env, uint32_t slot); +void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof, target_ulo= ng addr); + +uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, target_ulong vaddr); +uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, target_ulong vaddr= ); +uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, target_ulong vaddr= ); +uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, target_ulong vaddr= ); + +void log_reg_write(CPUHexagonState *env, int rnum, + target_ulong val, uint32_t slot); +void log_store64(CPUHexagonState *env, target_ulong addr, + int64_t val, int width, int slot); +void log_store32(CPUHexagonState *env, target_ulong addr, + target_ulong val, int width, int slot); + +#endif diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 4cd2a2aeb9..3fe279ce8c 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -29,6 +29,13 @@ #undef QEMU_GENERATE #include "gen_tcg.h" #include "gen_tcg_hvx.h" +#include "genptr.h" + +TCGv gen_read_preg(TCGv pred, uint8_t num) +{ + tcg_gen_mov_tl(pred, hex_pred[num]); + return pred; +} =20 static inline void gen_log_predicated_reg_write(int rnum, TCGv val, uint32_t slot) @@ -54,7 +61,7 @@ static inline void gen_log_predicated_reg_write(int rnum,= TCGv val, tcg_temp_free(slot_mask); } =20 -static inline void gen_log_reg_write(int rnum, TCGv val) +void gen_log_reg_write(int rnum, TCGv val) { tcg_gen_mov_tl(hex_new_value[rnum], val); if (HEX_DEBUG) { @@ -116,7 +123,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 v= al) } } =20 -static inline void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv va= l) +void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val) { TCGv base_val =3D tcg_temp_new(); =20 @@ -274,7 +281,7 @@ static inline void gen_write_ctrl_reg_pair(DisasContext= *ctx, int reg_num, } } =20 -static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign) +TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign) { if (sign) { tcg_gen_sextract_tl(result, src, N * 8, 8); @@ -284,7 +291,7 @@ static TCGv gen_get_byte(TCGv result, int N, TCGv src, = bool sign) return result; } =20 -static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign) +TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign) { TCGv_i64 res64 =3D tcg_temp_new_i64(); if (sign) { @@ -298,7 +305,7 @@ static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i= 64 src, bool sign) return result; } =20 -static inline TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign) +TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign) { if (sign) { tcg_gen_sextract_tl(result, src, N * 16, 16); @@ -308,12 +315,12 @@ static inline TCGv gen_get_half(TCGv result, int N, T= CGv src, bool sign) return result; } =20 -static inline void gen_set_half(int N, TCGv result, TCGv src) +void gen_set_half(int N, TCGv result, TCGv src) { tcg_gen_deposit_tl(result, result, src, N * 16, 16); } =20 -static inline void gen_set_half_i64(int N, TCGv_i64 result, TCGv src) +void gen_set_half_i64(int N, TCGv_i64 result, TCGv src) { TCGv_i64 src64 =3D tcg_temp_new_i64(); tcg_gen_extu_i32_i64(src64, src); @@ -321,7 +328,7 @@ static inline void gen_set_half_i64(int N, TCGv_i64 res= ult, TCGv src) tcg_temp_free_i64(src64); } =20 -static void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src) +void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src) { TCGv_i64 src64 =3D tcg_temp_new_i64(); tcg_gen_extu_i32_i64(src64, src); @@ -396,60 +403,60 @@ static inline void gen_store_conditional8(DisasContex= t *ctx, tcg_gen_movi_tl(hex_llsc_addr, ~0); } =20 -static inline void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t s= lot) +void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot) { tcg_gen_mov_tl(hex_store_addr[slot], vaddr); tcg_gen_movi_tl(hex_store_width[slot], width); tcg_gen_mov_tl(hex_store_val32[slot], src); } =20 -static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) +void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot) { gen_store32(vaddr, src, 1, slot); } =20 -static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) +void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store1(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) +void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot) { gen_store32(vaddr, src, 2, slot); } =20 -static inline void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) +void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store2(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint= 32_t slot) +void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, uint32_t slot) { gen_store32(vaddr, src, 4, slot); } =20 -static inline void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, = uint32_t slot) +void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot) { TCGv tmp =3D tcg_constant_tl(src); gen_store4(cpu_env, vaddr, tmp, slot); } =20 -static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, = uint32_t slot) +void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, uint32_t slot) { tcg_gen_mov_tl(hex_store_addr[slot], vaddr); tcg_gen_movi_tl(hex_store_width[slot], 8); tcg_gen_mov_i64(hex_store_val64[slot], src); } =20 -static inline void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, = uint32_t slot) +void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, uint32_t slot) { TCGv_i64 tmp =3D tcg_constant_i64(src); gen_store8(cpu_env, vaddr, tmp, slot); } =20 -static TCGv gen_8bitsof(TCGv result, TCGv value) +TCGv gen_8bitsof(TCGv result, TCGv value) { TCGv zero =3D tcg_constant_tl(0); TCGv ones =3D tcg_constant_tl(0xff); @@ -1014,7 +1021,7 @@ static void vec_to_qvec(size_t size, intptr_t dstoff,= intptr_t srcoff) tcg_temp_free_i64(mask); } =20 -static void probe_noshuf_load(TCGv va, int s, int mi) +void probe_noshuf_load(TCGv va, int s, int mi) { TCGv size =3D tcg_constant_tl(s); TCGv mem_idx =3D tcg_constant_tl(mi); diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index aad0195eb6..35449ef524 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -29,6 +29,7 @@ #include "fma_emu.h" #include "mmvec/mmvec.h" #include "mmvec/macros.h" +#include "op_helper.h" =20 #define SF_BIAS 127 #define SF_MANTBITS 23 @@ -50,8 +51,8 @@ G_NORETURN void HELPER(raise_exception)(CPUHexagonState *= env, uint32_t excp) do_raise_exception_err(env, excp, 0); } =20 -static void log_reg_write(CPUHexagonState *env, int rnum, - target_ulong val, uint32_t slot) +void log_reg_write(CPUHexagonState *env, int rnum, + target_ulong val, uint32_t slot) { HEX_DEBUG_LOG("log_reg_write[%d] =3D " TARGET_FMT_ld " (0x" TARGET_FMT= _lx ")", rnum, val, val); @@ -82,8 +83,8 @@ static void log_pred_write(CPUHexagonState *env, int pnum= , target_ulong val) } } =20 -static void log_store32(CPUHexagonState *env, target_ulong addr, - target_ulong val, int width, int slot) +void log_store32(CPUHexagonState *env, target_ulong addr, + target_ulong val, int width, int slot) { HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx ", %" PRId32 " [0x08%" PRIx32 "])\n", @@ -93,8 +94,8 @@ static void log_store32(CPUHexagonState *env, target_ulon= g addr, env->mem_log_stores[slot].data32 =3D val; } =20 -static void log_store64(CPUHexagonState *env, target_ulong addr, - int64_t val, int width, int slot) +void log_store64(CPUHexagonState *env, target_ulong addr, + int64_t val, int width, int slot) { HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx ", %" PRId64 " [0x016%" PRIx64 "])\n", @@ -104,7 +105,7 @@ static void log_store64(CPUHexagonState *env, target_ul= ong addr, env->mem_log_stores[slot].data64 =3D val; } =20 -static void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof, +void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof, target_ulong addr) { HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr); @@ -541,32 +542,28 @@ static void check_noshuf(CPUHexagonState *env, uint32= _t slot, } } =20 -static uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, - target_ulong vaddr) +uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, target_ulong vaddr) { uintptr_t ra =3D GETPC(); check_noshuf(env, slot, vaddr, 1); return cpu_ldub_data_ra(env, vaddr, ra); } =20 -static uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, - target_ulong vaddr) +uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, target_ulong vaddr) { uintptr_t ra =3D GETPC(); check_noshuf(env, slot, vaddr, 2); return cpu_lduw_data_ra(env, vaddr, ra); } =20 -static uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, - target_ulong vaddr) +uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, target_ulong vaddr) { uintptr_t ra =3D GETPC(); check_noshuf(env, slot, vaddr, 4); return cpu_ldl_data_ra(env, vaddr, ra); } =20 -static uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, - target_ulong vaddr) +uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, target_ulong vaddr) { uintptr_t ra =3D GETPC(); check_noshuf(env, slot, vaddr, 8); @@ -1471,7 +1468,7 @@ void HELPER(vwhist128qm)(CPUHexagonState *env, int32_= t uiV) } } =20 -static void cancel_slot(CPUHexagonState *env, uint32_t slot) +void cancel_slot(CPUHexagonState *env, uint32_t slot) { HEX_DEBUG_LOG("Slot %d cancelled\n", slot); env->slot_cancelled |=3D (1 << slot); --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223786; cv=none; d=zohomail.com; s=zohoarc; b=lzDDGlWihoCwLpjoLos1Kr6amslZeYk5P6hiYr5HZ+DSRcRflhOknsAts05JGsLOMB4zc+2+2At1n17WEOune1hmwsUidJOpQZi7wUzvpZ+yd7poZdskyTpJlJaTt/frlyNHwSf4J6ovvX/wzxh6n2UuXq1ha93owje/jogZpas= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223786; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=iaC8G5rkIs15l+QPNmN1n1vwy5rD4m/lDduhmnhE4XA=; b=Wnwtu9tesWzcJLop4jxnpTFEdnuwf2JbjKmKzlNnrR+V8iG/2OMXdZl0xxaT5hqgk3dUrvwZ/CILdjl8W/LYYRfXzhfaa58/lDXOwpFmQUVRWVYRn9f5ZPByT9Lf1W/uukWynmSPGjv/j5bSpw/Q2pcV1tkmjiIui22B/wcXcM8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671223786720444.88291650642793; Fri, 16 Dec 2022 12:49:46 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6He9-0002qd-Mo; Fri, 16 Dec 2022 15:49:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He7-0002pS-8x for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:31 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PN-EF for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:30 -0500 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKBqgc003511; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mgmv11yra-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA03.qualcomm.com [127.0.0.1]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg7gd024658; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 3mgw6trnfd-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA03.qualcomm.com (NALASPPMTA03.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgl9l025329; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 2BGKnDEl000427; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 0D40950011D; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-type : content-transfer-encoding; s=qcppdkim1; bh=iaC8G5rkIs15l+QPNmN1n1vwy5rD4m/lDduhmnhE4XA=; b=hDkDQKUMn9WVhlIb3LknpSYX6rQc4BALHntmx5kodcaP+bPkHZc7xye/l8KyyukPzY/U jpNr5LqVNZBhOtkJZ2cHmrI+eQTj9lTxFesw/9ocjoncTT9CtQR3ZB/fEOVz9+KXWs7Q YEfl68yGiwyRfAc3XWNAzEWWLR/eiTQGvEuYMIzHx0xceDWg4wRoJQzyqqEsqA9er0N1 wEnfeWwcBr9iA59CO35Oe7GRckarPm9e4caNRsDI1zrmYVNSWDFAcKvUfqWUiVts8qAT rIQAtDhIRhajUJaq0BIOPxBatzI7/dr10qtrfniPIcNHulz1Ar6CLScfSxVoovD1ZEMO og== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, =?UTF-8?q?Niccol=C3=B2=20Izzo?= , Alessandro Di Federico , Anton Johansson Subject: [PULL 16/21] target/hexagon: introduce new helper functions Date: Fri, 16 Dec 2022 12:48:40 -0800 Message-Id: <20221216204845.19290-17-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: v1wakmaJczuvNTT0M4htTigwWk97FhQs X-Proofpoint-ORIG-GUID: v1wakmaJczuvNTT0M4htTigwWk97FhQs X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1011 mlxscore=0 mlxlogscore=250 adultscore=0 phishscore=0 impostorscore=0 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223787469100004 Content-Type: text/plain; charset="utf-8" From: Niccol=C3=B2 Izzo These helpers will be employed by the idef-parser generated code, to correctly implement instruction semantics. "Helper" functions, in the context of this patch, refers to functions which provide a manual TCG implementation of certain features. Signed-off-by: Alessandro Di Federico Signed-off-by: Niccol=C3=B2 Izzo Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-6-anjo@rev.ng> --- target/hexagon/genptr.h | 13 ++++ target/hexagon/macros.h | 9 +++ target/hexagon/genptr.c | 146 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 166 insertions(+), 2 deletions(-) diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h index e126c46255..591b059698 100644 --- a/target/hexagon/genptr.h +++ b/target/hexagon/genptr.h @@ -33,9 +33,22 @@ void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t s= rc, uint32_t slot); void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot); void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, uint32_t slot); void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, uint32_t slot); +TCGv gen_read_reg(TCGv result, int num); TCGv gen_read_preg(TCGv pred, uint8_t num); void gen_log_reg_write(int rnum, TCGv val); void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val); +void gen_set_usr_field(int field, TCGv val); +void gen_set_usr_fieldi(int field, int x); +void gen_set_usr_field_if(int field, TCGv val); +void gen_sat_i32(TCGv dest, TCGv source, int width); +void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width); +void gen_satu_i32(TCGv dest, TCGv source, int width); +void gen_satu_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width); +void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width); +void gen_sat_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width= ); +void gen_satu_i64(TCGv_i64 dest, TCGv_i64 source, int width); +void gen_satu_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int widt= h); +void gen_add_sat_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b); TCGv gen_8bitsof(TCGv result, TCGv value); void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src); TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign); diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 1a31542010..cd64bb8eec 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -197,7 +197,16 @@ #define MEM_STORE8(VA, DATA, SLOT) log_store64(env, VA, DATA, 8, SLOT) #endif =20 +#ifdef QEMU_GENERATE +static inline void gen_cancel(uint32_t slot) +{ + tcg_gen_ori_tl(hex_slot_cancelled, hex_slot_cancelled, 1 << slot); +} + +#define CANCEL gen_cancel(slot); +#else #define CANCEL cancel_slot(env, slot) +#endif =20 #define LOAD_CANCEL(EA) do { CANCEL; } while (0) =20 diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 3fe279ce8c..6cf2e0ed43 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -31,6 +31,12 @@ #include "gen_tcg_hvx.h" #include "genptr.h" =20 +TCGv gen_read_reg(TCGv result, int num) +{ + tcg_gen_mov_tl(result, hex_gpr[num]); + return result; +} + TCGv gen_read_preg(TCGv pred, uint8_t num) { tcg_gen_mov_tl(pred, hex_pred[num]); @@ -506,7 +512,7 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, i= nt pc_off, } } =20 -static void gen_set_usr_field(int field, TCGv val) +void gen_set_usr_field(int field, TCGv val) { tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_U= SR], val, @@ -514,7 +520,7 @@ static void gen_set_usr_field(int field, TCGv val) reg_field_info[field].width); } =20 -static void gen_set_usr_fieldi(int field, int x) +void gen_set_usr_fieldi(int field, int x) { if (reg_field_info[field].width =3D=3D 1) { target_ulong bit =3D 1 << reg_field_info[field].offset; @@ -1028,5 +1034,141 @@ void probe_noshuf_load(TCGv va, int s, int mi) gen_helper_probe_noshuf_load(cpu_env, va, size, mem_idx); } =20 +/* + * Note: Since this function might branch, `val` is + * required to be a `tcg_temp_local`. + */ +void gen_set_usr_field_if(int field, TCGv val) +{ + /* Sets the USR field if `val` is non-zero */ + if (reg_field_info[field].width =3D=3D 1) { + TCGv tmp =3D tcg_temp_new(); + tcg_gen_extract_tl(tmp, val, 0, reg_field_info[field].width); + tcg_gen_shli_tl(tmp, tmp, reg_field_info[field].offset); + tcg_gen_or_tl(hex_new_value[HEX_REG_USR], + hex_new_value[HEX_REG_USR], + tmp); + tcg_temp_free(tmp); + } else { + TCGLabel *skip_label =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_EQ, val, 0, skip_label); + gen_set_usr_field(field, val); + gen_set_label(skip_label); + } +} + +void gen_sat_i32(TCGv dest, TCGv source, int width) +{ + TCGv max_val =3D tcg_constant_tl((1 << (width - 1)) - 1); + TCGv min_val =3D tcg_constant_tl(-(1 << (width - 1))); + tcg_gen_smin_tl(dest, source, max_val); + tcg_gen_smax_tl(dest, dest, min_val); +} + +void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width) +{ + gen_sat_i32(dest, source, width); + tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest); +} + +void gen_satu_i32(TCGv dest, TCGv source, int width) +{ + TCGv max_val =3D tcg_constant_tl((1 << width) - 1); + TCGv zero =3D tcg_constant_tl(0); + tcg_gen_movcond_tl(TCG_COND_GTU, dest, source, max_val, max_val, sourc= e); + tcg_gen_movcond_tl(TCG_COND_LT, dest, source, zero, zero, dest); +} + +void gen_satu_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width) +{ + gen_satu_i32(dest, source, width); + tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest); +} + +void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width) +{ + TCGv_i64 max_val =3D tcg_constant_i64((1LL << (width - 1)) - 1LL); + TCGv_i64 min_val =3D tcg_constant_i64(-(1LL << (width - 1))); + tcg_gen_smin_i64(dest, source, max_val); + tcg_gen_smax_i64(dest, dest, min_val); +} + +void gen_sat_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width) +{ + TCGv_i64 ovfl_64; + gen_sat_i64(dest, source, width); + ovfl_64 =3D tcg_temp_new_i64(); + tcg_gen_setcond_i64(TCG_COND_NE, ovfl_64, dest, source); + tcg_gen_trunc_i64_tl(ovfl, ovfl_64); + tcg_temp_free_i64(ovfl_64); +} + +void gen_satu_i64(TCGv_i64 dest, TCGv_i64 source, int width) +{ + TCGv_i64 max_val =3D tcg_constant_i64((1LL << width) - 1LL); + TCGv_i64 zero =3D tcg_constant_i64(0); + tcg_gen_movcond_i64(TCG_COND_GTU, dest, source, max_val, max_val, sour= ce); + tcg_gen_movcond_i64(TCG_COND_LT, dest, source, zero, zero, dest); +} + +void gen_satu_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int widt= h) +{ + TCGv_i64 ovfl_64; + gen_satu_i64(dest, source, width); + ovfl_64 =3D tcg_temp_new_i64(); + tcg_gen_setcond_i64(TCG_COND_NE, ovfl_64, dest, source); + tcg_gen_trunc_i64_tl(ovfl, ovfl_64); + tcg_temp_free_i64(ovfl_64); +} + +/* Implements the fADDSAT64 macro in TCG */ +void gen_add_sat_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) +{ + TCGv_i64 sum =3D tcg_temp_local_new_i64(); + TCGv_i64 xor =3D tcg_temp_new_i64(); + TCGv_i64 cond1 =3D tcg_temp_new_i64(); + TCGv_i64 cond2 =3D tcg_temp_local_new_i64(); + TCGv_i64 cond3 =3D tcg_temp_new_i64(); + TCGv_i64 mask =3D tcg_constant_i64(0x8000000000000000ULL); + TCGv_i64 max_pos =3D tcg_constant_i64(0x7FFFFFFFFFFFFFFFLL); + TCGv_i64 max_neg =3D tcg_constant_i64(0x8000000000000000LL); + TCGv_i64 zero =3D tcg_constant_i64(0); + TCGLabel *no_ovfl_label =3D gen_new_label(); + TCGLabel *ovfl_label =3D gen_new_label(); + TCGLabel *ret_label =3D gen_new_label(); + + tcg_gen_add_i64(sum, a, b); + tcg_gen_xor_i64(xor, a, b); + + /* if (xor & mask) */ + tcg_gen_and_i64(cond1, xor, mask); + tcg_temp_free_i64(xor); + tcg_gen_brcondi_i64(TCG_COND_NE, cond1, 0, no_ovfl_label); + tcg_temp_free_i64(cond1); + + /* else if ((a ^ sum) & mask) */ + tcg_gen_xor_i64(cond2, a, sum); + tcg_gen_and_i64(cond2, cond2, mask); + tcg_gen_brcondi_i64(TCG_COND_NE, cond2, 0, ovfl_label); + tcg_temp_free_i64(cond2); + /* fallthrough to no_ovfl_label branch */ + + /* if branch */ + gen_set_label(no_ovfl_label); + tcg_gen_mov_i64(ret, sum); + tcg_gen_br(ret_label); + + /* else if branch */ + gen_set_label(ovfl_label); + tcg_gen_and_i64(cond3, sum, mask); + tcg_temp_free_i64(mask); + tcg_temp_free_i64(sum); + tcg_gen_movcond_i64(TCG_COND_NE, ret, cond3, zero, max_pos, max_neg); + tcg_temp_free_i64(cond3); + SET_USR_FIELD(USR_OVF, 1); + + gen_set_label(ret_label); +} + #include "tcg_funcs_generated.c.inc" #include "tcg_func_table_generated.c.inc" --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224150; cv=none; d=zohomail.com; s=zohoarc; b=Q8lfP57sSiVO8bJSyH99B9b/PqPqjHFNNshkIXWnUbYPO0kt3ccDjPwVNJO2F2kbS+fduN8N8CpQfqcvt0mL+CzLmA6S+vlcldmgc9m2NMZYzo3IRkzoGQjL/bYXNtW4rQ5N9pVGt50m4SwqRzLj1ovEu34DFdCq4x3aQCldZaI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224150; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=nCyn5yH4j8+pJDF69s8vpLNqWgSNk05pqlhgyTVel18=; b=Jj8hAgdCW3vO788Fqw+KocIy2sGmNcqYcL4shFnuHnvthXmKyXvWAIsde1ekPKtL5JQGDjrCurQ52WpqnDj/X5hhfFjJy/cptbTtlhGNFJoI1bYNE9fumD/1qSH7JASY6zXuJgSq+FKfAivZH1VugOsd2bqBj5hqySZWwCvhsXA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224150532109.524540094543; Fri, 16 Dec 2022 12:55:50 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeE-0002sO-Uo; Fri, 16 Dec 2022 15:49:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He9-0002qV-Fk for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He4-0004QE-5r for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGJQ8wL008464; Fri, 16 Dec 2022 20:49:16 GMT Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mgmv11yre-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:16 +0000 Received: from pps.filterd (NALASPPMTA01.qualcomm.com [127.0.0.1]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKfqnE029602; Fri, 16 Dec 2022 20:49:15 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 3mgwcgrm6r-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA01.qualcomm.com (NALASPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKnDZ4005666; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA01.qualcomm.com (PPS) with ESMTP id 2BGKnDDo005675; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 0FC6A50011E; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=nCyn5yH4j8+pJDF69s8vpLNqWgSNk05pqlhgyTVel18=; b=Z0RQ3Q5Ty9GpjrCYm91K8ZMFNJXXvpwHDn/aDmbDY/w0tiDCa044HsQ1CsspsAuRSKmg yHC7hXq3u+eN4L/uQJundALOc/S4FeIqmETv8Hshourt0Pr6hPMnqH9KDdvMhDXrACCA 97jHRnnIbZ6qdK1/DohTZD70R/cEBWTjKmklJSf1rFfZLv+N+n38+SQhrLndfmN9EKAK xHUOdj9LhfSw2U4rRRfxn+rNN1CmIkel177wAYkrt0bE2xfEQxX/e3GkHDr9Rwi6uf76 LUj8E8RzCreuKya9lsF+5KteildvVzyOpbJrEzPcGu4oQBjgkcB5cl6MAR57LF0MW0HB Cg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Alessandro Di Federico , Anton Johansson Subject: [PULL 17/21] target/hexagon: prepare input for the idef-parser Date: Fri, 16 Dec 2022 12:48:41 -0800 Message-Id: <20221216204845.19290-18-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: rJiV_6GelU79adVSzVpoAjTYajMSo8y8 X-Proofpoint-ORIG-GUID: rJiV_6GelU79adVSzVpoAjTYajMSo8y8 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 phishscore=0 impostorscore=0 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224152263100003 From: Alessandro Di Federico Introduce infrastructure necessary to produce a file suitable for being parsed by the idef-parser. A build option is also added to fully disable the output of idef-parser, which is useful for debugging. Signed-off-by: Alessandro Di Federico Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-8-anjo@rev.ng> --- meson_options.txt | 3 + target/hexagon/gen_idef_parser_funcs.py | 130 ++++++++++++++++++++++ target/hexagon/idef-parser/macros.inc | 140 ++++++++++++++++++++++++ target/hexagon/idef-parser/prepare | 24 ++++ target/hexagon/meson.build | 20 ++++ 5 files changed, 317 insertions(+) create mode 100644 target/hexagon/gen_idef_parser_funcs.py create mode 100644 target/hexagon/idef-parser/macros.inc create mode 100755 target/hexagon/idef-parser/prepare diff --git a/meson_options.txt b/meson_options.txt index 4b749ca549..559a571b6b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -321,3 +321,6 @@ option('profiler', type: 'boolean', value: false, description: 'profiler support') option('slirp_smbd', type : 'feature', value : 'auto', description: 'use smbd (at path --smbd=3D*) in slirp networking') + +option('hexagon_idef_parser', type : 'boolean', value : true, + description: 'use idef-parser to automatically generate TCG code fo= r the Hexagon frontend') diff --git a/target/hexagon/gen_idef_parser_funcs.py b/target/hexagon/gen_i= def_parser_funcs.py new file mode 100644 index 0000000000..917753d6d8 --- /dev/null +++ b/target/hexagon/gen_idef_parser_funcs.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2022 rev.ng Labs Srl. 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 . +## + +import sys +import re +import string +from io import StringIO + +import hex_common + +## +## Generate code to be fed to the idef_parser +## +## Consider A2_add: +## +## Rd32=3Dadd(Rs32,Rt32), { RdV=3DRsV+RtV;} +## +## We produce: +## +## A2_add(RdV, in RsV, in RtV) { +## { RdV=3DRsV+RtV;} +## } +## +## A2_add represents the instruction tag. Then we have a list of TCGv +## that the code generated by the parser can expect in input. Some of +## them are inputs ("in" prefix), while some others are outputs. +## +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.calculate_attribs() + tagregs =3D hex_common.get_tagregs() + tagimms =3D hex_common.get_tagimms() + + with open(sys.argv[3], 'w') as f: + f.write('#include "macros.inc"\n\n') + + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip instructions that saturate in a ternary expression + if ( tag in {'S2_asr_r_r_sat', 'S2_asl_r_r_sat'} ) : + continue + ## Skip instructions using switch + if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) : + continue + ## Skip trap instructions + if ( tag in {'J2_trap0', 'J2_trap1'} ) : + continue + ## Skip 128-bit instructions + if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) : + continue + if ( tag in {'M7_wcmpyrw', 'M7_wcmpyrwc', + 'M7_wcmpyiw', 'M7_wcmpyiwc', + 'M7_wcmpyrw_rnd', 'M7_wcmpyrwc_rnd', + 'M7_wcmpyiw_rnd', 'M7_wcmpyiwc_rnd'} ) : + continue + ## Skip interleave/deinterleave instructions + if ( tag in {'S2_interleave', 'S2_deinterleave'} ) : + continue + ## Skip instructions using bit reverse + if ( tag in {'S2_brev', 'S2_brevp', 'S2_ct0', 'S2_ct1', + 'S2_ct0p', 'S2_ct1p', 'A4_tlbmatch'} ) : + continue + ## Skip other unsupported instructions + if ( tag =3D=3D 'S2_cabacdecbin' or tag =3D=3D 'A5_ACS' ) : + continue + if ( tag.startswith('Y') ) : + continue + if ( tag.startswith('V6_') ) : + continue + if ( tag.startswith('F') ) : + continue + if ( tag.endswith('_locked') ) : + continue + if ( "A_COF" in hex_common.attribdict[tag] ) : + continue + + regs =3D tagregs[tag] + imms =3D tagimms[tag] + + arguments =3D [] + for regtype,regid,toss,numregs in regs: + prefix =3D "in " if hex_common.is_read(regid) else "" + + is_pair =3D hex_common.is_pair(regid) + is_single_old =3D (hex_common.is_single(regid) + and hex_common.is_old_val(regtype, regid,= tag)) + is_single_new =3D (hex_common.is_single(regid) + and hex_common.is_new_val(regtype, regid,= tag)) + + if is_pair or is_single_old: + arguments.append("%s%s%sV" % (prefix, regtype, regid)) + elif is_single_new: + arguments.append("%s%s%sN" % (prefix, regtype, regid)) + else: + print("Bad register parse: ",regtype,regid,toss,numreg= s) + + for immlett,bits,immshift in imms: + arguments.append(hex_common.imm_name(immlett)) + + f.write("%s(%s) {\n" % (tag, ", ".join(arguments))) + f.write(" "); + if hex_common.need_ea(tag): + f.write("size4u_t EA; "); + f.write("%s\n" % hex_common.semdict[tag]) + f.write("}\n\n") + +if __name__ =3D=3D "__main__": + main() diff --git a/target/hexagon/idef-parser/macros.inc b/target/hexagon/idef-pa= rser/macros.inc new file mode 100644 index 0000000000..6b697da87a --- /dev/null +++ b/target/hexagon/idef-parser/macros.inc @@ -0,0 +1,140 @@ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. 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 . + */ + +/* Copy rules */ +#define fLSBOLD(VAL) (fGETBIT(0, VAL)) +#define fSATH(VAL) fSATN(16, VAL) +#define fSATUH(VAL) fSATUN(16, VAL) +#define fVSATH(VAL) fVSATN(16, VAL) +#define fVSATUH(VAL) fVSATUN(16, VAL) +#define fSATUB(VAL) fSATUN(8, VAL) +#define fSATB(VAL) fSATN(8, VAL) +#define fVSATUB(VAL) fVSATUN(8, VAL) +#define fVSATB(VAL) fVSATN(8, VAL) +#define fCALL(A) fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A); +#define fCALLR(A) fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A); +#define fCAST2_8s(A) fSXTN(16, 64, A) +#define fCAST2_8u(A) fZXTN(16, 64, A) +#define fVSATW(A) fVSATN(32, fCAST8_8s(A)) +#define fSATW(A) fSATN(32, fCAST8_8s(A)) +#define fVSAT(A) fVSATN(32, A) +#define fSAT(A) fSATN(32, A) + +/* Ease parsing */ +#define f8BITSOF(VAL) ((VAL) ? 0xff : 0x00) +#define fREAD_GP() (Constant_extended ? (0) : GP) +#define fCLIP(DST, SRC, U) (DST =3D fMIN((1 << U) - 1, fMAX(SRC, -(1 << U)= ))) +#define fBIDIR_ASHIFTL(SRC, SHAMT, REGSTYPE) \ + ((SHAMT > 0) ? \ + (fCAST##REGSTYPE##s(SRC) << SHAMT) : \ + (fCAST##REGSTYPE##s(SRC) >> -SHAMT)) + +#define fBIDIR_LSHIFTL(SRC, SHAMT, REGSTYPE) \ + ((SHAMT > 0) ? \ + (fCAST##REGSTYPE##u(SRC) << SHAMT) : \ + (fCAST##REGSTYPE##u(SRC) >>> -SHAMT)) + +#define fBIDIR_ASHIFTR(SRC, SHAMT, REGSTYPE) \ + ((SHAMT > 0) ? \ + (fCAST##REGSTYPE##s(SRC) >> SHAMT) : \ + (fCAST##REGSTYPE##s(SRC) << -SHAMT)) + +#define fBIDIR_SHIFTR(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT)) - 1)) << 1) \ + : (fCAST##REGSTYPE(SRC) >> (SHAMT))) + +#define fBIDIR_LSHIFTR(SRC, SHAMT, REGSTYPE) \ + fBIDIR_SHIFTR(SRC, SHAMT, REGSTYPE##u) + +#define fSATVALN(N, VAL) \ + fSET_OVERFLOW( \ + ((VAL) < 0) ? (-(1LL << ((N) - 1))) : ((1LL << ((N) - 1)) - 1) \ + ) + +#define fSAT_ORIG_SHL(A, ORIG_REG) \ + (((fCAST4s((fSAT(A)) ^ (fCAST4s(ORIG_REG)))) < 0) \ + ? fSATVALN(32, (fCAST4s(ORIG_REG))) \ + : ((((ORIG_REG) > 0) && ((A) =3D=3D 0)) ? fSATVALN(32, (ORIG_REG))= \ + : fSAT(A))) + +#define fBIDIR_ASHIFTR_SAT(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) \ + << ((-(SHAMT)) - 1)) << 1, (SRC)) \ + : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))) + +#define fBIDIR_ASHIFTL_SAT(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) \ + ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT)) - 1)) >> 1) \ + : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT), (SRC))) + +#define fEXTRACTU_BIDIR(INREG, WIDTH, OFFSET) \ + (fZXTN(WIDTH, 32, fBIDIR_LSHIFTR((INREG), (OFFSET), 4_8))) + +/* Least significant bit operations */ +#define fLSBNEW0 fLSBNEW(P0N) +#define fLSBNEW1 fLSBNEW(P1N) +#define fLSBOLDNOT(VAL) fGETBIT(0, ~VAL) +#define fLSBNEWNOT(PRED) (fLSBNEW(~PRED)) +#define fLSBNEW0NOT fLSBNEW(~P0N) +#define fLSBNEW1NOT fLSBNEW(~P1N) + +/* Assignments */ +#define fPCALIGN(IMM) (IMM =3D IMM & ~3) +#define fWRITE_LR(A) (LR =3D A) +#define fWRITE_FP(A) (FP =3D A) +#define fWRITE_SP(A) (SP =3D A) +/* + * Note: There is a rule in the parser that matches `PC =3D ...` and emits + * a call to `gen_write_new_pc`. We need to call `gen_write_new_pc` to + * get the correct semantics when there are multiple stores in a packet. + */ +#define fBRANCH(LOC, TYPE) (PC =3D LOC) +#define fJUMPR(REGNO, TARGET, TYPE) (PC =3D TARGET) +#define fWRITE_LOOP_REGS0(START, COUNT) SA0 =3D START; (LC0 =3D COUNT) +#define fWRITE_LOOP_REGS1(START, COUNT) SA1 =3D START; (LC1 =3D COUNT) +#define fWRITE_LC0(VAL) (LC0 =3D VAL) +#define fWRITE_LC1(VAL) (LC1 =3D VAL) +#define fSET_LPCFG(VAL) (USR.LPCFG =3D VAL) +#define fWRITE_P0(VAL) P0 =3D VAL; +#define fWRITE_P1(VAL) P1 =3D VAL; +#define fWRITE_P3(VAL) P3 =3D VAL; +#define fEA_RI(REG, IMM) (EA =3D REG + IMM) +#define fEA_RRs(REG, REG2, SCALE) (EA =3D REG + (REG2 << SCALE)) +#define fEA_IRs(IMM, REG, SCALE) (EA =3D IMM + (REG << SCALE)) +#define fEA_IMM(IMM) (EA =3D IMM) +#define fEA_REG(REG) (EA =3D REG) +#define fEA_BREVR(REG) (EA =3D fbrev(REG)) +#define fEA_GPI(IMM) (EA =3D fREAD_GP() + IMM) +#define fPM_I(REG, IMM) (REG =3D REG + IMM) +#define fPM_M(REG, MVAL) (REG =3D REG + MVAL) +#define fWRITE_NPC(VAL) (PC =3D VAL) + +/* Unary operators */ +#define fROUND(A) (A + 0x8000) + +/* Binary operators */ +#define fSCALE(N, A) (A << N) +#define fASHIFTR(SRC, SHAMT, REGSTYPE) (fCAST##REGSTYPE##s(SRC) >> SHAMT) +#define fLSHIFTR(SRC, SHAMT, REGSTYPE) (SRC >>> SHAMT) +#define fROTL(SRC, SHAMT, REGSTYPE) fROTL(SRC, SHAMT) +#define fASHIFTL(SRC, SHAMT, REGSTYPE) (fCAST##REGSTYPE##s(SRC) << SHAMT) + +/* Include fHIDE macros which hide type declarations */ +#define fHIDE(A) A + +/* Purge non-relavant parts */ +#define fBRANCH_SPECULATE_STALL(A, B, C, D, E) diff --git a/target/hexagon/idef-parser/prepare b/target/hexagon/idef-parse= r/prepare new file mode 100755 index 0000000000..72d6fcbd21 --- /dev/null +++ b/target/hexagon/idef-parser/prepare @@ -0,0 +1,24 @@ +#!/bin/bash + +# +# Copyright(c) 2019-2021 rev.ng Labs Srl. 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 . +# + +set -e +set -o pipefail + +# Run the preprocessor and drop comments +cpp "$@" diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index b61243103f..aaa487f950 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -21,6 +21,7 @@ hex_common_py =3D 'hex_common.py' attribs_def =3D meson.current_source_dir() / 'attribs_def.h.inc' gen_tcg_h =3D meson.current_source_dir() / 'gen_tcg.h' gen_tcg_hvx_h =3D meson.current_source_dir() / 'gen_tcg_hvx.h' +idef_parser_dir =3D meson.current_source_dir() / 'idef-parser' =20 # # Step 1 @@ -179,4 +180,23 @@ hexagon_ss.add(files( 'mmvec/system_ext_mmvec.c', )) =20 +idef_parser_enabled =3D get_option('hexagon_idef_parser') +if idef_parser_enabled and 'hexagon-linux-user' in target_dirs + idef_parser_input_generated =3D custom_target( + 'idef_parser_input.h.inc', + output: 'idef_parser_input.h.inc', + depends: [semantics_generated], + depend_files: [hex_common_py], + command: [python, files('gen_idef_parser_funcs.py'), semantics_gen= erated, attribs_def, '@OUTPUT@'], + ) + + preprocessed_idef_parser_input_generated =3D custom_target( + 'idef_parser_input.preprocessed.h.inc', + output: 'idef_parser_input.preprocessed.h.inc', + input: idef_parser_input_generated, + depend_files: [idef_parser_dir / 'macros.inc'], + command: [idef_parser_dir / 'prepare', '@INPUT@', '-I' + idef_pars= er_dir, '-o', '@OUTPUT@'], + ) +endif + target_arch +=3D {'hexagon': hexagon_ss} --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223918; cv=none; d=zohomail.com; s=zohoarc; b=heDZN1rZgK7Ma9q47JIfQ7dWsua89zTPVumtYpSiAuT7RtBpi1jgMOcqHRbS4C8SNfEXvnAjjJxa+G52SCv5+RbLCaiVV3/RR5KaRsx5y8vGpIWFD8E5q8JTvu0dgLAncPZbzCg95Z6ylS/wezLUtAORXC2M6JXKZmYXiDahlA8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223918; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=psIazzL1YGGgaJUNlT/JW/f31EYHbtiNKSSBzgiVj1M=; b=dMh44r0tj/jNWhcSRS/SONNzuiH1qdkBLzXQd82Rv6PZ7870Yid5hbXntRwRP3bdwHluv1iwEBegjI7EUDlq+gN56Hf3s2e268+Fum/6two7I8nrnyJudVdweU7GC2LavB40l1TYmmdwOaG3dXV+JOb5Azg2fRkAYHYE9wJ/oJM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671223918480762.7830051493736; Fri, 16 Dec 2022 12:51:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeE-0002sL-RL; Fri, 16 Dec 2022 15:49:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He9-0002qS-Bm for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PR-H0 for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKh1vt032055; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg3f8w3dg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA04.qualcomm.com [127.0.0.1]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgoZm016632; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 3mgw840n79-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA04.qualcomm.com (NALASPPMTA04.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg5G9015901; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA04.qualcomm.com (PPS) with ESMTP id 2BGKnD5a024110; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 1294950011F; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=psIazzL1YGGgaJUNlT/JW/f31EYHbtiNKSSBzgiVj1M=; b=NIbGxMhmGogrzzQI25g9cDMO/idzME+tyuIin3MMC57/ah7wnGEfQyG/b5MwIjX1xQac 8vzk/6/dR2qXZHM3mUx9vsBfrHaAVRFXbgdzzdNPe7SNREfjEDkWgu0gPaqg9BB0+K2L 4meLhyMspI+57se8evrmLCY5MjL60AXkONzvM+qWVHyr6yDMYdOqyNHYsusN1QruW0Dy jDMvPmiIWos1vvKcCcREByk8LOzRx6SkMo8LtWDQua2X/XaLfnBSbNlCoCXE5rEjrE+t rNi4bBTXqFkkEepr/TRcrCti4eVhKymBUQb+tqt9YFDpMx2MLblIEysj4CkJJ9z8yqOX vA== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Paolo Montesel , Alessandro Di Federico , Anton Johansson Subject: [PULL 18/21] target/hexagon: import lexer for idef-parser Date: Fri, 16 Dec 2022 12:48:42 -0800 Message-Id: <20221216204845.19290-19-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 0sAweHU-4lo08lgNiObepVwOhELbqscr X-Proofpoint-ORIG-GUID: 0sAweHU-4lo08lgNiObepVwOhELbqscr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 lowpriorityscore=0 spamscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 phishscore=0 bulkscore=0 mlxscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223920274100003 From: Paolo Montesel Signed-off-by: Alessandro Di Federico Signed-off-by: Paolo Montesel Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-9-anjo@rev.ng> --- target/hexagon/idef-parser/idef-parser.h | 253 +++++++++++ target/hexagon/idef-parser/idef-parser.lex | 471 +++++++++++++++++++++ target/hexagon/meson.build | 6 + 3 files changed, 730 insertions(+) create mode 100644 target/hexagon/idef-parser/idef-parser.h create mode 100644 target/hexagon/idef-parser/idef-parser.lex diff --git a/target/hexagon/idef-parser/idef-parser.h b/target/hexagon/idef= -parser/idef-parser.h new file mode 100644 index 0000000000..5c49d4da3e --- /dev/null +++ b/target/hexagon/idef-parser/idef-parser.h @@ -0,0 +1,253 @@ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. 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 IDEF_PARSER_H +#define IDEF_PARSER_H + +#include +#include +#include +#include + +#define TCGV_NAME_SIZE 7 +#define MAX_WRITTEN_REGS 32 +#define OFFSET_STR_LEN 32 +#define ALLOC_LIST_LEN 32 +#define ALLOC_NAME_SIZE 32 +#define INIT_LIST_LEN 32 +#define OUT_BUF_LEN (1024 * 1024) +#define SIGNATURE_BUF_LEN (128 * 1024) +#define HEADER_BUF_LEN (128 * 1024) + +/* Variadic macros to wrap the buffer printing functions */ +#define EMIT(c, ...) = \ + do { = \ + g_string_append_printf((c)->out_str, __VA_ARGS__); = \ + } while (0) + +#define EMIT_SIG(c, ...) = \ + do { = \ + g_string_append_printf((c)->signature_str, __VA_ARGS__); = \ + } while (0) + +#define EMIT_HEAD(c, ...) = \ + do { = \ + g_string_append_printf((c)->header_str, __VA_ARGS__); = \ + } while (0) + +/** + * Type of register, assigned to the HexReg.type field + */ +typedef enum { GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW } HexRegType; + +typedef enum { UNKNOWN_SIGNEDNESS, SIGNED, UNSIGNED } HexSignedness; + +/** + * Semantic record of the REG tokens, identifying registers + */ +typedef struct HexReg { + uint8_t id; /**< Identifier of the register = */ + HexRegType type; /**< Type of the register = */ + unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits = */ +} HexReg; + +/** + * Data structure, identifying a TCGv temporary value + */ +typedef struct HexTmp { + unsigned index; /**< Index of the TCGv temporary value = */ +} HexTmp; + +/** + * Enum of the possible immediated, an immediate is a value which is known + * at tinycode generation time, e.g. an integer value, not a TCGv + */ +enum ImmUnionTag { + I, + VARIABLE, + VALUE, + QEMU_TMP, + IMM_PC, + IMM_NPC, + IMM_CONSTEXT, +}; + +/** + * Semantic record of the IMM token, identifying an immediate constant + */ +typedef struct HexImm { + union { + char id; /**< Identifier, used when type is VARIABL= E */ + uint64_t value; /**< Immediate value, used when type is VA= LUE */ + uint64_t index; /**< Index, used when type is QEMU_TMP = */ + }; + enum ImmUnionTag type; /**< Type of the immediate = */ +} HexImm; + +/** + * Semantic record of the PRED token, identifying a predicate + */ +typedef struct HexPred { + char id; /**< Identifier of the predicate = */ +} HexPred; + +/** + * Semantic record of the SAT token, identifying the saturate operator + * Note: All saturates are assumed to implicitly set overflow. + */ +typedef struct HexSat { + HexSignedness signedness; /**< Signedness of the sat. op. = */ +} HexSat; + +/** + * Semantic record of the CAST token, identifying the cast operator + */ +typedef struct HexCast { + unsigned bit_width; /**< Bit width of the cast operator = */ + HexSignedness signedness; /**< Unsigned flag for the cast operator = */ +} HexCast; + +/** + * Semantic record of the EXTRACT token, identifying the cast operator + */ +typedef struct HexExtract { + unsigned bit_width; /**< Bit width of the extract operator = */ + unsigned storage_bit_width; /**< Actual bit width of the extract opera= tor */ + HexSignedness signedness; /**< Unsigned flag for the extract operato= r */ +} HexExtract; + +/** + * Semantic record of the MPY token, identifying the fMPY multiplication + * operator + */ +typedef struct HexMpy { + unsigned first_bit_width; /**< Bit width of 1st operand of fMPY= */ + unsigned second_bit_width; /**< Bit width of 2nd operand of fMPY= */ + HexSignedness first_signedness; /**< Signedness of 1st operand of fMP= Y */ + HexSignedness second_signedness; /**< Signedness of 2nd operand of fMP= Y */ +} HexMpy; + +/** + * Semantic record of the VARID token, identifying declared variables + * of the input language + */ +typedef struct HexVar { + GString *name; /**< Name of the VARID variable = */ +} HexVar; + +/** + * Data structure uniquely identifying a declared VARID variable, used for + * keeping track of declared variable, so that any variable is declared on= ly + * once, and its properties are propagated through all the subsequent inst= ances + * of that variable + */ +typedef struct Var { + GString *name; /**< Name of the VARID variable = */ + uint8_t bit_width; /**< Bit width of the VARID variable = */ + HexSignedness signedness; /**< Unsigned flag for the VARID var = */ +} Var; + +/** + * Enum of the possible rvalue types, used in the HexValue.type field + */ +typedef enum RvalueUnionTag { + REGISTER, REGISTER_ARG, TEMP, IMMEDIATE, PREDICATE, VARID +} RvalueUnionTag; + +/** + * Semantic record of the rvalue token, identifying any numeric value, + * immediate or register based. The rvalue tokens are combined together + * through the use of several operators, to encode expressions + */ +typedef struct HexValue { + union { + HexReg reg; /**< rvalue of register type = */ + HexTmp tmp; /**< rvalue of temporary type = */ + HexImm imm; /**< rvalue of immediate type = */ + HexPred pred; /**< rvalue of predicate type = */ + HexVar var; /**< rvalue of declared variable type = */ + }; + RvalueUnionTag type; /**< Type of the rvalue = */ + unsigned bit_width; /**< Bit width of the rvalue = */ + HexSignedness signedness; /**< Unsigned flag for the rvalue = */ + bool is_dotnew; /**< rvalue of predicate type is dotnew? = */ + bool is_manual; /**< Opt out of automatic freeing of param= s */ +} HexValue; + +/** + * State of ternary operator + */ +typedef enum TernaryState { IN_LEFT, IN_RIGHT } TernaryState; + +/** + * Data structure used to handle side effects inside ternary operators + */ +typedef struct Ternary { + TernaryState state; + HexValue cond; +} Ternary; + +/** + * Operator type, used for referencing the correct operator when calling t= he + * gen_bin_op() function, which in turn will generate the correct code to + * execute the operation between the two rvalues + */ +typedef enum OpType { + ADD_OP, SUB_OP, MUL_OP, ASL_OP, ASR_OP, LSR_OP, ANDB_OP, ORB_OP, + XORB_OP, ANDL_OP, MINI_OP, MAXI_OP +} OpType; + +/** + * Data structure including instruction specific information, to be cleared + * out after the compilation of each instruction + */ +typedef struct Inst { + GString *name; /**< Name of the compiled instruction = */ + char *code_begin; /**< Beginning of instruction input code = */ + char *code_end; /**< End of instruction input code = */ + unsigned tmp_count; /**< Index of the last declared TCGv temp = */ + unsigned qemu_tmp_count; /**< Index of the last declared int temp = */ + unsigned if_count; /**< Index of the last declared if label = */ + unsigned error_count; /**< Number of generated errors = */ + GArray *allocated; /**< Allocated declaredVARID vars = */ + GArray *init_list; /**< List of initialized registers = */ + GArray *strings; /**< Strings allocated by the instruction = */ +} Inst; + +/** + * Data structure representing the whole translation context, which in a + * reentrant flex/bison parser just like ours is passed between the scanner + * and the parser, holding all the necessary information to perform the + * parsing, this data structure survives between the compilation of differ= ent + * instructions + */ +typedef struct Context { + void *scanner; /**< Reentrant parser state pointer = */ + char *input_buffer; /**< Buffer containing the input code = */ + GString *out_str; /**< String containing the output code = */ + GString *signature_str; /**< String containing the signatures code= */ + GString *header_str; /**< String containing the header code = */ + FILE *defines_file; /**< FILE * of the generated header = */ + FILE *output_file; /**< FILE * of the C output file = */ + FILE *enabled_file; /**< FILE * of the list of enabled inst = */ + GArray *ternary; /**< Array to track nesting of ternary ops= */ + unsigned total_insn; /**< Number of instructions in input file = */ + unsigned implemented_insn; /**< Instruction compiled without errors = */ + Inst inst; /**< Parsing data of the current inst = */ +} Context; + +#endif /* IDEF_PARSER_H */ diff --git a/target/hexagon/idef-parser/idef-parser.lex b/target/hexagon/id= ef-parser/idef-parser.lex new file mode 100644 index 0000000000..ff87a02c3a --- /dev/null +++ b/target/hexagon/idef-parser/idef-parser.lex @@ -0,0 +1,471 @@ +%option noyywrap noinput nounput +%option 8bit reentrant bison-bridge +%option warn nodefault +%option bison-locations + +%{ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. 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 +#include + +#include "hex_regs.h" + +#include "idef-parser.h" +#include "idef-parser.tab.h" + +/* Keep track of scanner position for error message printout */ +#define YY_USER_ACTION yylloc->first_column =3D yylloc->last_column; \ + for (int i =3D 0; yytext[i] !=3D '\0'; i++) { \ + yylloc->last_column++; \ + } + +/* Global Error Counter */ +int error_count; + +%} + +/* Definitions */ +DIGIT [0-9] +LOWER_ID [a-z] +UPPER_ID [A-Z] +ID LOWER_ID|UPPER_ID +INST_NAME [A-Z]+[0-9]_([A-Za-z]|[0-9]|_)+ +HEX_DIGIT [0-9a-fA-F] +REG_ID_32 e|s|d|t|u|v|x|y +REG_ID_64 ee|ss|dd|tt|uu|vv|xx|yy +SYS_ID_32 s|d +SYS_ID_64 ss|dd +PRED_ID d|s|t|u|v|e|x|x +IMM_ID r|s|S|u|U +VAR_ID [a-zA-Z_][a-zA-Z0-9_]* +SIGN_ID s|u +STRING_LIT \"(\\.|[^"\\])*\" + +/* Tokens */ +%% + +[ \t\f\v]+ { /* Ignore whitespaces. */ } +[\n\r]+ { /* Ignore newlines. */ } +^#.*$ { /* Ignore linemarkers. */ } + +{INST_NAME} { yylval->string =3D g_string_new(yytext); + return INAME; } +"fFLOAT" | +"fUNFLOAT" | +"fDOUBLE" | +"fUNDOUBLE" | +"0.0" | +"0x1.0p52" | +"0x1.0p-52" { return FAIL; } +"in" { return IN; } +"R"{REG_ID_32}"V" { + yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D GENERAL_PURPOSE; + yylval->rvalue.reg.id =3D yytext[1]; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D false; + yylval->rvalue.signedness =3D SIGNED; + return REG; } +"R"{REG_ID_64}"V" { + yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D GENERAL_PURPOSE; + yylval->rvalue.reg.id =3D yytext[1]; + yylval->rvalue.reg.bit_width =3D 64; + yylval->rvalue.bit_width =3D 64; + yylval->rvalue.is_dotnew =3D false; + yylval->rvalue.signedness =3D SIGNED; + return REG; } +"MuV" { + yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D MODIFIER; + yylval->rvalue.reg.id =3D 'u'; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D SIGNED; + return REG; } +"C"{REG_ID_32}"V" { + yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D yytext[1]; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D false; + yylval->rvalue.signedness =3D SIGNED; + return REG; } +"C"{REG_ID_64}"V" { + yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D yytext[1]; + yylval->rvalue.reg.bit_width =3D 64; + yylval->rvalue.bit_width =3D 64; + yylval->rvalue.is_dotnew =3D false; + yylval->rvalue.signedness =3D SIGNED; + return REG; } +{IMM_ID}"iV" { + yylval->rvalue.type =3D IMMEDIATE; + yylval->rvalue.signedness =3D SIGNED; + yylval->rvalue.imm.type =3D VARIABLE; + yylval->rvalue.imm.id =3D yytext[0]; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D false; + return IMM; } +"P"{PRED_ID}"V" { + yylval->rvalue.type =3D PREDICATE; + yylval->rvalue.pred.id =3D yytext[1]; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D false; + yylval->rvalue.signedness =3D SIGNED; + return PRED; } +"P"{PRED_ID}"N" { + yylval->rvalue.type =3D PREDICATE; + yylval->rvalue.pred.id =3D yytext[1]; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D true; + yylval->rvalue.signedness =3D SIGNED; + return PRED; } +"IV1DEAD()" | +"fPAUSE(uiV);" { return ';'; } +"+=3D" { return INC; } +"-=3D" { return DEC; } +"++" { return PLUSPLUS; } +"&=3D" { return ANDA; } +"|=3D" { return ORA; } +"^=3D" { return XORA; } +"<<" { return ASL; } +">>" { return ASR; } +">>>" { return LSR; } +"=3D=3D" { return EQ; } +"!=3D" { return NEQ; } +"<=3D" { return LTE; } +">=3D" { return GTE; } +"&&" { return ANDL; } +"else" { return ELSE; } +"for" { return FOR; } +"fREAD_IREG" { return ICIRC; } +"fPART1" { return PART1; } +"if" { return IF; } +"fFRAME_SCRAMBLE" { return FSCR; } +"fFRAME_UNSCRAMBLE" { return FSCR; } +"fFRAMECHECK" { return FCHK; } +"Constant_extended" { return CONSTEXT; } +"fCL1_"{DIGIT} { return LOCNT; } +"fbrev" { return BREV; } +"fSXTN" { return SXT; } +"fZXTN" { return ZXT; } +"fDF_MAX" | +"fSF_MAX" | +"fMAX" { return MAX; } +"fDF_MIN" | +"fSF_MIN" | +"fMIN" { return MIN; } +"fABS" { return ABS; } +"fRNDN" { return ROUND; } +"fCRND" { return CROUND; } +"fCRNDN" { return CROUND; } +"fPM_CIRI" { return CIRCADD; } +"fPM_CIRR" { return CIRCADD; } +"fCOUNTONES_"{DIGIT} { return COUNTONES; } +"fSATN" { yylval->sat.signedness =3D SIGNED; + return SAT; } +"fSATUN" { yylval->sat.signedness =3D UNSIGNED; + return SAT; } +"fCONSTLL" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D SIGNED; + return CAST; } +"fSE32_64" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D SIGNED; + return CAST; } +"fCAST4_4u" { yylval->cast.bit_width =3D 32; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"fCAST4_8s" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D SIGNED; + return CAST; } +"fCAST4_8u" { return CAST4_8U; } +"fCAST4u" { yylval->cast.bit_width =3D 32; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"fNEWREG" | +"fCAST4_4s" | +"fCAST4s" { yylval->cast.bit_width =3D 32; + yylval->cast.signedness =3D SIGNED; + return CAST; } +"fCAST8_8u" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"fCAST8u" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"fCAST8_8s" | +"fCAST8s" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D SIGNED; + return CAST; } +"fGETBIT" { yylval->extract.bit_width =3D 1; + yylval->extract.storage_bit_width =3D 1; + yylval->extract.signedness =3D UNSIGNED; + return EXTRACT; } +"fGETBYTE" { yylval->extract.bit_width =3D 8; + yylval->extract.storage_bit_width =3D 8; + yylval->extract.signedness =3D SIGNED; + return EXTRACT; } +"fGETUBYTE" { yylval->extract.bit_width =3D 8; + yylval->extract.storage_bit_width =3D 8; + yylval->extract.signedness =3D UNSIGNED; + return EXTRACT; } +"fGETHALF" { yylval->extract.bit_width =3D 16; + yylval->extract.storage_bit_width =3D 16; + yylval->extract.signedness =3D SIGNED; + return EXTRACT; } +"fGETUHALF" { yylval->extract.bit_width =3D 16; + yylval->extract.storage_bit_width =3D 16; + yylval->extract.signedness =3D UNSIGNED; + return EXTRACT; } +"fGETWORD" { yylval->extract.bit_width =3D 32; + yylval->extract.storage_bit_width =3D 64; + yylval->extract.signedness =3D SIGNED; + return EXTRACT; } +"fGETUWORD" { yylval->extract.bit_width =3D 32; + yylval->extract.storage_bit_width =3D 64; + yylval->extract.signedness =3D UNSIGNED; + return EXTRACT; } +"fEXTRACTU_RANGE" { return EXTRANGE; } +"fSETBIT" { yylval->cast.bit_width =3D 1; + yylval->cast.signedness =3D SIGNED; + return DEPOSIT; } +"fSETBYTE" { yylval->cast.bit_width =3D 8; + yylval->cast.signedness =3D SIGNED; + return DEPOSIT; } +"fSETHALF" { yylval->cast.bit_width =3D 16; + yylval->cast.signedness =3D SIGNED; + return SETHALF; } +"fSETWORD" { yylval->cast.bit_width =3D 32; + yylval->cast.signedness =3D SIGNED; + return DEPOSIT; } +"fINSERT_BITS" { return INSBITS; } +"fSETBITS" { return SETBITS; } +"fMPY16UU" { yylval->mpy.first_bit_width =3D 16; + yylval->mpy.second_bit_width =3D 16; + yylval->mpy.first_signedness =3D UNSIGNED; + yylval->mpy.second_signedness =3D UNSIGNED; + return MPY; } +"fMPY16SU" { yylval->mpy.first_bit_width =3D 16; + yylval->mpy.second_bit_width =3D 16; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D UNSIGNED; + return MPY; } +"fMPY16SS" { yylval->mpy.first_bit_width =3D 16; + yylval->mpy.second_bit_width =3D 16; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D SIGNED; + return MPY; } +"fMPY32UU" { yylval->mpy.first_bit_width =3D 32; + yylval->mpy.second_bit_width =3D 32; + yylval->mpy.first_signedness =3D UNSIGNED; + yylval->mpy.second_signedness =3D UNSIGNED; + return MPY; } +"fMPY32SU" { yylval->mpy.first_bit_width =3D 32; + yylval->mpy.second_bit_width =3D 32; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D UNSIGNED; + return MPY; } +"fSFMPY" | +"fMPY32SS" { yylval->mpy.first_bit_width =3D 32; + yylval->mpy.second_bit_width =3D 32; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D SIGNED; + return MPY; } +"fMPY3216SS" { yylval->mpy.first_bit_width =3D 32; + yylval->mpy.second_bit_width =3D 16; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D SIGNED; + return MPY; } +"fMPY3216SU" { yylval->mpy.first_bit_width =3D 32; + yylval->mpy.second_bit_width =3D 16; + yylval->mpy.first_signedness =3D SIGNED; + yylval->mpy.second_signedness =3D UNSIGNED; + return MPY; } +"fNEWREG_ST" | +"fIMMEXT" | +"fMUST_IMMEXT" | +"fPASS" | +"fECHO" { return IDENTITY; } +"(size8u_t)" { yylval->cast.bit_width =3D 64; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"(unsigned int)" { yylval->cast.bit_width =3D 32; + yylval->cast.signedness =3D UNSIGNED; + return CAST; } +"fREAD_PC()" | +"PC" { return PC; } +"fREAD_NPC()" | +"NPC" { return NPC; } +"fGET_LPCFG" | +"USR.LPCFG" { return LPCFG; } +"LOAD_CANCEL(EA)" { return LOAD_CANCEL; } +"STORE_CANCEL(EA)" | +"CANCEL" { return CANCEL; } +"N"{LOWER_ID}"N" { yylval->rvalue.type =3D REGISTER_ARG; + yylval->rvalue.reg.type =3D DOTNEW; + yylval->rvalue.reg.id =3D yytext[1]; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_SP()" | +"SP" { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D GENERAL_PURPOSE; + yylval->rvalue.reg.id =3D HEX_REG_SP; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_FP()" | +"FP" { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D GENERAL_PURPOSE; + yylval->rvalue.reg.id =3D HEX_REG_FP; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_LR()" | +"LR" { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D GENERAL_PURPOSE; + yylval->rvalue.reg.id =3D HEX_REG_LR; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_GP()" | +"GP" { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D HEX_REG_GP; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_LC"[01] { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D HEX_REG_LC0 + + (yytext[8] - '0') * 2; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"LC"[01] { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D HEX_REG_LC0 + + (yytext[2] - '0') * 2; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_SA"[01] { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D HEX_REG_SA0 + + (yytext[8] - '0') * 2; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"SA"[01] { yylval->rvalue.type =3D REGISTER; + yylval->rvalue.reg.type =3D CONTROL; + yylval->rvalue.reg.id =3D HEX_REG_SA0 + + (yytext[2] - '0') * 2; + yylval->rvalue.reg.bit_width =3D 32; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D UNSIGNED; + return REG; } +"fREAD_P0()" { yylval->rvalue.type =3D PREDICATE; + yylval->rvalue.pred.id =3D '0'; + yylval->rvalue.bit_width =3D 32; + return PRED; } +[pP]{DIGIT} { yylval->rvalue.type =3D PREDICATE; + yylval->rvalue.pred.id =3D yytext[1]; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D false; + return PRED; } +[pP]{DIGIT}[nN] { yylval->rvalue.type =3D PREDICATE; + yylval->rvalue.pred.id =3D yytext[1]; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.is_dotnew =3D true; + return PRED; } +"fLSBNEW" { return LSBNEW; } +"N" { yylval->rvalue.type =3D IMMEDIATE; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.imm.type =3D VARIABLE; + yylval->rvalue.imm.id =3D 'N'; + return IMM; } +"i" { yylval->rvalue.type =3D IMMEDIATE; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D SIGNED; + yylval->rvalue.imm.type =3D I; + return IMM; } +{SIGN_ID} { if (yytext[0] =3D=3D 'u') { + yylval->signedness =3D UNSIGNED; + } else { + yylval->signedness =3D SIGNED; + } + return SIGN; + } +"0x"{HEX_DIGIT}+ | +{DIGIT}+ { yylval->rvalue.type =3D IMMEDIATE; + yylval->rvalue.bit_width =3D 32; + yylval->rvalue.signedness =3D SIGNED; + yylval->rvalue.imm.type =3D VALUE; + yylval->rvalue.imm.value =3D strtoull(yytext, N= ULL, 0); + return IMM; } +"0x"{HEX_DIGIT}+"ULL" | +{DIGIT}+"ULL" { yylval->rvalue.type =3D IMMEDIATE; + yylval->rvalue.bit_width =3D 64; + yylval->rvalue.signedness =3D UNSIGNED; + yylval->rvalue.imm.type =3D VALUE; + yylval->rvalue.imm.value =3D strtoull(yytext, N= ULL, 0); + return IMM; } +"fLOAD" { return LOAD; } +"fSTORE" { return STORE; } +"fROTL" { return ROTL; } +"fCARRY_FROM_ADD" { return CARRY_FROM_ADD; } +"fADDSAT64" { return ADDSAT64; } +"size"[1248][us]"_t" { /* Handles "size_t" variants of int types */ + const unsigned int bits_per_byte =3D 8; + const unsigned int bytes =3D yytext[4] - '0'; + yylval->rvalue.bit_width =3D bits_per_byte * by= tes; + if (yytext[5] =3D=3D 'u') { + yylval->rvalue.signedness =3D UNSIGNED; + } else { + yylval->rvalue.signedness =3D SIGNED; + } + return TYPE_SIZE_T; } +"unsigned" { return TYPE_UNSIGNED; } +"long" { return TYPE_LONG; } +"int" { return TYPE_INT; } +"const" { /* Emit no token */ } +{VAR_ID} { /* Variable name, we adopt the C names conventi= on */ + yylval->rvalue.type =3D VARID; + yylval->rvalue.var.name =3D g_string_new(yytext= ); + /* Default to an unknown signedness and 0 width= . */ + yylval->rvalue.bit_width =3D 0; + yylval->rvalue.signedness =3D UNKNOWN_SIGNEDNES= S; + return VAR; } +"fatal("{STRING_LIT}")" { /* Emit no token */ } +"fHINTJR(RsV)" { /* Emit no token */ } +. { return yytext[0]; } + +%% diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index aaa487f950..5af0a6f419 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -197,6 +197,12 @@ if idef_parser_enabled and 'hexagon-linux-user' in tar= get_dirs depend_files: [idef_parser_dir / 'macros.inc'], command: [idef_parser_dir / 'prepare', '@INPUT@', '-I' + idef_pars= er_dir, '-o', '@OUTPUT@'], ) + + flex =3D generator( + find_program('flex'), + output: ['@BASENAME@.yy.c', '@BASENAME@.yy.h'], + arguments: ['-o', '@OUTPUT0@', '--header-file=3D@OUTPUT1@', '@INPU= T@'] + ) endif =20 target_arch +=3D {'hexagon': hexagon_ss} --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671223864; cv=none; d=zohomail.com; s=zohoarc; b=icZRPXvHFng8FjeEGyZyz1SMbDV3q3h+0yXZtt9sMhY++Rrk98flXoAsbVtFIjy8O3nG1gC5Q7K1MtrgSDWcEhHZEKnqo9mx3ndHaPu+sD6IpjW5CzF2QTlGKJhcokndB1nuYFtfu5YbvFPwETMyebWgrmLD0V2xEUBbqOTI9Mg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671223864; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=a0YzA4peuL06SyePgur/w6Dfu8KuR9zU4bxwbRtfvgc=; b=ZZio+8S84fRDQuo6mQLO9MbDH8I6GTpaMvI5GESEWZzWWC6Ty8BrGcd8emtS9Q8OFLuizNAptBU6E4X5KiqcmQOaXG258/OedPqfpWHRxX+Cpcal+pvn6t6aRia1/BLf0r5iG10x7mbHLWiTJEXqmalCNl4hLntyqOewke/JNWo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671223864180799.1308709381454; Fri, 16 Dec 2022 12:51:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeJ-0002t0-1K; Fri, 16 Dec 2022 15:49:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6HeB-0002r7-Ef for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:36 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He4-0004Q8-29 for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:35 -0500 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGGlkRE009351; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg8e6bpq9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA05.qualcomm.com [127.0.0.1]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKfq9J019837; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 3mgwb1gmps-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA05.qualcomm.com (NALASPPMTA05.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKg3rA019961; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTP id 2BGKnDBw028291; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 16354500120; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=a0YzA4peuL06SyePgur/w6Dfu8KuR9zU4bxwbRtfvgc=; b=LnmXiS6lSt2ae5STCl/nFZJotoKK8GEsDhTCR0ta7Ipgn4W9R6NkL6NvrtU2g0rCAbxk L6nowPE0EGD8dcor3UTFzzsP5YwtgaTYW4VzRhsYiXUaNpKroEITYrIkYEbhO4W+5oKg 5co0LiOIqK/0RN4SWP2jtHlx9REGgCHPSSQ6r3GwPMIMXtrx8mfIcCT/qS25GmQtDxgD W8rC92lL060JKURAxEQOB/naEh5JWrMxX6ihBZumG5Y2LwNfHA7qpfa+NNT1zC8wP1Y1 1/GiOg50/MuJiTr8ctKpnXC0EUmedEhAENeJk359SjsXXz9UD4iszXvjlSMcH2nqQX/g 7g== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Anton Johansson , Alessandro Di Federico , Paolo Montesel Subject: [PULL 19/21] target/hexagon: import parser for idef-parser Date: Fri, 16 Dec 2022 12:48:43 -0800 Message-Id: <20221216204845.19290-20-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: xSA5BYKtZSxZKaHMtRcnTXk7tw4aWD9k X-Proofpoint-ORIG-GUID: xSA5BYKtZSxZKaHMtRcnTXk7tw4aWD9k X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=544 priorityscore=1501 lowpriorityscore=0 spamscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxscore=0 adultscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671223865935100003 From: Anton Johansson Signed-off-by: Alessandro Di Federico Signed-off-by: Paolo Montesel Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-10-anjo@rev.ng> --- target/hexagon/idef-parser/parser-helpers.h | 376 +++ target/hexagon/idef-parser/parser-helpers.c | 2360 +++++++++++++++++++ target/hexagon/idef-parser/idef-parser.y | 965 ++++++++ target/hexagon/meson.build | 29 + 4 files changed, 3730 insertions(+) create mode 100644 target/hexagon/idef-parser/parser-helpers.h create mode 100644 target/hexagon/idef-parser/parser-helpers.c create mode 100644 target/hexagon/idef-parser/idef-parser.y diff --git a/target/hexagon/idef-parser/parser-helpers.h b/target/hexagon/i= def-parser/parser-helpers.h new file mode 100644 index 0000000000..2766296417 --- /dev/null +++ b/target/hexagon/idef-parser/parser-helpers.h @@ -0,0 +1,376 @@ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. 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 PARSER_HELPERS_H +#define PARSER_HELPERS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tcg/tcg-cond.h" + +#include "idef-parser.tab.h" +#include "idef-parser.yy.h" +#include "idef-parser.h" + +/* Decomment this to disable yyasserts */ +/* #define NDEBUG */ + +#define ERR_LINE_CONTEXT 40 + +#define START_COMMENT "/" "*" +#define END_COMMENT "*" "/" + +void yyerror(YYLTYPE *locp, + yyscan_t scanner __attribute__((unused)), + Context *c, + const char *s); + +#ifndef NDEBUG +#define yyassert(context, locp, condition, msg) \ + if (!(condition)) { \ + yyerror(locp, (context)->scanner, (context), (msg)); \ + } +#endif + +bool is_direct_predicate(HexValue *value); + +bool is_inside_ternary(Context *c); + +/** + * Print functions + */ + +void str_print(Context *c, YYLTYPE *locp, const char *string); + +void uint8_print(Context *c, YYLTYPE *locp, uint8_t *num); + +void uint64_print(Context *c, YYLTYPE *locp, uint64_t *num); + +void int_print(Context *c, YYLTYPE *locp, int *num); + +void uint_print(Context *c, YYLTYPE *locp, unsigned *num); + +void tmp_print(Context *c, YYLTYPE *locp, HexTmp *tmp); + +void pred_print(Context *c, YYLTYPE *locp, HexPred *pred, bool is_dotnew); + +void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char reg_id[5]); + +void reg_print(Context *c, YYLTYPE *locp, HexReg *reg); + +void imm_print(Context *c, YYLTYPE *locp, HexImm *imm); + +void var_print(Context *c, YYLTYPE *locp, HexVar *var); + +void rvalue_print(Context *c, YYLTYPE *locp, void *pointer); + +void out_assert(Context *c, YYLTYPE *locp, void *dummy); + +/** + * Copies output code buffer into stdout + */ +void commit(Context *c); + +#define OUT_IMPL(c, locp, x) \ + _Generic(*(x), \ + char: str_print, \ + uint8_t: uint8_print, \ + uint64_t: uint64_print, \ + int: int_print, \ + unsigned: uint_print, \ + HexValue: rvalue_print, \ + default: out_assert \ + )(c, locp, x); + +/* FOREACH macro */ +#define FE_1(c, locp, WHAT, X) WHAT(c, locp, X) +#define FE_2(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_1(c, locp, WHAT, __VA_ARGS__) +#define FE_3(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_2(c, locp, WHAT, __VA_ARGS__) +#define FE_4(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_3(c, locp, WHAT, __VA_ARGS__) +#define FE_5(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_4(c, locp, WHAT, __VA_ARGS__) +#define FE_6(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_5(c, locp, WHAT, __VA_ARGS__) +#define FE_7(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_6(c, locp, WHAT, __VA_ARGS__) +#define FE_8(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_7(c, locp, WHAT, __VA_ARGS__) +#define FE_9(c, locp, WHAT, X, ...) \ + WHAT(c, locp, X)FE_8(c, locp, WHAT, __VA_ARGS__) +/* repeat as needed */ + +#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) NAME + +#define FOR_EACH(c, locp, action, ...) \ + do { \ + GET_MACRO(__VA_ARGS__, \ + FE_9, \ + FE_8, \ + FE_7, \ + FE_6, \ + FE_5, \ + FE_4, \ + FE_3, \ + FE_2, \ + FE_1)(c, locp, action, \ + __VA_ARGS__) \ + } while (0) + +#define OUT(c, locp, ...) FOR_EACH((c), (locp), OUT_IMPL, __VA_ARGS__) + +const char *cmp_swap(Context *c, YYLTYPE *locp, const char *type); + +/** + * Temporary values creation + */ + +HexValue gen_tmp(Context *c, + YYLTYPE *locp, + unsigned bit_width, + HexSignedness signedness); + +HexValue gen_tmp_value(Context *c, + YYLTYPE *locp, + const char *value, + unsigned bit_width, + HexSignedness signedness); + +HexValue gen_imm_value(Context *c __attribute__((unused)), + YYLTYPE *locp, + int value, + unsigned bit_width, + HexSignedness signedness); + +HexValue gen_imm_qemu_tmp(Context *c, YYLTYPE *locp, unsigned bit_width, + HexSignedness signedness); + +void gen_rvalue_free(Context *c, YYLTYPE *locp, HexValue *rvalue); + +HexValue rvalue_materialize(Context *c, YYLTYPE *locp, HexValue *rvalue); + +HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, HexValue *rvalue); + +HexValue gen_rvalue_truncate(Context *c, YYLTYPE *locp, HexValue *rvalue); + +void gen_varid_allocate(Context *c, + YYLTYPE *locp, + HexValue *varid, + unsigned bit_width, + HexSignedness signedness); + +/** + * Code generation functions + */ + +HexValue gen_bin_cmp(Context *c, + YYLTYPE *locp, + TCGCond type, + HexValue *op1, + HexValue *op2); + +HexValue gen_bin_op(Context *c, + YYLTYPE *locp, + OpType type, + HexValue *op1, + HexValue *op2); + +HexValue gen_cast_op(Context *c, + YYLTYPE *locp, + HexValue *src, + unsigned target_width, + HexSignedness signedness); + +/** + * gen_extend_op extends a region of src_width_ptr bits stored in a + * value_ptr to the size of dst_width. Note: src_width_ptr is a + * HexValue * to handle the special case where it is unknown at + * translation time. + */ +HexValue gen_extend_op(Context *c, + YYLTYPE *locp, + HexValue *src_width, + unsigned dst_width, + HexValue *value, + HexSignedness signedness); + +void gen_rdeposit_op(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value, + HexValue *begin, + HexValue *width); + +void gen_deposit_op(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value, + HexValue *index, + HexCast *cast); + +HexValue gen_rextract_op(Context *c, + YYLTYPE *locp, + HexValue *src, + unsigned begin, + unsigned width); + +HexValue gen_extract_op(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *index, + HexExtract *extract); + +HexValue gen_read_reg(Context *c, YYLTYPE *locp, HexValue *reg); + +void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *val= ue); + +void gen_assign(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value); + +HexValue gen_convround(Context *c, + YYLTYPE *locp, + HexValue *src); + +HexValue gen_round(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *position); + +HexValue gen_convround_n(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *pos); + +/** + * Circular addressing mode with auto-increment + */ +void gen_circ_op(Context *c, + YYLTYPE *locp, + HexValue *addr, + HexValue *increment, + HexValue *modifier); + +HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src); + +HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src); + +HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *n); + +HexValue gen_deinterleave(Context *c, YYLTYPE *locp, HexValue *mixed); + +HexValue gen_interleave(Context *c, + YYLTYPE *locp, + HexValue *odd, + HexValue *even); + +HexValue gen_carry_from_add(Context *c, + YYLTYPE *locp, + HexValue *op1, + HexValue *op2, + HexValue *op3); + +void gen_addsat64(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *op1, + HexValue *op2); + +void gen_inst(Context *c, GString *iname); + +void gen_inst_init_args(Context *c, YYLTYPE *locp); + +void gen_inst_code(Context *c, YYLTYPE *locp); + +void gen_pred_assign(Context *c, YYLTYPE *locp, HexValue *left_pred, + HexValue *right_pred); + +void gen_cancel(Context *c, YYLTYPE *locp); + +void gen_load_cancel(Context *c, YYLTYPE *locp); + +void gen_load(Context *c, YYLTYPE *locp, HexValue *size, + HexSignedness signedness, HexValue *ea, HexValue *dst); + +void gen_store(Context *c, YYLTYPE *locp, HexValue *size, HexValue *ea, + HexValue *src); + +void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n, + HexValue *dst, HexValue *value); + +void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo, + HexValue *dst, HexValue *value); + +unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond); + +unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index); + +HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred); + +HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var); + +HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, HexValue *= op1, + HexValue *op2); + +HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, HexValue *= n, + HexValue *value); + +HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value); + +HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond, + HexValue *true_branch, HexValue *false_branch); + +const char *cond_to_str(TCGCond cond); + +void emit_header(Context *c); + +void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg); + +void emit_footer(Context *c); + +void track_string(Context *c, GString *s); + +void free_variables(Context *c, YYLTYPE *locp); + +void free_instruction(Context *c); + +void assert_signedness(Context *c, + YYLTYPE *locp, + HexSignedness signedness); + +#endif /* PARSER_HELPERS_h */ diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/i= def-parser/parser-helpers.c new file mode 100644 index 0000000000..8110686c51 --- /dev/null +++ b/target/hexagon/idef-parser/parser-helpers.c @@ -0,0 +1,2360 @@ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "idef-parser.h" +#include "parser-helpers.h" +#include "idef-parser.tab.h" +#include "idef-parser.yy.h" + +void yyerror(YYLTYPE *locp, + yyscan_t scanner __attribute__((unused)), + Context *c, + const char *s) +{ + const char *code_ptr =3D c->input_buffer; + + fprintf(stderr, "WARNING (%s): '%s'\n", c->inst.name->str, s); + + fprintf(stderr, "Problematic range: "); + for (int i =3D locp->first_column; i < locp->last_column; i++) { + if (code_ptr[i] !=3D '\n') { + fprintf(stderr, "%c", code_ptr[i]); + } + } + fprintf(stderr, "\n"); + + for (unsigned i =3D 0; + i < 80 && + code_ptr[locp->first_column - 10 + i] !=3D '\0' && + code_ptr[locp->first_column - 10 + i] !=3D '\n'; + i++) { + fprintf(stderr, "%c", code_ptr[locp->first_column - 10 + i]); + } + fprintf(stderr, "\n"); + for (unsigned i =3D 0; i < 9; i++) { + fprintf(stderr, " "); + } + fprintf(stderr, "^"); + for (int i =3D 0; i < (locp->last_column - locp->first_column) - 1; i+= +) { + fprintf(stderr, "~"); + } + fprintf(stderr, "\n"); + c->inst.error_count++; +} + +bool is_direct_predicate(HexValue *value) +{ + return value->pred.id >=3D '0' && value->pred.id <=3D '3'; +} + +bool is_inside_ternary(Context *c) +{ + return c->ternary->len > 0; +} + +/* Print functions */ +void str_print(Context *c, YYLTYPE *locp, const char *string) +{ + (void) locp; + EMIT(c, "%s", string); +} + +void uint8_print(Context *c, YYLTYPE *locp, uint8_t *num) +{ + (void) locp; + EMIT(c, "%u", *num); +} + +void uint64_print(Context *c, YYLTYPE *locp, uint64_t *num) +{ + (void) locp; + EMIT(c, "%" PRIu64, *num); +} + +void int_print(Context *c, YYLTYPE *locp, int *num) +{ + (void) locp; + EMIT(c, "%d", *num); +} + +void uint_print(Context *c, YYLTYPE *locp, unsigned *num) +{ + (void) locp; + EMIT(c, "%u", *num); +} + +void tmp_print(Context *c, YYLTYPE *locp, HexTmp *tmp) +{ + (void) locp; + EMIT(c, "tmp_%d", tmp->index); +} + +void pred_print(Context *c, YYLTYPE *locp, HexPred *pred, bool is_dotnew) +{ + (void) locp; + char suffix =3D is_dotnew ? 'N' : 'V'; + EMIT(c, "P%c%c", pred->id, suffix); +} + +void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char reg_id[5]) +{ + memset(reg_id, 0, 5 * sizeof(char)); + switch (reg->type) { + case GENERAL_PURPOSE: + reg_id[0] =3D 'R'; + break; + case CONTROL: + reg_id[0] =3D 'C'; + break; + case MODIFIER: + reg_id[0] =3D 'M'; + break; + case DOTNEW: + reg_id[0] =3D 'N'; + reg_id[1] =3D reg->id; + reg_id[2] =3D 'N'; + return; + } + switch (reg->bit_width) { + case 32: + reg_id[1] =3D reg->id; + reg_id[2] =3D 'V'; + break; + case 64: + reg_id[1] =3D reg->id; + reg_id[2] =3D reg->id; + reg_id[3] =3D 'V'; + break; + default: + yyassert(c, locp, false, "Unhandled register bit width!\n"); + } +} + +static void reg_arg_print(Context *c, YYLTYPE *locp, HexReg *reg) +{ + char reg_id[5]; + reg_compose(c, locp, reg, reg_id); + EMIT(c, "%s", reg_id); +} + +void reg_print(Context *c, YYLTYPE *locp, HexReg *reg) +{ + (void) locp; + EMIT(c, "hex_gpr[%u]", reg->id); +} + +void imm_print(Context *c, YYLTYPE *locp, HexImm *imm) +{ + switch (imm->type) { + case I: + EMIT(c, "i"); + break; + case VARIABLE: + EMIT(c, "%ciV", imm->id); + break; + case VALUE: + EMIT(c, "((int64_t) %" PRIu64 "ULL)", (int64_t) imm->value); + break; + case QEMU_TMP: + EMIT(c, "qemu_tmp_%" PRIu64, imm->index); + break; + case IMM_PC: + EMIT(c, "ctx->base.pc_next"); + break; + case IMM_NPC: + EMIT(c, "ctx->npc"); + break; + case IMM_CONSTEXT: + EMIT(c, "insn->extension_valid"); + break; + default: + yyassert(c, locp, false, "Cannot print this expression!"); + } +} + +void var_print(Context *c, YYLTYPE *locp, HexVar *var) +{ + (void) locp; + EMIT(c, "%s", var->name->str); +} + +void rvalue_print(Context *c, YYLTYPE *locp, void *pointer) +{ + HexValue *rvalue =3D (HexValue *) pointer; + switch (rvalue->type) { + case REGISTER: + reg_print(c, locp, &rvalue->reg); + break; + case REGISTER_ARG: + reg_arg_print(c, locp, &rvalue->reg); + break; + case TEMP: + tmp_print(c, locp, &rvalue->tmp); + break; + case IMMEDIATE: + imm_print(c, locp, &rvalue->imm); + break; + case VARID: + var_print(c, locp, &rvalue->var); + break; + case PREDICATE: + pred_print(c, locp, &rvalue->pred, rvalue->is_dotnew); + break; + default: + yyassert(c, locp, false, "Cannot print this expression!"); + } +} + +void out_assert(Context *c, YYLTYPE *locp, + void *dummy __attribute__((unused))) +{ + yyassert(c, locp, false, "Unhandled print type!"); +} + +/* Copy output code buffer */ +void commit(Context *c) +{ + /* Emit instruction pseudocode */ + EMIT_SIG(c, "\n" START_COMMENT " "); + for (char *x =3D c->inst.code_begin; x < c->inst.code_end; x++) { + EMIT_SIG(c, "%c", *x); + } + EMIT_SIG(c, " " END_COMMENT "\n"); + + /* Commit instruction code to output file */ + fwrite(c->signature_str->str, sizeof(char), c->signature_str->len, + c->output_file); + fwrite(c->header_str->str, sizeof(char), c->header_str->len, + c->output_file); + fwrite(c->out_str->str, sizeof(char), c->out_str->len, + c->output_file); + + fwrite(c->signature_str->str, sizeof(char), c->signature_str->len, + c->defines_file); + fprintf(c->defines_file, ";\n"); +} + +static void gen_c_int_type(Context *c, YYLTYPE *locp, unsigned bit_width, + HexSignedness signedness) +{ + const char *signstr =3D (signedness =3D=3D UNSIGNED) ? "u" : ""; + OUT(c, locp, signstr, "int", &bit_width, "_t"); +} + +static HexValue gen_constant(Context *c, + YYLTYPE *locp, + const char *value, + unsigned bit_width, + HexSignedness signedness) +{ + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D TEMP; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D true; + rvalue.tmp.index =3D c->inst.tmp_count; + OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, + " =3D tcg_constant_i", &bit_width, "(", value, ");\n"); + c->inst.tmp_count++; + return rvalue; +} + +/* Temporary values creation */ +HexValue gen_tmp(Context *c, + YYLTYPE *locp, + unsigned bit_width, + HexSignedness signedness) +{ + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D TEMP; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.tmp.index =3D c->inst.tmp_count; + OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, + " =3D tcg_temp_new_i", &bit_width, "();\n"); + c->inst.tmp_count++; + return rvalue; +} + +HexValue gen_tmp_local(Context *c, + YYLTYPE *locp, + unsigned bit_width, + HexSignedness signedness) +{ + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D TEMP; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.tmp.index =3D c->inst.tmp_count; + OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, + " =3D tcg_temp_local_new_i", &bit_width, "();\n"); + c->inst.tmp_count++; + return rvalue; +} + +HexValue gen_tmp_value(Context *c, + YYLTYPE *locp, + const char *value, + unsigned bit_width, + HexSignedness signedness) +{ + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D TEMP; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.tmp.index =3D c->inst.tmp_count; + OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, + " =3D tcg_const_i", &bit_width, "(", value, ");\n"); + c->inst.tmp_count++; + return rvalue; +} + +static HexValue gen_tmp_value_from_imm(Context *c, + YYLTYPE *locp, + HexValue *value) +{ + HexValue rvalue; + assert(value->type =3D=3D IMMEDIATE); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D TEMP; + rvalue.bit_width =3D value->bit_width; + rvalue.signedness =3D value->signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.tmp.index =3D c->inst.tmp_count; + /* + * Here we output the call to `tcg_const_i` in + * order to create the temporary value. Note, that we + * add a cast + * + * `tcg_const_i`((int_t) ...)` + * + * This cast is required to avoid implicit integer + * conversion warnings since all immediates are + * output as `((int64_t) 123ULL)`, even if the + * integer is 32-bit. + */ + OUT(c, locp, "TCGv_i", &rvalue.bit_width, " tmp_", &c->inst.tmp_count); + OUT(c, locp, " =3D tcg_const_i", &rvalue.bit_width, + "((int", &rvalue.bit_width, "_t) (", value, "));\n"); + + c->inst.tmp_count++; + return rvalue; +} + +HexValue gen_imm_value(Context *c __attribute__((unused)), + YYLTYPE *locp, + int value, + unsigned bit_width, + HexSignedness signedness) +{ + (void) locp; + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D IMMEDIATE; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.imm.type =3D VALUE; + rvalue.imm.value =3D value; + return rvalue; +} + +HexValue gen_imm_qemu_tmp(Context *c, YYLTYPE *locp, unsigned bit_width, + HexSignedness signedness) +{ + (void) locp; + HexValue rvalue; + assert(bit_width =3D=3D 32 || bit_width =3D=3D 64); + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D IMMEDIATE; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + rvalue.bit_width =3D bit_width; + rvalue.signedness =3D signedness; + rvalue.imm.type =3D QEMU_TMP; + rvalue.imm.index =3D c->inst.qemu_tmp_count++; + return rvalue; +} + +void gen_rvalue_free(Context *c, YYLTYPE *locp, HexValue *rvalue) +{ + if (rvalue->type =3D=3D TEMP && !rvalue->is_manual) { + const char *bit_suffix =3D (rvalue->bit_width =3D=3D 64) ? "i64" := "i32"; + OUT(c, locp, "tcg_temp_free_", bit_suffix, "(", rvalue, ");\n"); + } +} + +static void gen_rvalue_free_manual(Context *c, YYLTYPE *locp, HexValue *rv= alue) +{ + rvalue->is_manual =3D false; + gen_rvalue_free(c, locp, rvalue); +} + +HexValue rvalue_materialize(Context *c, YYLTYPE *locp, HexValue *rvalue) +{ + if (rvalue->type =3D=3D IMMEDIATE) { + HexValue res =3D gen_tmp_value_from_imm(c, locp, rvalue); + gen_rvalue_free(c, locp, rvalue); + return res; + } + return *rvalue; +} + +HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, HexValue *rvalue) +{ + assert_signedness(c, locp, rvalue->signedness); + if (rvalue->bit_width > 32) { + return *rvalue; + } + + if (rvalue->type =3D=3D IMMEDIATE) { + HexValue res =3D gen_imm_qemu_tmp(c, locp, 64, rvalue->signedness); + bool is_unsigned =3D (rvalue->signedness =3D=3D UNSIGNED); + const char *sign_suffix =3D is_unsigned ? "u" : ""; + gen_c_int_type(c, locp, 64, rvalue->signedness); + OUT(c, locp, " ", &res, " =3D "); + OUT(c, locp, "(", sign_suffix, "int64_t) "); + OUT(c, locp, "(", sign_suffix, "int32_t) "); + OUT(c, locp, rvalue, ";\n"); + return res; + } else { + HexValue res =3D gen_tmp(c, locp, 64, rvalue->signedness); + bool is_unsigned =3D (rvalue->signedness =3D=3D UNSIGNED); + const char *sign_suffix =3D is_unsigned ? "u" : ""; + OUT(c, locp, "tcg_gen_ext", sign_suffix, + "_i32_i64(", &res, ", ", rvalue, ");\n"); + gen_rvalue_free(c, locp, rvalue); + return res; + } +} + +HexValue gen_rvalue_truncate(Context *c, YYLTYPE *locp, HexValue *rvalue) +{ + if (rvalue->type =3D=3D IMMEDIATE) { + HexValue res =3D *rvalue; + res.bit_width =3D 32; + return res; + } else { + if (rvalue->bit_width =3D=3D 64) { + HexValue res =3D gen_tmp(c, locp, 32, rvalue->signedness); + OUT(c, locp, "tcg_gen_trunc_i64_tl(", &res, ", ", rvalue, ");\= n"); + gen_rvalue_free(c, locp, rvalue); + return res; + } + } + return *rvalue; +} + +/* + * Attempts to lookup the `Var` struct associated with the given `varid`. + * The `dst` argument is populated with the found name, bit_width, and + * signedness, given that `dst` is non-NULL. Returns true if the lookup + * succeeded and false otherwise. + */ +static bool try_find_variable(Context *c, YYLTYPE *locp, + HexValue *dst, + HexValue *varid) +{ + yyassert(c, locp, varid, "varid to lookup is NULL"); + yyassert(c, locp, varid->type =3D=3D VARID, + "Can only lookup variables by varid"); + for (unsigned i =3D 0; i < c->inst.allocated->len; i++) { + Var *curr =3D &g_array_index(c->inst.allocated, Var, i); + if (g_string_equal(varid->var.name, curr->name)) { + if (dst) { + dst->var.name =3D curr->name; + dst->bit_width =3D curr->bit_width; + dst->signedness =3D curr->signedness; + } + return true; + } + } + return false; +} + +/* Calls `try_find_variable` and asserts succcess. */ +static void find_variable(Context *c, YYLTYPE *locp, + HexValue *dst, + HexValue *varid) +{ + bool found =3D try_find_variable(c, locp, dst, varid); + yyassert(c, locp, found, "Use of undeclared variable!\n"); +} + +/* Handle signedness, if both unsigned -> result is unsigned, else signed = */ +static inline HexSignedness bin_op_signedness(Context *c, YYLTYPE *locp, + HexSignedness sign1, + HexSignedness sign2) +{ + assert_signedness(c, locp, sign1); + assert_signedness(c, locp, sign2); + return (sign1 =3D=3D UNSIGNED && sign2 =3D=3D UNSIGNED) ? UNSIGNED : S= IGNED; +} + +void gen_varid_allocate(Context *c, + YYLTYPE *locp, + HexValue *varid, + unsigned bit_width, + HexSignedness signedness) +{ + const char *bit_suffix =3D (bit_width =3D=3D 64) ? "i64" : "i32"; + bool found =3D try_find_variable(c, locp, NULL, varid); + Var new_var; + + memset(&new_var, 0, sizeof(Var)); + + yyassert(c, locp, !found, "Redeclaration of variables not allowed!"); + assert_signedness(c, locp, signedness); + + /* `varid` only carries name information */ + new_var.name =3D varid->var.name; + new_var.bit_width =3D bit_width; + new_var.signedness =3D signedness; + + EMIT_HEAD(c, "TCGv_%s %s", bit_suffix, varid->var.name->str); + EMIT_HEAD(c, " =3D tcg_temp_local_new_%s();\n", bit_suffix); + g_array_append_val(c->inst.allocated, new_var); +} + +enum OpTypes { + IMM_IMM =3D 0, + IMM_REG =3D 1, + REG_IMM =3D 2, + REG_REG =3D 3, +}; + +HexValue gen_bin_cmp(Context *c, + YYLTYPE *locp, + TCGCond type, + HexValue *op1, + HexValue *op2) +{ + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + enum OpTypes op_types =3D (op1_m.type !=3D IMMEDIATE) << 1 + | (op2_m.type !=3D IMMEDIATE); + + bool op_is64bit =3D op1_m.bit_width =3D=3D 64 || op2_m.bit_width =3D= =3D 64; + const char *bit_suffix =3D op_is64bit ? "i64" : "i32"; + unsigned bit_width =3D (op_is64bit) ? 64 : 32; + HexValue res =3D gen_tmp(c, locp, bit_width, UNSIGNED); + + /* Extend to 64-bits, if required */ + if (op_is64bit) { + op1_m =3D gen_rvalue_extend(c, locp, &op1_m); + op2_m =3D gen_rvalue_extend(c, locp, &op2_m); + } + + switch (op_types) { + case IMM_IMM: + case IMM_REG: + yyassert(c, locp, false, "Binary comparisons between IMM op IMM an= d" + "IMM op REG not handled!"); + break; + case REG_IMM: + OUT(c, locp, "tcg_gen_setcondi_", bit_suffix, "("); + OUT(c, locp, cond_to_str(type), ", ", &res, ", ", &op1_m, ", ", &o= p2_m, + ");\n"); + break; + case REG_REG: + OUT(c, locp, "tcg_gen_setcond_", bit_suffix, "("); + OUT(c, locp, cond_to_str(type), ", ", &res, ", ", &op1_m, ", ", &o= p2_m, + ");\n"); + break; + default: + fprintf(stderr, "Error in evalutating immediateness!"); + abort(); + } + + /* Free operands */ + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); + + return res; +} + +static void gen_simple_op(Context *c, YYLTYPE *locp, unsigned bit_width, + const char *bit_suffix, HexValue *res, + enum OpTypes op_types, + HexValue *op1, + HexValue *op2, + const char *imm_imm, + const char *imm_reg, + const char *reg_imm, + const char *reg_reg) +{ + switch (op_types) { + case IMM_IMM: { + HexSignedness signedness =3D bin_op_signedness(c, locp, + op1->signedness, + op2->signedness); + gen_c_int_type(c, locp, bit_width, signedness); + OUT(c, locp, " ", res, + " =3D ", op1, imm_imm, op2, ";\n"); + } break; + case IMM_REG: + OUT(c, locp, imm_reg, bit_suffix, + "(", res, ", ", op2, ", ", op1, ");\n"); + break; + case REG_IMM: + OUT(c, locp, reg_imm, bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + break; + case REG_REG: + OUT(c, locp, reg_reg, bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + break; + } + gen_rvalue_free(c, locp, op1); + gen_rvalue_free(c, locp, op2); +} + +static void gen_sub_op(Context *c, YYLTYPE *locp, unsigned bit_width, + const char *bit_suffix, HexValue *res, + enum OpTypes op_types, HexValue *op1, + HexValue *op2) +{ + switch (op_types) { + case IMM_IMM: { + HexSignedness signedness =3D bin_op_signedness(c, locp, + op1->signedness, + op2->signedness); + gen_c_int_type(c, locp, bit_width, signedness); + OUT(c, locp, " ", res, + " =3D ", op1, " - ", op2, ";\n"); + } break; + case IMM_REG: { + OUT(c, locp, "tcg_gen_subfi_", bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + } break; + case REG_IMM: { + OUT(c, locp, "tcg_gen_subi_", bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + } break; + case REG_REG: { + OUT(c, locp, "tcg_gen_sub_", bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + } break; + } + gen_rvalue_free(c, locp, op1); + gen_rvalue_free(c, locp, op2); +} + +static void gen_asl_op(Context *c, YYLTYPE *locp, unsigned bit_width, + bool op_is64bit, const char *bit_suffix, + HexValue *res, enum OpTypes op_types, + HexValue *op1, HexValue *op2) +{ + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + switch (op_types) { + case IMM_IMM: { + HexSignedness signedness =3D bin_op_signedness(c, locp, + op1->signedness, + op2->signedness); + gen_c_int_type(c, locp, bit_width, signedness); + OUT(c, locp, " ", res, + " =3D ", op1, " << ", op2, ";\n"); + } break; + case REG_IMM: { + OUT(c, locp, "if (", op2, " >=3D ", &bit_width, ") {\n"); + OUT(c, locp, "tcg_gen_movi_", bit_suffix, "(", res, ", 0);\n"); + OUT(c, locp, "} else {\n"); + OUT(c, locp, "tcg_gen_shli_", bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + OUT(c, locp, "}\n"); + } break; + case IMM_REG: + op1_m.bit_width =3D bit_width; + op1_m =3D rvalue_materialize(c, locp, &op1_m); + /* fallthrough */ + case REG_REG: { + OUT(c, locp, "tcg_gen_shl_", bit_suffix, + "(", res, ", ", &op1_m, ", ", op2, ");\n"); + } break; + } + if (op_types =3D=3D IMM_REG || op_types =3D=3D REG_REG) { + /* + * Handle left shift by 64/32 which hexagon-sim expects to clear o= ut + * register + */ + HexValue zero =3D gen_constant(c, locp, "0", bit_width, UNSIGNED); + HexValue edge =3D gen_imm_value(c, locp, bit_width, bit_width, UNS= IGNED); + edge =3D rvalue_materialize(c, locp, &edge); + if (op_is64bit) { + op2_m =3D gen_rvalue_extend(c, locp, &op2_m); + } + op1_m =3D rvalue_materialize(c, locp, &op1_m); + op2_m =3D rvalue_materialize(c, locp, &op2_m); + OUT(c, locp, "tcg_gen_movcond_i", &bit_width); + OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); + OUT(c, locp, ", ", &zero, ", ", res, ");\n"); + gen_rvalue_free(c, locp, &edge); + } + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); +} + +static void gen_asr_op(Context *c, YYLTYPE *locp, unsigned bit_width, + bool op_is64bit, const char *bit_suffix, + HexValue *res, enum OpTypes op_types, + HexValue *op1, HexValue *op2) +{ + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + switch (op_types) { + case IMM_IMM: + case IMM_REG: + yyassert(c, locp, false, "ASR between IMM op IMM, and IMM op REG" + " not handled!"); + break; + case REG_IMM: { + HexSignedness signedness =3D bin_op_signedness(c, locp, + op1->signedness, + op2->signedness); + OUT(c, locp, "{\n"); + gen_c_int_type(c, locp, bit_width, signedness); + OUT(c, locp, " shift =3D ", op2, ";\n"); + OUT(c, locp, "if (", op2, " >=3D ", &bit_width, ") {\n"); + OUT(c, locp, " shift =3D ", &bit_width, " - 1;\n"); + OUT(c, locp, "}\n"); + OUT(c, locp, "tcg_gen_sari_", bit_suffix, + "(", res, ", ", op1, ", shift);\n}\n"); + } break; + case REG_REG: + OUT(c, locp, "tcg_gen_sar_", bit_suffix, + "(", res, ", ", &op1_m, ", ", op2, ");\n"); + break; + } + if (op_types =3D=3D REG_REG) { + /* Handle right shift by values >=3D bit_width */ + const char *offset =3D op_is64bit ? "63" : "31"; + HexValue tmp =3D gen_tmp(c, locp, bit_width, SIGNED); + HexValue zero =3D gen_constant(c, locp, "0", bit_width, SIGNED); + HexValue edge =3D gen_imm_value(c, locp, bit_width, bit_width, UNS= IGNED); + + edge =3D rvalue_materialize(c, locp, &edge); + if (op_is64bit) { + op2_m =3D gen_rvalue_extend(c, locp, &op2_m); + } + op1_m =3D rvalue_materialize(c, locp, &op1_m); + op2_m =3D rvalue_materialize(c, locp, &op2_m); + + OUT(c, locp, "tcg_gen_extract_", bit_suffix, "(", + &tmp, ", ", &op1_m, ", ", offset, ", 1);\n"); + OUT(c, locp, "tcg_gen_sub_", bit_suffix, "(", + &tmp, ", ", &zero, ", ", &tmp, ");\n"); + OUT(c, locp, "tcg_gen_movcond_i", &bit_width); + OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); + OUT(c, locp, ", ", &tmp, ", ", res, ");\n"); + gen_rvalue_free(c, locp, &edge); + gen_rvalue_free(c, locp, &tmp); + } + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); +} + +static void gen_lsr_op(Context *c, YYLTYPE *locp, unsigned bit_width, + bool op_is64bit, const char *bit_suffix, + HexValue *res, enum OpTypes op_types, + HexValue *op1, HexValue *op2) +{ + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + switch (op_types) { + case IMM_IMM: + case IMM_REG: + yyassert(c, locp, false, "LSR between IMM op IMM, and IMM op REG" + " not handled!"); + break; + case REG_IMM: + OUT(c, locp, "if (", op2, " >=3D ", &bit_width, ") {\n"); + OUT(c, locp, "tcg_gen_movi_", bit_suffix, "(", res, ", 0);\n"); + OUT(c, locp, "} else {\n"); + OUT(c, locp, "tcg_gen_shri_", bit_suffix, + "(", res, ", ", op1, ", ", op2, ");\n"); + OUT(c, locp, "}\n"); + break; + case REG_REG: + OUT(c, locp, "tcg_gen_shr_", bit_suffix, + "(", res, ", ", &op1_m, ", ", op2, ");\n"); + break; + } + if (op_types =3D=3D REG_REG) { + /* Handle right shift by values >=3D bit_width */ + HexValue zero =3D gen_constant(c, locp, "0", bit_width, UNSIGNED); + HexValue edge =3D gen_imm_value(c, locp, bit_width, bit_width, UNS= IGNED); + edge =3D rvalue_materialize(c, locp, &edge); + if (op_is64bit) { + op2_m =3D gen_rvalue_extend(c, locp, &op2_m); + } + op1_m =3D rvalue_materialize(c, locp, &op1_m); + op2_m =3D rvalue_materialize(c, locp, &op2_m); + OUT(c, locp, "tcg_gen_movcond_i", &bit_width); + OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); + OUT(c, locp, ", ", &zero, ", ", res, ");\n"); + gen_rvalue_free(c, locp, &edge); + } + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); +} + +/* + * Note: This implementation of logical `and` does not mirror that in C. + * We do not short-circuit logical expressions! + */ +static void gen_andl_op(Context *c, YYLTYPE *locp, unsigned bit_width, + const char *bit_suffix, HexValue *res, + enum OpTypes op_types, HexValue *op1, + HexValue *op2) +{ + (void) bit_width; + HexValue tmp1, tmp2; + HexValue zero =3D gen_constant(c, locp, "0", 32, UNSIGNED); + memset(&tmp1, 0, sizeof(HexValue)); + memset(&tmp2, 0, sizeof(HexValue)); + switch (op_types) { + case IMM_IMM: + case IMM_REG: + case REG_IMM: + yyassert(c, locp, false, "ANDL between IMM op IMM, IMM op REG, and" + " REG op IMM, not handled!"); + break; + case REG_REG: + tmp1 =3D gen_bin_cmp(c, locp, TCG_COND_NE, op1, &zero); + tmp2 =3D gen_bin_cmp(c, locp, TCG_COND_NE, op2, &zero); + OUT(c, locp, "tcg_gen_and_", bit_suffix, + "(", res, ", ", &tmp1, ", ", &tmp2, ");\n"); + gen_rvalue_free_manual(c, locp, &zero); + gen_rvalue_free(c, locp, &tmp1); + gen_rvalue_free(c, locp, &tmp2); + break; + } +} + +static void gen_minmax_op(Context *c, YYLTYPE *locp, unsigned bit_width, + HexValue *res, enum OpTypes op_types, + HexValue *op1, HexValue *op2, bool minmax) +{ + const char *mm; + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + bool is_unsigned; + + assert_signedness(c, locp, res->signedness); + is_unsigned =3D res->signedness =3D=3D UNSIGNED; + + if (minmax) { + /* Max */ + mm =3D is_unsigned ? "tcg_gen_umax" : "tcg_gen_smax"; + } else { + /* Min */ + mm =3D is_unsigned ? "tcg_gen_umin" : "tcg_gen_smin"; + } + switch (op_types) { + case IMM_IMM: + yyassert(c, locp, false, "MINMAX between IMM op IMM, not handled!"= ); + break; + case IMM_REG: + op1_m.bit_width =3D bit_width; + op1_m =3D rvalue_materialize(c, locp, &op1_m); + OUT(c, locp, mm, "_i", &bit_width, "("); + OUT(c, locp, res, ", ", &op1_m, ", ", op2, ");\n"); + break; + case REG_IMM: + op2_m.bit_width =3D bit_width; + op2_m =3D rvalue_materialize(c, locp, &op2_m); + /* Fallthrough */ + case REG_REG: + OUT(c, locp, mm, "_i", &bit_width, "("); + OUT(c, locp, res, ", ", op1, ", ", &op2_m, ");\n"); + break; + } + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); +} + +/* Code generation functions */ +HexValue gen_bin_op(Context *c, + YYLTYPE *locp, + OpType type, + HexValue *op1, + HexValue *op2) +{ + /* Replicate operands to avoid side effects */ + HexValue op1_m =3D *op1; + HexValue op2_m =3D *op2; + enum OpTypes op_types; + bool op_is64bit; + HexSignedness signedness; + unsigned bit_width; + const char *bit_suffix; + HexValue res; + + memset(&res, 0, sizeof(HexValue)); + + /* + * If the operands are VARID's we need to look up the + * type information. + */ + if (op1_m.type =3D=3D VARID) { + find_variable(c, locp, &op1_m, &op1_m); + } + if (op2_m.type =3D=3D VARID) { + find_variable(c, locp, &op2_m, &op2_m); + } + + op_types =3D (op1_m.type !=3D IMMEDIATE) << 1 + | (op2_m.type !=3D IMMEDIATE); + op_is64bit =3D op1_m.bit_width =3D=3D 64 || op2_m.bit_width =3D=3D 64; + /* Shift greater than 32 are 64 bits wide */ + + if (type =3D=3D ASL_OP && op2_m.type =3D=3D IMMEDIATE && + op2_m.imm.type =3D=3D VALUE && op2_m.imm.value >=3D 32) { + op_is64bit =3D true; + } + + bit_width =3D (op_is64bit) ? 64 : 32; + bit_suffix =3D op_is64bit ? "i64" : "i32"; + + /* Extend to 64-bits, if required */ + if (op_is64bit) { + op1_m =3D gen_rvalue_extend(c, locp, &op1_m); + op2_m =3D gen_rvalue_extend(c, locp, &op2_m); + } + + signedness =3D bin_op_signedness(c, locp, op1_m.signedness, op2_m.sign= edness); + if (op_types !=3D IMM_IMM) { + res =3D gen_tmp(c, locp, bit_width, signedness); + } else { + res =3D gen_imm_qemu_tmp(c, locp, bit_width, signedness); + } + + switch (type) { + case ADD_OP: + gen_simple_op(c, locp, bit_width, bit_suffix, &res, + op_types, &op1_m, &op2_m, + " + ", + "tcg_gen_addi_", + "tcg_gen_addi_", + "tcg_gen_add_"); + break; + case SUB_OP: + gen_sub_op(c, locp, bit_width, bit_suffix, &res, op_types, + &op1_m, &op2_m); + break; + case MUL_OP: + gen_simple_op(c, locp, bit_width, bit_suffix, &res, + op_types, &op1_m, &op2_m, + " * ", + "tcg_gen_muli_", + "tcg_gen_muli_", + "tcg_gen_mul_"); + break; + case ASL_OP: + gen_asl_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_ty= pes, + &op1_m, &op2_m); + break; + case ASR_OP: + gen_asr_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_ty= pes, + &op1_m, &op2_m); + break; + case LSR_OP: + gen_lsr_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_ty= pes, + &op1_m, &op2_m); + break; + case ANDB_OP: + gen_simple_op(c, locp, bit_width, bit_suffix, &res, + op_types, &op1_m, &op2_m, + " & ", + "tcg_gen_andi_", + "tcg_gen_andi_", + "tcg_gen_and_"); + break; + case ORB_OP: + gen_simple_op(c, locp, bit_width, bit_suffix, &res, + op_types, &op1_m, &op2_m, + " | ", + "tcg_gen_ori_", + "tcg_gen_ori_", + "tcg_gen_or_"); + break; + case XORB_OP: + gen_simple_op(c, locp, bit_width, bit_suffix, &res, + op_types, &op1_m, &op2_m, + " ^ ", + "tcg_gen_xori_", + "tcg_gen_xori_", + "tcg_gen_xor_"); + break; + case ANDL_OP: + gen_andl_op(c, locp, bit_width, bit_suffix, &res, op_types, &op1_m, + &op2_m); + break; + case MINI_OP: + gen_minmax_op(c, locp, bit_width, &res, op_types, &op1_m, &op2_m, + false); + break; + case MAXI_OP: + gen_minmax_op(c, locp, bit_width, &res, op_types, &op1_m, &op2_m, = true); + break; + } + return res; +} + +HexValue gen_cast_op(Context *c, + YYLTYPE *locp, + HexValue *src, + unsigned target_width, + HexSignedness signedness) +{ + assert_signedness(c, locp, src->signedness); + if (src->bit_width =3D=3D target_width) { + return *src; + } else if (src->type =3D=3D IMMEDIATE) { + HexValue res =3D *src; + res.bit_width =3D target_width; + res.signedness =3D signedness; + return res; + } else { + HexValue res =3D gen_tmp(c, locp, target_width, signedness); + /* Truncate */ + if (src->bit_width > target_width) { + OUT(c, locp, "tcg_gen_trunc_i64_tl(", &res, ", ", src, ");\n"); + } else { + assert_signedness(c, locp, src->signedness); + if (src->signedness =3D=3D UNSIGNED) { + /* Extend unsigned */ + OUT(c, locp, "tcg_gen_extu_i32_i64(", + &res, ", ", src, ");\n"); + } else { + /* Extend signed */ + OUT(c, locp, "tcg_gen_ext_i32_i64(", + &res, ", ", src, ");\n"); + } + } + gen_rvalue_free(c, locp, src); + return res; + } +} + + +/* + * Implements an extension when the `src_width` is an immediate. + * If the `value` to extend is also an immediate we use `extract/sextract` + * from QEMU `bitops.h`. If `value` is a TCGv then we rely on + * `tcg_gen_extract/tcg_gen_sextract`. + */ +static HexValue gen_extend_imm_width_op(Context *c, + YYLTYPE *locp, + HexValue *src_width, + unsigned dst_width, + HexValue *value, + HexSignedness signedness) +{ + /* + * If the source width is not an immediate value, we need to guard + * our extend op with if statements to handle the case where + * `src_width_m` is 0. + */ + const char *sign_prefix; + bool need_guarding; + + assert_signedness(c, locp, signedness); + assert(dst_width =3D=3D 64 || dst_width =3D=3D 32); + assert(src_width->type =3D=3D IMMEDIATE); + + sign_prefix =3D (signedness =3D=3D UNSIGNED) ? "" : "s"; + need_guarding =3D (src_width->imm.type !=3D VALUE); + + if (src_width->imm.type =3D=3D VALUE && + src_width->imm.value =3D=3D 0) { + /* + * We can bail out early if the source width is known to be zero + * at translation time. + */ + return gen_imm_value(c, locp, 0, dst_width, signedness); + } + + if (value->type =3D=3D IMMEDIATE) { + /* + * If both the value and source width are immediates, + * we can perform the extension at translation time + * using QEMUs bitops. + */ + HexValue res =3D gen_imm_qemu_tmp(c, locp, dst_width, signedness); + gen_c_int_type(c, locp, dst_width, signedness); + OUT(c, locp, " ", &res, " =3D 0;\n"); + if (need_guarding) { + OUT(c, locp, "if (", src_width, " !=3D 0) {\n"); + } + OUT(c, locp, &res, " =3D ", sign_prefix, "extract", &dst_width); + OUT(c, locp, "(", value, ", 0, ", src_width, ");\n"); + if (need_guarding) { + OUT(c, locp, "}\n"); + } + + gen_rvalue_free(c, locp, value); + return res; + } else { + /* + * If the source width is an immediate and the value to + * extend is a TCGv, then use tcg_gen_extract/tcg_gen_sextract + */ + HexValue res =3D gen_tmp(c, locp, dst_width, signedness); + + /* + * If the width is an immediate value we know it is non-zero + * at this point, otherwise we need an if-statement + */ + if (need_guarding) { + OUT(c, locp, "if (", src_width, " !=3D 0) {\n"); + } + OUT(c, locp, "tcg_gen_", sign_prefix, "extract_i", &dst_width); + OUT(c, locp, "(", &res, ", ", value, ", 0, ", src_width, + ");\n"); + if (need_guarding) { + OUT(c, locp, "} else {\n"); + OUT(c, locp, "tcg_gen_movi_i", &dst_width, "(", &res, + ", 0);\n"); + OUT(c, locp, "}\n"); + } + + gen_rvalue_free(c, locp, value); + return res; + } +} + +/* + * Implements an extension when the `src_width` is given by + * a TCGv. Here we need to reimplement the behaviour of + * `tcg_gen_extract` and the like using shifts and masks. + */ +static HexValue gen_extend_tcg_width_op(Context *c, + YYLTYPE *locp, + HexValue *src_width, + unsigned dst_width, + HexValue *value, + HexSignedness signedness) +{ + HexValue src_width_m =3D rvalue_materialize(c, locp, src_width); + HexValue zero =3D gen_constant(c, locp, "0", dst_width, UNSIGNED); + HexValue shift =3D gen_tmp(c, locp, dst_width, UNSIGNED); + HexValue res; + + assert_signedness(c, locp, signedness); + assert(dst_width =3D=3D 64 || dst_width =3D=3D 32); + assert(src_width->type !=3D IMMEDIATE); + + res =3D gen_tmp(c, locp, dst_width, signedness); + + OUT(c, locp, "tcg_gen_subfi_i", &dst_width); + OUT(c, locp, "(", &shift, ", ", &dst_width, ", ", &src_width_m, ");\n"= ); + if (signedness =3D=3D UNSIGNED) { + const char *mask_str =3D (dst_width =3D=3D 32) + ? "0xffffffff" + : "0xffffffffffffffff"; + HexValue mask =3D gen_tmp_value(c, locp, mask_str, + dst_width, UNSIGNED); + OUT(c, locp, "tcg_gen_shr_i", &dst_width, "(", + &mask, ", ", &mask, ", ", &shift, ");\n"); + OUT(c, locp, "tcg_gen_and_i", &dst_width, "(", + &res, ", ", value, ", ", &mask, ");\n"); + gen_rvalue_free(c, locp, &mask); + } else { + OUT(c, locp, "tcg_gen_shl_i", &dst_width, "(", + &res, ", ", value, ", ", &shift, ");\n"); + OUT(c, locp, "tcg_gen_sar_i", &dst_width, "(", + &res, ", ", &res, ", ", &shift, ");\n"); + } + OUT(c, locp, "tcg_gen_movcond_i", &dst_width, "(TCG_COND_EQ, ", &res, + ", "); + OUT(c, locp, &src_width_m, ", ", &zero, ", ", &zero, ", ", &res, + ");\n"); + + gen_rvalue_free(c, locp, &src_width_m); + gen_rvalue_free(c, locp, value); + gen_rvalue_free(c, locp, &shift); + + return res; +} + +HexValue gen_extend_op(Context *c, + YYLTYPE *locp, + HexValue *src_width, + unsigned dst_width, + HexValue *value, + HexSignedness signedness) +{ + unsigned bit_width =3D (dst_width =3D 64) ? 64 : 32; + HexValue value_m =3D *value; + HexValue src_width_m =3D *src_width; + + assert_signedness(c, locp, signedness); + yyassert(c, locp, value_m.bit_width <=3D bit_width && + src_width_m.bit_width <=3D bit_width, + "Extending to a size smaller than the current size" + " makes no sense"); + + if (value_m.bit_width < bit_width) { + value_m =3D gen_rvalue_extend(c, locp, &value_m); + } + + if (src_width_m.bit_width < bit_width) { + src_width_m =3D gen_rvalue_extend(c, locp, &src_width_m); + } + + if (src_width_m.type =3D=3D IMMEDIATE) { + return gen_extend_imm_width_op(c, locp, &src_width_m, bit_width, + &value_m, signedness); + } else { + return gen_extend_tcg_width_op(c, locp, &src_width_m, bit_width, + &value_m, signedness); + } +} + +/* + * Implements `rdeposit` for the special case where `width` + * is of TCGv type. In this case we need to reimplement the behaviour + * of `tcg_gen_deposit*` using binary operations and masks/shifts. + * + * Note: this is the only type of `rdeposit` that occurs, meaning the + * `width` is _NEVER_ of IMMEDIATE type. + */ +void gen_rdeposit_op(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value, + HexValue *begin, + HexValue *width) +{ + /* + * Otherwise if the width is not known, we fallback on reimplementing + * desposit in TCG. + */ + HexValue begin_m =3D *begin; + HexValue value_m =3D *value; + HexValue width_m =3D *width; + const char *mask_str =3D (dst->bit_width =3D=3D 32) + ? "0xffffffffUL" + : "0xffffffffffffffffUL"; + HexValue mask =3D gen_constant(c, locp, mask_str, dst->bit_width, + UNSIGNED); + const char *dst_width_str =3D (dst->bit_width =3D=3D 32) ? "32" : "64"; + HexValue k64 =3D gen_constant(c, locp, dst_width_str, dst->bit_width, + UNSIGNED); + HexValue res; + HexValue zero; + + assert(dst->bit_width >=3D value->bit_width); + assert(begin->type =3D=3D IMMEDIATE && begin->imm.type =3D=3D VALUE); + assert(dst->type =3D=3D REGISTER_ARG); + + yyassert(c, locp, width->type !=3D IMMEDIATE, + "Immediate index to rdeposit not handled!"); + + yyassert(c, locp, value_m.bit_width =3D=3D dst->bit_width && + begin_m.bit_width =3D=3D dst->bit_width && + width_m.bit_width =3D=3D dst->bit_width, + "Extension/truncation should be taken care of" + " before rdeposit!"); + + width_m =3D rvalue_materialize(c, locp, &width_m); + + /* + * mask =3D 0xffffffffffffffff >> (64 - width) + * mask =3D mask << begin + * value =3D (value << begin) & mask + * res =3D dst & ~mask + * res =3D res | value + * dst =3D (width !=3D 0) ? res : dst + */ + k64 =3D gen_bin_op(c, locp, SUB_OP, &k64, &width_m); + mask =3D gen_bin_op(c, locp, LSR_OP, &mask, &k64); + begin_m.is_manual =3D true; + mask =3D gen_bin_op(c, locp, ASL_OP, &mask, &begin_m); + mask.is_manual =3D true; + value_m =3D gen_bin_op(c, locp, ASL_OP, &value_m, &begin_m); + value_m =3D gen_bin_op(c, locp, ANDB_OP, &value_m, &mask); + + OUT(c, locp, "tcg_gen_not_i", &dst->bit_width, "(", &mask, ", ", + &mask, ");\n"); + mask.is_manual =3D false; + res =3D gen_bin_op(c, locp, ANDB_OP, dst, &mask); + res =3D gen_bin_op(c, locp, ORB_OP, &res, &value_m); + + /* + * We don't need to truncate `res` here, since all operations involved= use + * the same bit width. + */ + + /* If the width is zero, then return the identity dst =3D dst */ + zero =3D gen_constant(c, locp, "0", res.bit_width, UNSIGNED); + OUT(c, locp, "tcg_gen_movcond_i", &res.bit_width, "(TCG_COND_NE, ", + dst); + OUT(c, locp, ", ", &width_m, ", ", &zero, ", ", &res, ", ", dst, + ");\n"); + + gen_rvalue_free(c, locp, width); + gen_rvalue_free(c, locp, &res); +} + +void gen_deposit_op(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value, + HexValue *index, + HexCast *cast) +{ + HexValue value_m =3D *value; + unsigned bit_width =3D (dst->bit_width =3D=3D 64) ? 64 : 32; + unsigned width =3D cast->bit_width; + + yyassert(c, locp, index->type =3D=3D IMMEDIATE, + "Deposit index must be immediate!\n"); + + /* + * Using tcg_gen_deposit_i**(dst, dst, ...) requires dst to be + * initialized. + */ + gen_inst_init_args(c, locp); + + /* If the destination value is 32, truncate the value, otherwise exten= d */ + if (dst->bit_width !=3D value->bit_width) { + if (bit_width =3D=3D 32) { + value_m =3D gen_rvalue_truncate(c, locp, &value_m); + } else { + value_m =3D gen_rvalue_extend(c, locp, &value_m); + } + } + value_m =3D rvalue_materialize(c, locp, &value_m); + OUT(c, locp, "tcg_gen_deposit_i", &bit_width, "(", dst, ", ", dst, ", = "); + OUT(c, locp, &value_m, ", ", index, " * ", &width, ", ", &width, ");\n= "); + gen_rvalue_free(c, locp, index); + gen_rvalue_free(c, locp, &value_m); +} + +HexValue gen_rextract_op(Context *c, + YYLTYPE *locp, + HexValue *src, + unsigned begin, + unsigned width) +{ + unsigned bit_width =3D (src->bit_width =3D=3D 64) ? 64 : 32; + HexValue res =3D gen_tmp(c, locp, bit_width, UNSIGNED); + OUT(c, locp, "tcg_gen_extract_i", &bit_width, "(", &res); + OUT(c, locp, ", ", src, ", ", &begin, ", ", &width, ");\n"); + gen_rvalue_free(c, locp, src); + return res; +} + +HexValue gen_extract_op(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *index, + HexExtract *extract) +{ + unsigned bit_width =3D (src->bit_width =3D=3D 64) ? 64 : 32; + unsigned width =3D extract->bit_width; + const char *sign_prefix; + HexValue res; + + yyassert(c, locp, index->type =3D=3D IMMEDIATE, + "Extract index must be immediate!\n"); + assert_signedness(c, locp, extract->signedness); + + sign_prefix =3D (extract->signedness =3D=3D UNSIGNED) ? "" : "s"; + res =3D gen_tmp(c, locp, bit_width, extract->signedness); + + OUT(c, locp, "tcg_gen_", sign_prefix, "extract_i", &bit_width, + "(", &res, ", ", src); + OUT(c, locp, ", ", index, " * ", &width, ", ", &width, ");\n"); + + /* Some extract operations have bit_width !=3D storage_bit_width */ + if (extract->storage_bit_width > bit_width) { + HexValue tmp =3D gen_tmp(c, locp, extract->storage_bit_width, + extract->signedness); + const char *sign_suffix =3D (extract->signedness =3D=3D UNSIGNED) = ? "u" : ""; + OUT(c, locp, "tcg_gen_ext", sign_suffix, "_i32_i64(", + &tmp, ", ", &res, ");\n"); + gen_rvalue_free(c, locp, &res); + res =3D tmp; + } + + gen_rvalue_free(c, locp, src); + gen_rvalue_free(c, locp, index); + return res; +} + +void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *val= ue) +{ + HexValue value_m =3D *value; + yyassert(c, locp, reg->type =3D=3D REGISTER, "reg must be a register!"= ); + value_m =3D gen_rvalue_truncate(c, locp, &value_m); + value_m =3D rvalue_materialize(c, locp, &value_m); + OUT(c, + locp, + "gen_log_reg_write(", ®->reg.id, ", ", + &value_m, ");\n"); + OUT(c, + locp, + "ctx_log_reg_write(ctx, ", ®->reg.id, + ");\n"); + gen_rvalue_free(c, locp, reg); + gen_rvalue_free(c, locp, &value_m); +} + +void gen_assign(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *value) +{ + HexValue value_m =3D *value; + unsigned bit_width; + + yyassert(c, locp, !is_inside_ternary(c), + "Assign in ternary not allowed!"); + + if (dst->type =3D=3D REGISTER) { + gen_write_reg(c, locp, dst, &value_m); + return; + } + + if (dst->type =3D=3D VARID) { + find_variable(c, locp, dst, dst); + } + bit_width =3D dst->bit_width =3D=3D 64 ? 64 : 32; + + if (bit_width !=3D value_m.bit_width) { + if (bit_width =3D=3D 64) { + value_m =3D gen_rvalue_extend(c, locp, &value_m); + } else { + value_m =3D gen_rvalue_truncate(c, locp, &value_m); + } + } + + const char *imm_suffix =3D (value_m.type =3D=3D IMMEDIATE) ? "i" : ""; + OUT(c, locp, "tcg_gen_mov", imm_suffix, "_i", &bit_width, + "(", dst, ", ", &value_m, ");\n"); + + gen_rvalue_free(c, locp, &value_m); +} + +HexValue gen_convround(Context *c, + YYLTYPE *locp, + HexValue *src) +{ + HexValue src_m =3D *src; + unsigned bit_width =3D src_m.bit_width; + const char *size =3D (bit_width =3D=3D 32) ? "32" : "64"; + HexValue res =3D gen_tmp(c, locp, bit_width, src->signedness); + HexValue mask =3D gen_constant(c, locp, "0x3", bit_width, UNSIGNED); + HexValue one =3D gen_constant(c, locp, "1", bit_width, UNSIGNED); + HexValue and; + HexValue src_p1; + + src_m.is_manual =3D true; + + and =3D gen_bin_op(c, locp, ANDB_OP, &src_m, &mask); + src_p1 =3D gen_bin_op(c, locp, ADD_OP, &src_m, &one); + + OUT(c, locp, "tcg_gen_movcond_i", size, "(TCG_COND_EQ, ", &res); + OUT(c, locp, ", ", &and, ", ", &mask, ", "); + OUT(c, locp, &src_p1, ", ", &src_m, ");\n"); + + /* Free src but use the original `is_manual` value */ + gen_rvalue_free(c, locp, src); + + /* Free the rest of the values */ + gen_rvalue_free(c, locp, &src_p1); + + return res; +} + +static HexValue gen_convround_n_b(Context *c, + YYLTYPE *locp, + HexValue *a, + HexValue *n) +{ + HexValue one =3D gen_constant(c, locp, "1", 32, UNSIGNED); + HexValue res =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue tmp =3D gen_tmp(c, locp, 32, UNSIGNED); + HexValue tmp_64 =3D gen_tmp(c, locp, 64, UNSIGNED); + + assert(n->type !=3D IMMEDIATE); + OUT(c, locp, "tcg_gen_ext_i32_i64(", &res, ", ", a, ");\n"); + OUT(c, locp, "tcg_gen_shl_i32(", &tmp); + OUT(c, locp, ", ", &one, ", ", n, ");\n"); + OUT(c, locp, "tcg_gen_and_i32(", &tmp); + OUT(c, locp, ", ", &tmp, ", ", a, ");\n"); + OUT(c, locp, "tcg_gen_shri_i32(", &tmp); + OUT(c, locp, ", ", &tmp, ", 1);\n"); + OUT(c, locp, "tcg_gen_ext_i32_i64(", &tmp_64, ", ", &tmp, ");\n"); + OUT(c, locp, "tcg_gen_add_i64(", &res); + OUT(c, locp, ", ", &res, ", ", &tmp_64, ");\n"); + + gen_rvalue_free(c, locp, &tmp); + gen_rvalue_free(c, locp, &tmp_64); + + return res; +} + +static HexValue gen_convround_n_c(Context *c, + YYLTYPE *locp, + HexValue *a, + HexValue *n) +{ + HexValue res =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue one =3D gen_constant(c, locp, "1", 32, UNSIGNED); + HexValue tmp =3D gen_tmp(c, locp, 32, UNSIGNED); + HexValue tmp_64 =3D gen_tmp(c, locp, 64, UNSIGNED); + + OUT(c, locp, "tcg_gen_ext_i32_i64(", &res, ", ", a, ");\n"); + OUT(c, locp, "tcg_gen_subi_i32(", &tmp); + OUT(c, locp, ", ", n, ", 1);\n"); + OUT(c, locp, "tcg_gen_shl_i32(", &tmp); + OUT(c, locp, ", ", &one, ", ", &tmp, ");\n"); + OUT(c, locp, "tcg_gen_ext_i32_i64(", &tmp_64, ", ", &tmp, ");\n"); + OUT(c, locp, "tcg_gen_add_i64(", &res); + OUT(c, locp, ", ", &res, ", ", &tmp_64, ");\n"); + + gen_rvalue_free(c, locp, &one); + gen_rvalue_free(c, locp, &tmp); + gen_rvalue_free(c, locp, &tmp_64); + + return res; +} + +HexValue gen_convround_n(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *pos) +{ + HexValue zero =3D gen_constant(c, locp, "0", 64, UNSIGNED); + HexValue l_32 =3D gen_constant(c, locp, "1", 32, UNSIGNED); + HexValue cond =3D gen_tmp(c, locp, 32, UNSIGNED); + HexValue cond_64 =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue mask =3D gen_tmp(c, locp, 32, UNSIGNED); + HexValue n_64 =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue res =3D gen_tmp(c, locp, 64, UNSIGNED); + /* If input is 64 bit cast it to 32 */ + HexValue src_casted =3D gen_cast_op(c, locp, src, 32, src->signedness); + HexValue pos_casted =3D gen_cast_op(c, locp, pos, 32, pos->signedness); + HexValue r1; + HexValue r2; + HexValue r3; + + src_casted =3D rvalue_materialize(c, locp, &src_casted); + pos_casted =3D rvalue_materialize(c, locp, &pos_casted); + + /* + * r1, r2, and r3 represent the results of three different branches. + * - r1 picked if pos_casted =3D=3D 0 + * - r2 picked if (src_casted & ((1 << (pos_casted - 1)) - 1)) =3D= =3D 0), + * that is if bits 0, ..., pos_casted-1 are all 0. + * - r3 picked otherwise. + */ + r1 =3D gen_rvalue_extend(c, locp, &src_casted); + r2 =3D gen_convround_n_b(c, locp, &src_casted, &pos_casted); + r3 =3D gen_convround_n_c(c, locp, &src_casted, &pos_casted); + + /* + * Calculate the condition + * (src_casted & ((1 << (pos_casted - 1)) - 1)) =3D=3D 0), + * which checks if the bits 0,...,pos-1 are all 0. + */ + OUT(c, locp, "tcg_gen_sub_i32(", &mask); + OUT(c, locp, ", ", &pos_casted, ", ", &l_32, ");\n"); + OUT(c, locp, "tcg_gen_shl_i32(", &mask); + OUT(c, locp, ", ", &l_32, ", ", &mask, ");\n"); + OUT(c, locp, "tcg_gen_sub_i32(", &mask); + OUT(c, locp, ", ", &mask, ", ", &l_32, ");\n"); + OUT(c, locp, "tcg_gen_and_i32(", &cond); + OUT(c, locp, ", ", &src_casted, ", ", &mask, ");\n"); + OUT(c, locp, "tcg_gen_extu_i32_i64(", &cond_64, ", ", &cond, ");\n"); + + OUT(c, locp, "tcg_gen_ext_i32_i64(", &n_64, ", ", &pos_casted, ");\n"); + + /* + * if the bits 0, ..., pos_casted-1 are all 0, then pick r2 otherwise, + * pick r3. + */ + OUT(c, locp, "tcg_gen_movcond_i64"); + OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &cond_64, ", ", &zero); + OUT(c, locp, ", ", &r2, ", ", &r3, ");\n"); + + /* Lastly, if the pos_casted =3D=3D 0, then pick r1 */ + OUT(c, locp, "tcg_gen_movcond_i64"); + OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &n_64, ", ", &zero); + OUT(c, locp, ", ", &r1, ", ", &res, ");\n"); + + /* Finally shift back val >>=3D n */ + OUT(c, locp, "tcg_gen_shr_i64(", &res); + OUT(c, locp, ", ", &res, ", ", &n_64, ");\n"); + + gen_rvalue_free(c, locp, &src_casted); + gen_rvalue_free(c, locp, &pos_casted); + + gen_rvalue_free(c, locp, &r1); + gen_rvalue_free(c, locp, &r2); + gen_rvalue_free(c, locp, &r3); + + gen_rvalue_free(c, locp, &cond); + gen_rvalue_free(c, locp, &cond_64); + gen_rvalue_free(c, locp, &mask); + gen_rvalue_free(c, locp, &n_64); + + res =3D gen_rvalue_truncate(c, locp, &res); + return res; +} + +HexValue gen_round(Context *c, + YYLTYPE *locp, + HexValue *src, + HexValue *pos) +{ + HexValue zero =3D gen_constant(c, locp, "0", 64, UNSIGNED); + HexValue one =3D gen_constant(c, locp, "1", 64, UNSIGNED); + HexValue res; + HexValue n_m1; + HexValue shifted; + HexValue sum; + HexValue src_width; + HexValue a; + HexValue b; + + assert_signedness(c, locp, src->signedness); + yyassert(c, locp, src->bit_width <=3D 32, + "fRNDN not implemented for bit widths > 32!"); + + res =3D gen_tmp(c, locp, 64, src->signedness); + + src_width =3D gen_imm_value(c, locp, src->bit_width, 32, UNSIGNED); + a =3D gen_extend_op(c, locp, &src_width, 64, src, SIGNED); + a =3D rvalue_materialize(c, locp, &a); + + src_width =3D gen_imm_value(c, locp, 5, 32, UNSIGNED); + b =3D gen_extend_op(c, locp, &src_width, 64, pos, UNSIGNED); + b =3D rvalue_materialize(c, locp, &b); + + /* Disable auto-free of values used more than once */ + a.is_manual =3D true; + b.is_manual =3D true; + + n_m1 =3D gen_bin_op(c, locp, SUB_OP, &b, &one); + shifted =3D gen_bin_op(c, locp, ASL_OP, &one, &n_m1); + sum =3D gen_bin_op(c, locp, ADD_OP, &shifted, &a); + + OUT(c, locp, "tcg_gen_movcond_i64"); + OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &b, ", ", &zero); + OUT(c, locp, ", ", &a, ", ", &sum, ");\n"); + + gen_rvalue_free_manual(c, locp, &a); + gen_rvalue_free_manual(c, locp, &b); + gen_rvalue_free(c, locp, &sum); + + return res; +} + +/* Circular addressing mode with auto-increment */ +void gen_circ_op(Context *c, + YYLTYPE *locp, + HexValue *addr, + HexValue *increment, + HexValue *modifier) +{ + HexValue cs =3D gen_tmp(c, locp, 32, UNSIGNED); + HexValue increment_m =3D *increment; + increment_m =3D rvalue_materialize(c, locp, &increment_m); + OUT(c, locp, "gen_read_reg(", &cs, ", HEX_REG_CS0 + MuN);\n"); + OUT(c, + locp, + "gen_helper_fcircadd(", + addr, + ", ", + addr, + ", ", + &increment_m, + ", ", + modifier); + OUT(c, locp, ", ", &cs, ");\n"); + gen_rvalue_free(c, locp, &increment_m); + gen_rvalue_free(c, locp, modifier); + gen_rvalue_free(c, locp, &cs); +} + +HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src) +{ + const char *bit_suffix =3D src->bit_width =3D=3D 64 ? "64" : "32"; + HexValue src_m =3D *src; + HexValue res; + + assert_signedness(c, locp, src->signedness); + res =3D gen_tmp(c, locp, src->bit_width =3D=3D 64 ? 64 : 32, src->sign= edness); + src_m =3D rvalue_materialize(c, locp, &src_m); + OUT(c, locp, "tcg_gen_not_i", bit_suffix, "(", + &res, ", ", &src_m, ");\n"); + OUT(c, locp, "tcg_gen_clzi_i", bit_suffix, "(", &res, ", ", &res, ", "= ); + OUT(c, locp, bit_suffix, ");\n"); + gen_rvalue_free(c, locp, &src_m); + return res; +} + +HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src) +{ + const char *bit_suffix =3D src->bit_width =3D=3D 64 ? "64" : "32"; + HexValue src_m =3D *src; + HexValue res; + assert_signedness(c, locp, src->signedness); + res =3D gen_tmp(c, locp, src->bit_width =3D=3D 64 ? 64 : 32, src->sign= edness); + src_m =3D rvalue_materialize(c, locp, &src_m); + OUT(c, locp, "tcg_gen_ctpop_i", bit_suffix, + "(", &res, ", ", &src_m, ");\n"); + gen_rvalue_free(c, locp, &src_m); + return res; +} + +HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *widt= h) +{ + const char *suffix =3D src->bit_width =3D=3D 64 ? "i64" : "i32"; + HexValue amount =3D *width; + HexValue res; + assert_signedness(c, locp, src->signedness); + res =3D gen_tmp(c, locp, src->bit_width, src->signedness); + if (amount.bit_width < src->bit_width) { + amount =3D gen_rvalue_extend(c, locp, &amount); + } else { + amount =3D gen_rvalue_truncate(c, locp, &amount); + } + amount =3D rvalue_materialize(c, locp, &amount); + OUT(c, locp, "tcg_gen_rotl_", suffix, "(", + &res, ", ", src, ", ", &amount, ");\n"); + gen_rvalue_free(c, locp, src); + gen_rvalue_free(c, locp, &amount); + + return res; +} + +HexValue gen_carry_from_add(Context *c, + YYLTYPE *locp, + HexValue *op1, + HexValue *op2, + HexValue *op3) +{ + HexValue zero =3D gen_constant(c, locp, "0", 64, UNSIGNED); + HexValue res =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue cf =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue op1_m =3D rvalue_materialize(c, locp, op1); + HexValue op2_m =3D rvalue_materialize(c, locp, op2); + HexValue op3_m =3D rvalue_materialize(c, locp, op3); + op3_m =3D gen_rvalue_extend(c, locp, &op3_m); + + OUT(c, locp, "tcg_gen_add2_i64(", &res, ", ", &cf, ", ", &op1_m, ", ", + &zero); + OUT(c, locp, ", ", &op3_m, ", ", &zero, ");\n"); + OUT(c, locp, "tcg_gen_add2_i64(", &res, ", ", &cf, ", ", &res, ", ", &= cf); + OUT(c, locp, ", ", &op2_m, ", ", &zero, ");\n"); + + gen_rvalue_free(c, locp, &op1_m); + gen_rvalue_free(c, locp, &op2_m); + gen_rvalue_free(c, locp, &op3_m); + gen_rvalue_free(c, locp, &res); + return cf; +} + +void gen_addsat64(Context *c, + YYLTYPE *locp, + HexValue *dst, + HexValue *op1, + HexValue *op2) +{ + HexValue op1_m =3D rvalue_materialize(c, locp, op1); + HexValue op2_m =3D rvalue_materialize(c, locp, op2); + OUT(c, locp, "gen_add_sat_i64(", dst, ", ", &op1_m, ", ", &op2_m, ");\= n"); +} + +void gen_inst(Context *c, GString *iname) +{ + c->total_insn++; + c->inst.name =3D iname; + c->inst.allocated =3D g_array_new(FALSE, FALSE, sizeof(Var)); + c->inst.init_list =3D g_array_new(FALSE, FALSE, sizeof(HexValue)); + c->inst.strings =3D g_array_new(FALSE, FALSE, sizeof(GString *)); + EMIT_SIG(c, "void emit_%s(DisasContext *ctx, Insn *insn, Packet *pkt", + c->inst.name->str); +} + + +/* + * Initialize declared but uninitialized registers, but only for + * non-conditional instructions + */ +void gen_inst_init_args(Context *c, YYLTYPE *locp) +{ + if (!c->inst.init_list) { + return; + } + + for (unsigned i =3D 0; i < c->inst.init_list->len; i++) { + HexValue *val =3D &g_array_index(c->inst.init_list, HexValue, i); + if (val->type =3D=3D REGISTER_ARG) { + char reg_id[5]; + reg_compose(c, locp, &val->reg, reg_id); + EMIT_HEAD(c, "tcg_gen_movi_i%u(%s, 0);\n", val->bit_width, reg= _id); + } else if (val->type =3D=3D PREDICATE) { + char suffix =3D val->is_dotnew ? 'N' : 'V'; + EMIT_HEAD(c, "tcg_gen_movi_i%u(P%c%c, 0);\n", val->bit_width, + val->pred.id, suffix); + } else { + yyassert(c, locp, false, "Invalid arg type!"); + } + } + + /* Free argument init list once we have initialized everything */ + g_array_free(c->inst.init_list, TRUE); + c->inst.init_list =3D NULL; +} + +void gen_inst_code(Context *c, YYLTYPE *locp) +{ + if (c->inst.error_count !=3D 0) { + fprintf(stderr, + "Parsing of instruction %s generated %d errors!\n", + c->inst.name->str, + c->inst.error_count); + } else { + free_variables(c, locp); + c->implemented_insn++; + fprintf(c->enabled_file, "%s\n", c->inst.name->str); + emit_footer(c); + commit(c); + } + free_instruction(c); +} + +void gen_pred_assign(Context *c, YYLTYPE *locp, HexValue *left_pred, + HexValue *right_pred) +{ + char pred_id[2] =3D {left_pred->pred.id, 0}; + bool is_direct =3D is_direct_predicate(left_pred); + HexValue r =3D rvalue_materialize(c, locp, right_pred); + r =3D gen_rvalue_truncate(c, locp, &r); + yyassert(c, locp, !is_inside_ternary(c), + "Predicate assign not allowed in ternary!"); + /* Extract predicate TCGv */ + if (is_direct) { + *left_pred =3D gen_tmp_value(c, locp, "0", 32, UNSIGNED); + } + /* Extract first 8 bits, and store new predicate value */ + OUT(c, locp, "tcg_gen_mov_i32(", left_pred, ", ", &r, ");\n"); + OUT(c, locp, "tcg_gen_andi_i32(", left_pred, ", ", left_pred, + ", 0xff);\n"); + if (is_direct) { + OUT(c, locp, "gen_log_pred_write(ctx, ", pred_id, ", ", left_pred, + ");\n"); + OUT(c, locp, "ctx_log_pred_write(ctx, ", pred_id, ");\n"); + gen_rvalue_free(c, locp, left_pred); + } + /* Free temporary value */ + gen_rvalue_free(c, locp, &r); +} + +void gen_cancel(Context *c, YYLTYPE *locp) +{ + OUT(c, locp, "gen_cancel(insn->slot);\n"); +} + +void gen_load_cancel(Context *c, YYLTYPE *locp) +{ + gen_cancel(c, locp); + OUT(c, locp, "if (insn->slot =3D=3D 0 && pkt->pkt_has_store_s1) {\n"); + OUT(c, locp, "ctx->s1_store_processed =3D false;\n"); + OUT(c, locp, "process_store(ctx, 1);\n"); + OUT(c, locp, "}\n"); +} + +void gen_load(Context *c, YYLTYPE *locp, HexValue *width, + HexSignedness signedness, HexValue *ea, HexValue *dst) +{ + char size_suffix[4] =3D {0}; + const char *sign_suffix; + /* Memop width is specified in the load macro */ + assert_signedness(c, locp, signedness); + sign_suffix =3D (width->imm.value > 4) + ? "" + : ((signedness =3D=3D UNSIGNED) ? "u" : "s"); + /* If dst is a variable, assert that is declared and load the type inf= o */ + if (dst->type =3D=3D VARID) { + find_variable(c, locp, dst, dst); + } + + snprintf(size_suffix, 4, "%" PRIu64, width->imm.value * 8); + /* Lookup the effective address EA */ + find_variable(c, locp, ea, ea); + OUT(c, locp, "if (insn->slot =3D=3D 0 && pkt->pkt_has_store_s1) {\n"); + OUT(c, locp, "probe_noshuf_load(", ea, ", ", width, ", ctx->mem_idx);\= n"); + OUT(c, locp, "process_store(ctx, 1);\n"); + OUT(c, locp, "}\n"); + OUT(c, locp, "tcg_gen_qemu_ld", size_suffix, sign_suffix); + OUT(c, locp, "("); + if (dst->bit_width > width->imm.value * 8) { + /* + * Cast to the correct TCG type if necessary, to avoid implict cast + * warnings. This is needed when the width of the destination var = is + * larger than the size of the requested load. + */ + OUT(c, locp, "(TCGv) "); + } + OUT(c, locp, dst, ", ", ea, ", ctx->mem_idx);\n"); + /* If the var in EA was truncated it is now a tmp HexValue, so free it= . */ + gen_rvalue_free(c, locp, ea); +} + +void gen_store(Context *c, YYLTYPE *locp, HexValue *width, HexValue *ea, + HexValue *src) +{ + HexValue src_m =3D *src; + /* Memop width is specified in the store macro */ + unsigned mem_width =3D width->imm.value; + /* Lookup the effective address EA */ + find_variable(c, locp, ea, ea); + src_m =3D rvalue_materialize(c, locp, &src_m); + OUT(c, locp, "gen_store", &mem_width, "(cpu_env, ", ea, ", ", &src_m); + OUT(c, locp, ", insn->slot);\n"); + gen_rvalue_free(c, locp, &src_m); + /* If the var in ea was truncated it is now a tmp HexValue, so free it= . */ + gen_rvalue_free(c, locp, ea); +} + +void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n, + HexValue *dst, HexValue *value) +{ + yyassert(c, locp, n->type =3D=3D IMMEDIATE, + "Deposit index must be immediate!\n"); + if (dst->type =3D=3D VARID) { + find_variable(c, locp, dst, dst); + } + + gen_deposit_op(c, locp, dst, value, n, sh); +} + +void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo, + HexValue *dst, HexValue *value) +{ + unsigned len; + HexValue tmp; + + yyassert(c, locp, hi->type =3D=3D IMMEDIATE && + hi->imm.type =3D=3D VALUE && + lo->type =3D=3D IMMEDIATE && + lo->imm.type =3D=3D VALUE, + "Range deposit needs immediate values!\n"); + + *value =3D gen_rvalue_truncate(c, locp, value); + len =3D hi->imm.value + 1 - lo->imm.value; + tmp =3D gen_tmp(c, locp, 32, value->signedness); + /* Emit an `and` to ensure `value` is either 0 or 1. */ + OUT(c, locp, "tcg_gen_andi_i32(", &tmp, ", ", value, ", 1);\n"); + /* Use `neg` to map 0 -> 0 and 1 -> 0xffff... */ + OUT(c, locp, "tcg_gen_neg_i32(", &tmp, ", ", &tmp, ");\n"); + OUT(c, locp, "tcg_gen_deposit_i32(", dst, ", ", dst, + ", ", &tmp, ", "); + OUT(c, locp, lo, ", ", &len, ");\n"); + + gen_rvalue_free(c, locp, &tmp); + gen_rvalue_free(c, locp, hi); + gen_rvalue_free(c, locp, lo); + gen_rvalue_free(c, locp, value); +} + +unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond) +{ + const char *bit_suffix; + /* Generate an end label, if false branch to that label */ + OUT(c, locp, "TCGLabel *if_label_", &c->inst.if_count, + " =3D gen_new_label();\n"); + *cond =3D rvalue_materialize(c, locp, cond); + bit_suffix =3D (cond->bit_width =3D=3D 64) ? "i64" : "i32"; + OUT(c, locp, "tcg_gen_brcondi_", bit_suffix, "(TCG_COND_EQ, ", cond, + ", 0, if_label_", &c->inst.if_count, ");\n"); + gen_rvalue_free(c, locp, cond); + return c->inst.if_count++; +} + +unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index) +{ + unsigned if_index =3D c->inst.if_count++; + /* Generate label to jump if else is not verified */ + OUT(c, locp, "TCGLabel *if_label_", &if_index, + " =3D gen_new_label();\n"); + /* Jump out of the else statement */ + OUT(c, locp, "tcg_gen_br(if_label_", &if_index, ");\n"); + /* Fix the else label */ + OUT(c, locp, "gen_set_label(if_label_", &index, ");\n"); + return if_index; +} + +HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred) +{ + /* Predicted instructions need to zero out result args */ + gen_inst_init_args(c, locp); + + if (is_direct_predicate(pred)) { + bool is_dotnew =3D pred->is_dotnew; + char predicate_id[2] =3D { pred->pred.id, '\0' }; + char *pred_str =3D (char *) &predicate_id; + *pred =3D gen_tmp_value(c, locp, "0", 32, UNSIGNED); + if (is_dotnew) { + OUT(c, locp, "tcg_gen_mov_i32(", pred, + ", hex_new_pred_value["); + OUT(c, locp, pred_str, "]);\n"); + } else { + OUT(c, locp, "gen_read_preg(", pred, ", ", pred_str, ");\n"); + } + } + + return *pred; +} + +HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var) +{ + find_variable(c, locp, var, var); + return *var; +} + +HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, + HexValue *op1, HexValue *op2) +{ + HexValue res; + memset(&res, 0, sizeof(HexValue)); + + assert_signedness(c, locp, mpy->first_signedness); + assert_signedness(c, locp, mpy->second_signedness); + + *op1 =3D gen_cast_op(c, locp, op1, mpy->first_bit_width * 2, + mpy->first_signedness); + /* Handle fMPTY3216.. */ + if (mpy->first_bit_width =3D=3D 32) { + *op2 =3D gen_cast_op(c, locp, op2, 64, mpy->second_signedness); + } else { + *op2 =3D gen_cast_op(c, locp, op2, mpy->second_bit_width * 2, + mpy->second_signedness); + } + res =3D gen_bin_op(c, locp, MUL_OP, op1, op2); + /* Handle special cases required by the language */ + if (mpy->first_bit_width =3D=3D 16 && mpy->second_bit_width =3D=3D 16)= { + HexValue src_width =3D gen_imm_value(c, locp, 32, 32, UNSIGNED); + HexSignedness signedness =3D bin_op_signedness(c, locp, + mpy->first_signedness, + mpy->second_signednes= s); + res =3D gen_extend_op(c, locp, &src_width, 64, &res, + signedness); + } + return res; +} + +static inline HexValue gen_rvalue_simple_unary(Context *c, YYLTYPE *locp, + HexValue *value, + const char *c_code, + const char *tcg_code) +{ + unsigned bit_width =3D (value->bit_width =3D=3D 64) ? 64 : 32; + HexValue res; + if (value->type =3D=3D IMMEDIATE) { + res =3D gen_imm_qemu_tmp(c, locp, bit_width, value->signedness); + gen_c_int_type(c, locp, value->bit_width, value->signedness); + OUT(c, locp, " ", &res, " =3D ", c_code, "(", value, ");\n"); + } else { + res =3D gen_tmp(c, locp, bit_width, value->signedness); + OUT(c, locp, tcg_code, "_i", &bit_width, "(", &res, ", ", value, + ");\n"); + gen_rvalue_free(c, locp, value); + } + return res; +} + + +HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value) +{ + return gen_rvalue_simple_unary(c, locp, value, "~", "tcg_gen_not"); +} + +HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value) +{ + unsigned bit_width =3D (value->bit_width =3D=3D 64) ? 64 : 32; + HexValue res; + if (value->type =3D=3D IMMEDIATE) { + res =3D gen_imm_qemu_tmp(c, locp, bit_width, value->signedness); + gen_c_int_type(c, locp, value->bit_width, value->signedness); + OUT(c, locp, " ", &res, " =3D !(", value, ");\n"); + } else { + HexValue zero =3D gen_constant(c, locp, "0", bit_width, UNSIGNED); + HexValue one =3D gen_constant(c, locp, "0xff", bit_width, UNSIGNED= ); + res =3D gen_tmp(c, locp, bit_width, value->signedness); + OUT(c, locp, "tcg_gen_movcond_i", &bit_width); + OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", value, ", ", &zero); + OUT(c, locp, ", ", &one, ", ", &zero, ");\n"); + gen_rvalue_free(c, locp, value); + } + return res; +} + +HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, + HexValue *width, HexValue *value) +{ + const char *unsigned_str; + const char *bit_suffix =3D (value->bit_width =3D=3D 64) ? "i64" : "i32= "; + HexValue res; + HexValue ovfl; + /* + * Note: all saturates are assumed to implicitly set overflow. + * This assumption holds for the instructions currently parsed + * by idef-parser. + */ + yyassert(c, locp, width->imm.value < value->bit_width, + "To compute overflow, source width must be greater than" + " saturation width!"); + yyassert(c, locp, !is_inside_ternary(c), + "Saturating from within a ternary is not allowed!"); + assert_signedness(c, locp, sat->signedness); + + unsigned_str =3D (sat->signedness =3D=3D UNSIGNED) ? "u" : ""; + res =3D gen_tmp_local(c, locp, value->bit_width, sat->signedness); + ovfl =3D gen_tmp_local(c, locp, 32, sat->signedness); + OUT(c, locp, "gen_sat", unsigned_str, "_", bit_suffix, "_ovfl("); + OUT(c, locp, &ovfl, ", ", &res, ", ", value, ", ", &width->imm.value, + ");\n"); + OUT(c, locp, "gen_set_usr_field_if(USR_OVF,", &ovfl, ");\n"); + gen_rvalue_free(c, locp, value); + + return res; +} + +HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value) +{ + HexValue key =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue res =3D gen_tmp(c, locp, 64, UNSIGNED); + HexValue frame_key =3D gen_tmp(c, locp, 32, UNSIGNED); + *value =3D gen_rvalue_extend(c, locp, value); + OUT(c, locp, "gen_read_reg(", &frame_key, ", HEX_REG_FRAMEKEY);\n"); + OUT(c, locp, "tcg_gen_concat_i32_i64(", + &key, ", ", &frame_key, ", ", &frame_key, ");\n"); + OUT(c, locp, "tcg_gen_xor_i64(", &res, ", ", value, ", ", &key, ");\n"= ); + gen_rvalue_free(c, locp, &key); + gen_rvalue_free(c, locp, &frame_key); + gen_rvalue_free(c, locp, value); + return res; +} + +HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value) +{ + return gen_rvalue_simple_unary(c, locp, value, "abs", "tcg_gen_abs"); +} + +HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value) +{ + return gen_rvalue_simple_unary(c, locp, value, "-", "tcg_gen_neg"); +} + +HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value) +{ + HexValue res; + yyassert(c, locp, value->bit_width <=3D 32, + "fbrev not implemented for 64-bit integers!"); + res =3D gen_tmp(c, locp, value->bit_width, value->signedness); + *value =3D rvalue_materialize(c, locp, value); + OUT(c, locp, "gen_helper_fbrev(", &res, ", ", value, ");\n"); + gen_rvalue_free(c, locp, value); + return res; +} + +HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond, + HexValue *true_branch, HexValue *false_branch) +{ + bool is_64bit =3D (true_branch->bit_width =3D=3D 64) || + (false_branch->bit_width =3D=3D 64); + unsigned bit_width =3D (is_64bit) ? 64 : 32; + HexValue zero =3D gen_constant(c, locp, "0", bit_width, UNSIGNED); + HexValue res =3D gen_tmp(c, locp, bit_width, UNSIGNED); + Ternary *ternary =3D NULL; + + if (is_64bit) { + *cond =3D gen_rvalue_extend(c, locp, cond); + *true_branch =3D gen_rvalue_extend(c, locp, true_branch); + *false_branch =3D gen_rvalue_extend(c, locp, false_branch); + } else { + *cond =3D gen_rvalue_truncate(c, locp, cond); + } + *cond =3D rvalue_materialize(c, locp, cond); + *true_branch =3D rvalue_materialize(c, locp, true_branch); + *false_branch =3D rvalue_materialize(c, locp, false_branch); + + OUT(c, locp, "tcg_gen_movcond_i", &bit_width); + OUT(c, locp, "(TCG_COND_NE, ", &res, ", ", cond, ", ", &zero); + OUT(c, locp, ", ", true_branch, ", ", false_branch, ");\n"); + + assert(c->ternary->len > 0); + ternary =3D &g_array_index(c->ternary, Ternary, c->ternary->len - 1); + gen_rvalue_free_manual(c, locp, &ternary->cond); + g_array_remove_index(c->ternary, c->ternary->len - 1); + + gen_rvalue_free(c, locp, cond); + gen_rvalue_free(c, locp, true_branch); + gen_rvalue_free(c, locp, false_branch); + return res; +} + +const char *cond_to_str(TCGCond cond) +{ + switch (cond) { + case TCG_COND_NEVER: + return "TCG_COND_NEVER"; + case TCG_COND_ALWAYS: + return "TCG_COND_ALWAYS"; + case TCG_COND_EQ: + return "TCG_COND_EQ"; + case TCG_COND_NE: + return "TCG_COND_NE"; + case TCG_COND_LT: + return "TCG_COND_LT"; + case TCG_COND_GE: + return "TCG_COND_GE"; + case TCG_COND_LE: + return "TCG_COND_LE"; + case TCG_COND_GT: + return "TCG_COND_GT"; + case TCG_COND_LTU: + return "TCG_COND_LTU"; + case TCG_COND_GEU: + return "TCG_COND_GEU"; + case TCG_COND_LEU: + return "TCG_COND_LEU"; + case TCG_COND_GTU: + return "TCG_COND_GTU"; + default: + abort(); + } +} + +void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg) +{ + switch (arg->type) { + case REGISTER_ARG: + if (arg->reg.type =3D=3D DOTNEW) { + EMIT_SIG(c, ", TCGv N%cN", arg->reg.id); + } else { + bool is64 =3D (arg->bit_width =3D=3D 64); + const char *type =3D is64 ? "TCGv_i64" : "TCGv_i32"; + char reg_id[5]; + reg_compose(c, locp, &(arg->reg), reg_id); + EMIT_SIG(c, ", %s %s", type, reg_id); + /* MuV register requires also MuN to provide its index */ + if (arg->reg.type =3D=3D MODIFIER) { + EMIT_SIG(c, ", int MuN"); + } + } + break; + case PREDICATE: + { + char suffix =3D arg->is_dotnew ? 'N' : 'V'; + EMIT_SIG(c, ", TCGv P%c%c", arg->pred.id, suffix); + } + break; + default: + { + fprintf(stderr, "emit_arg got unsupported argument!"); + abort(); + } + } +} + +void emit_footer(Context *c) +{ + EMIT(c, "}\n"); + EMIT(c, "\n"); +} + +void track_string(Context *c, GString *s) +{ + g_array_append_val(c->inst.strings, s); +} + +void free_variables(Context *c, YYLTYPE *locp) +{ + for (unsigned i =3D 0; i < c->inst.allocated->len; ++i) { + Var *var =3D &g_array_index(c->inst.allocated, Var, i); + const char *suffix =3D var->bit_width =3D=3D 64 ? "i64" : "i32"; + OUT(c, locp, "tcg_temp_free_", suffix, "(", var->name->str, ");\n"= ); + } +} + +void free_instruction(Context *c) +{ + assert(!is_inside_ternary(c)); + /* Free the strings */ + g_string_truncate(c->signature_str, 0); + g_string_truncate(c->out_str, 0); + g_string_truncate(c->header_str, 0); + /* Free strings allocated by the instruction */ + for (unsigned i =3D 0; i < c->inst.strings->len; i++) { + g_string_free(g_array_index(c->inst.strings, GString*, i), TRUE); + } + g_array_free(c->inst.strings, TRUE); + /* Free INAME token value */ + g_string_free(c->inst.name, TRUE); + /* Free variables and registers */ + g_array_free(c->inst.allocated, TRUE); + /* Initialize instruction-specific portion of the context */ + memset(&(c->inst), 0, sizeof(Inst)); +} + +void assert_signedness(Context *c, + YYLTYPE *locp, + HexSignedness signedness) +{ + yyassert(c, locp, + signedness !=3D UNKNOWN_SIGNEDNESS, + "Unspecified signedness"); +} diff --git a/target/hexagon/idef-parser/idef-parser.y b/target/hexagon/idef= -parser/idef-parser.y new file mode 100644 index 0000000000..8be44a0ad1 --- /dev/null +++ b/target/hexagon/idef-parser/idef-parser.y @@ -0,0 +1,965 @@ +%{ +/* + * Copyright(c) 2019-2022 rev.ng Labs Srl. All Rights Reserved. + * + * 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 "idef-parser.h" +#include "parser-helpers.h" +#include "idef-parser.tab.h" +#include "idef-parser.yy.h" + +/* Uncomment this to disable yyasserts */ +/* #define NDEBUG */ + +#define ERR_LINE_CONTEXT 40 + +%} + +%lex-param {void *scanner} +%parse-param {void *scanner} +%parse-param {Context *c} + +%define parse.error verbose +%define parse.lac full +%define api.pure full + +%locations + +%union { + GString *string; + HexValue rvalue; + HexSat sat; + HexCast cast; + HexExtract extract; + HexMpy mpy; + HexSignedness signedness; + int index; +} + +/* Tokens */ +%start input + +%expect 1 + +%token IN INAME VAR +%token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS A= SL +%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT +%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC NPC LPCFG +%token LOAD_CANCEL CANCEL IDENTITY PART1 ROTL INSBITS SETBITS EXTRANGE +%token CAST4_8U FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW +%token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG + +%token REG IMM PRED +%token ELSE +%token MPY +%token SAT +%token CAST DEPOSIT SETHALF +%token EXTRACT +%type INAME +%type rvalue lvalue VAR assign_statement var var_decl var_type +%type FAIL +%type TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T +%type if_stmt IF +%type SIGN + +/* Operator Precedences */ +%left MIN MAX +%left '(' +%left ',' +%left '=3D' +%right CIRCADD +%right INC DEC ANDA ORA XORA +%left '?' ':' +%left ANDL +%left '|' +%left '^' ANDOR +%left '&' +%left EQ NEQ +%left '<' '>' LTE GTE +%left ASL ASR LSR +%right ABS +%left '-' '+' +%left '*' '/' '%' MPY +%right '~' '!' +%left '[' +%right CAST +%right LOCNT BREV + +/* Bison Grammar */ +%% + +/* Input file containing the description of each hexagon instruction */ +input : instructions + { + YYACCEPT; + } + ; + +instructions : instruction instructions + | %empty + ; + +instruction : INAME + { + gen_inst(c, $1); + } + arguments + { + EMIT_SIG(c, ")"); + EMIT_HEAD(c, "{\n"); + } + code + { + gen_inst_code(c, &@1); + } + | error /* Recover gracefully after instruction compilation er= ror */ + { + free_instruction(c); + } + ; + +arguments : '(' ')' + | '(' argument_list ')'; + +argument_list : argument_decl ',' argument_list + | argument_decl + ; + +var : VAR + { + track_string(c, $1.var.name); + $$ =3D $1; + } + ; + +/* + * Here the integer types are defined from valid combinations of + * `signed`, `unsigned`, `int`, and `long` tokens. The `signed` + * and `unsigned` tokens are here assumed to always be placed + * first in the type declaration, which is not the case in + * normal C. Similarly, `int` is assumed to always be placed + * last in the type. + */ +type_int : TYPE_INT + | TYPE_SIGNED + | TYPE_SIGNED TYPE_INT; +type_uint : TYPE_UNSIGNED + | TYPE_UNSIGNED TYPE_INT; +type_ulonglong : TYPE_UNSIGNED TYPE_LONG TYPE_LONG + | TYPE_UNSIGNED TYPE_LONG TYPE_LONG TYPE_INT; + +/* + * Here the various valid int types defined above specify + * their `signedness` and `bit_width`. The LP64 convention + * is assumed where longs are 64-bit, long longs are then + * assumed to also be 64-bit. + */ +var_type : TYPE_SIZE_T + { + yyassert(c, &@1, $1.bit_width <=3D 64, + "Variables with size > 64-bit are not supported!"); + $$ =3D $1; + } + | type_int + { + $$.signedness =3D SIGNED; + $$.bit_width =3D 32; + } + | type_uint + { + $$.signedness =3D UNSIGNED; + $$.bit_width =3D 32; + } + | type_ulonglong + { + $$.signedness =3D UNSIGNED; + $$.bit_width =3D 64; + } + ; + +/* Rule to capture declarations of VARs */ +var_decl : var_type IMM + { + /* + * Rule to capture "int i;" declarations since "i" is special + * and assumed to be always be IMM. Moreover, "i" is only + * assumed to be used in for-loops. + * + * Therefore we want to NOP these declarations. + */ + yyassert(c, &@2, $2.imm.type =3D=3D I, + "Variable declaration with immedaties only allowed" + " for the loop induction variable \"i\""); + $$ =3D $2; + } + | var_type var + { + /* + * Allocate new variable, this checks that it hasn't already + * been declared. + */ + gen_varid_allocate(c, &@1, &$2, $1.bit_width, $1.signedness); + /* Copy var for variable name */ + $$ =3D $2; + /* Copy type info from var_type */ + $$.signedness =3D $1.signedness; + $$.bit_width =3D $1.bit_width; + } + ; + +/* Return the modified registers list */ +code : '{' statements '}' + { + c->inst.code_begin =3D c->input_buffer + @2.first_column - 1; + c->inst.code_end =3D c->input_buffer + @2.last_column - 1; + } + | '{' + { + /* Nop */ + } + '}' + ; + +argument_decl : REG + { + emit_arg(c, &@1, &$1); + /* Enqueue register into initialization list */ + g_array_append_val(c->inst.init_list, $1); + } + | PRED + { + emit_arg(c, &@1, &$1); + /* Enqueue predicate into initialization list */ + g_array_append_val(c->inst.init_list, $1); + } + | IN REG + { + emit_arg(c, &@2, &$2); + } + | IN PRED + { + emit_arg(c, &@2, &$2); + } + | IMM + { + EMIT_SIG(c, ", int %ciV", $1.imm.id); + } + ; + +code_block : '{' statements '}' + | '{' '}' + ; + +/* A list of one or more statements */ +statements : statements statement + | statement + ; + +/* Statements can be assignment (rvalue ';'), control or memory statements= */ +statement : control_statement + | var_decl ';' + | rvalue ';' + { + gen_rvalue_free(c, &@1, &$1); + } + | code_block + | ';' + ; + +assign_statement : lvalue '=3D' rvalue + { + @1.last_column =3D @3.last_column; + gen_assign(c, &@1, &$1, &$3); + $$ =3D $1; + } + | var_decl '=3D' rvalue + { + @1.last_column =3D @3.last_column; + gen_assign(c, &@1, &$1, &$3); + $$ =3D $1; + } + | lvalue INC rvalue + { + @1.last_column =3D @3.last_column; + HexValue tmp =3D gen_bin_op(c, &@1, ADD_OP, &$1, &$= 3); + gen_assign(c, &@1, &$1, &tmp); + $$ =3D $1; + } + | lvalue DEC rvalue + { + @1.last_column =3D @3.last_column; + HexValue tmp =3D gen_bin_op(c, &@1, SUB_OP, &$1, &$= 3); + gen_assign(c, &@1, &$1, &tmp); + $$ =3D $1; + } + | lvalue ANDA rvalue + { + @1.last_column =3D @3.last_column; + HexValue tmp =3D gen_bin_op(c, &@1, ANDB_OP, &$1, &= $3); + gen_assign(c, &@1, &$1, &tmp); + $$ =3D $1; + } + | lvalue ORA rvalue + { + @1.last_column =3D @3.last_column; + HexValue tmp =3D gen_bin_op(c, &@1, ORB_OP, &$1, &$= 3); + gen_assign(c, &@1, &$1, &tmp); + $$ =3D $1; + } + | lvalue XORA rvalue + { + @1.last_column =3D @3.last_column; + HexValue tmp =3D gen_bin_op(c, &@1, XORB_OP, &$1, &= $3); + gen_assign(c, &@1, &$1, &tmp); + $$ =3D $1; + } + | PRED '=3D' rvalue + { + @1.last_column =3D @3.last_column; + gen_pred_assign(c, &@1, &$1, &$3); + } + | IMM '=3D' rvalue + { + @1.last_column =3D @3.last_column; + yyassert(c, &@1, $3.type =3D=3D IMMEDIATE, + "Cannot assign non-immediate to immediate!= "); + yyassert(c, &@1, $1.imm.type =3D=3D VARIABLE, + "Cannot assign to non-variable!"); + /* Assign to the function argument */ + OUT(c, &@1, &$1, " =3D ", &$3, ";\n"); + $$ =3D $1; + } + | PC '=3D' rvalue + { + @1.last_column =3D @3.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + $3 =3D gen_rvalue_truncate(c, &@1, &$3); + $3 =3D rvalue_materialize(c, &@1, &$3); + OUT(c, &@1, "gen_write_new_pc(", &$3, ");\n"); + gen_rvalue_free(c, &@1, &$3); /* Free temporary val= ue */ + } + | LOAD '(' IMM ',' IMM ',' SIGN ',' var ',' lvalue ')' + { + @1.last_column =3D @12.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + yyassert(c, &@1, $3.imm.value =3D=3D 1, + "LOAD of arrays not supported!"); + gen_load(c, &@1, &$5, $7, &$9, &$11); + } + | STORE '(' IMM ',' IMM ',' var ',' rvalue ')' + /* Store primitive */ + { + @1.last_column =3D @10.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + yyassert(c, &@1, $3.imm.value =3D=3D 1, + "STORE of arrays not supported!"); + gen_store(c, &@1, &$5, &$7, &$9); + } + | LPCFG '=3D' rvalue + { + @1.last_column =3D @3.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + $3 =3D gen_rvalue_truncate(c, &@1, &$3); + $3 =3D rvalue_materialize(c, &@1, &$3); + OUT(c, &@1, "SET_USR_FIELD(USR_LPCFG, ", &$3, ");\n= "); + gen_rvalue_free(c, &@1, &$3); + } + | DEPOSIT '(' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + gen_deposit_op(c, &@1, &$5, &$7, &$3, &$1); + } + | SETHALF '(' rvalue ',' lvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + gen_sethalf(c, &@1, &$1, &$3, &$5, &$7); + } + | SETBITS '(' rvalue ',' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @10.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + gen_setbits(c, &@1, &$3, &$5, &$7, &$9); + } + | INSBITS '(' lvalue ',' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @10.last_column; + yyassert(c, &@1, !is_inside_ternary(c), + "Assignment side-effect not modeled!"); + gen_rdeposit_op(c, &@1, &$3, &$9, &$7, &$5); + } + | IDENTITY '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + $$ =3D $3; + } + ; + +control_statement : frame_check + | cancel_statement + | if_statement + | for_statement + | fpart1_statement + ; + +frame_check : FCHK '(' rvalue ',' rvalue ')' ';' + { + gen_rvalue_free(c, &@1, &$3); + gen_rvalue_free(c, &@1, &$5); + } + ; + +cancel_statement : LOAD_CANCEL + { + gen_load_cancel(c, &@1); + } + | CANCEL + { + gen_cancel(c, &@1); + } + ; + +if_statement : if_stmt + { + /* Fix else label */ + OUT(c, &@1, "gen_set_label(if_label_", &$1, ");\n"); + } + | if_stmt ELSE + { + @1.last_column =3D @2.last_column; + $2 =3D gen_if_else(c, &@1, $1); + } + statement + { + OUT(c, &@1, "gen_set_label(if_label_", &$2, ");\n"); + } + ; + +for_statement : FOR '(' IMM '=3D' IMM ';' IMM '<' IMM ';' IMM PLUSPLUS ')' + { + yyassert(c, &@3, + $3.imm.type =3D=3D I && + $7.imm.type =3D=3D I && + $11.imm.type =3D=3D I, + "Loop induction variable must be \"i\""); + @1.last_column =3D @13.last_column; + OUT(c, &@1, "for (int ", &$3, " =3D ", &$5, "; ", + &$7, " < ", &$9); + OUT(c, &@1, "; ", &$11, "++) {\n"); + } + code_block + { + OUT(c, &@1, "}\n"); + } + ; + +fpart1_statement : PART1 + { + OUT(c, &@1, "if (insn->part1) {\n"); + } + '(' statements ')' + { + @1.last_column =3D @3.last_column; + OUT(c, &@1, "return; }\n"); + } + ; + +if_stmt : IF '(' rvalue ')' + { + @1.last_column =3D @3.last_column; + $1 =3D gen_if_cond(c, &@1, &$3); + } + statement + { + $$ =3D $1; + } + ; + +rvalue : FAIL + { + yyassert(c, &@1, false, "Encountered a FAIL token as rvalue.\= n"); + } + | assign_statement + | REG + { + $$ =3D $1; + } + | IMM + { + $$ =3D $1; + } + | PRED + { + $$ =3D gen_rvalue_pred(c, &@1, &$1); + } + | PC + { + /* Read PC from the CR */ + HexValue rvalue; + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D IMMEDIATE; + rvalue.imm.type =3D IMM_PC; + rvalue.bit_width =3D 32; + rvalue.signedness =3D UNSIGNED; + $$ =3D rvalue; + } + | NPC + { + /* + * NPC is only read from CALLs, so we can hardcode it + * at translation time + */ + HexValue rvalue; + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D IMMEDIATE; + rvalue.imm.type =3D IMM_NPC; + rvalue.bit_width =3D 32; + rvalue.signedness =3D UNSIGNED; + $$ =3D rvalue; + } + | CONSTEXT + { + HexValue rvalue; + memset(&rvalue, 0, sizeof(HexValue)); + rvalue.type =3D IMMEDIATE; + rvalue.imm.type =3D IMM_CONSTEXT; + rvalue.signedness =3D UNSIGNED; + rvalue.is_dotnew =3D false; + rvalue.is_manual =3D false; + $$ =3D rvalue; + } + | var + { + $$ =3D gen_rvalue_var(c, &@1, &$1); + } + | MPY '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_rvalue_mpy(c, &@1, &$1, &$3, &$5); + } + | rvalue '+' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, ADD_OP, &$1, &$3); + } + | rvalue '-' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, SUB_OP, &$1, &$3); + } + | rvalue '*' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, MUL_OP, &$1, &$3); + } + | rvalue ASL rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, ASL_OP, &$1, &$3); + } + | rvalue ASR rvalue + { + @1.last_column =3D @3.last_column; + assert_signedness(c, &@1, $1.signedness); + if ($1.signedness =3D=3D UNSIGNED) { + $$ =3D gen_bin_op(c, &@1, LSR_OP, &$1, &$3); + } else if ($1.signedness =3D=3D SIGNED) { + $$ =3D gen_bin_op(c, &@1, ASR_OP, &$1, &$3); + } + } + | rvalue LSR rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, LSR_OP, &$1, &$3); + } + | rvalue '&' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, ANDB_OP, &$1, &$3); + } + | rvalue '|' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, ORB_OP, &$1, &$3); + } + | rvalue '^' rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, XORB_OP, &$1, &$3); + } + | rvalue ANDL rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, ANDL_OP, &$1, &$3); + } + | MIN '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, MINI_OP, &$3, &$5); + } + | MAX '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_op(c, &@1, MAXI_OP, &$3, &$5); + } + | '~' rvalue + { + @1.last_column =3D @2.last_column; + $$ =3D gen_rvalue_not(c, &@1, &$2); + } + | '!' rvalue + { + @1.last_column =3D @2.last_column; + $$ =3D gen_rvalue_notl(c, &@1, &$2); + } + | SAT '(' IMM ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_rvalue_sat(c, &@1, &$1, &$3, &$5); + } + | CAST rvalue + { + @1.last_column =3D @2.last_column; + /* Assign target signedness */ + $2.signedness =3D $1.signedness; + $$ =3D gen_cast_op(c, &@1, &$2, $1.bit_width, $1.signedness); + } + | rvalue EQ rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_EQ, &$1, &$3); + } + | rvalue NEQ rvalue + { + @1.last_column =3D @3.last_column; + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_NE, &$1, &$3); + } + | rvalue '<' rvalue + { + @1.last_column =3D @3.last_column; + + assert_signedness(c, &@1, $1.signedness); + assert_signedness(c, &@1, $3.signedness); + if ($1.signedness =3D=3D UNSIGNED || $3.signedness =3D=3D UNS= IGNED) { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_LTU, &$1, &$3); + } else { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_LT, &$1, &$3); + } + } + | rvalue '>' rvalue + { + @1.last_column =3D @3.last_column; + + assert_signedness(c, &@1, $1.signedness); + assert_signedness(c, &@1, $3.signedness); + if ($1.signedness =3D=3D UNSIGNED || $3.signedness =3D=3D UNS= IGNED) { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_GTU, &$1, &$3); + } else { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_GT, &$1, &$3); + } + } + | rvalue LTE rvalue + { + @1.last_column =3D @3.last_column; + + assert_signedness(c, &@1, $1.signedness); + assert_signedness(c, &@1, $3.signedness); + if ($1.signedness =3D=3D UNSIGNED || $3.signedness =3D=3D UNS= IGNED) { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_LEU, &$1, &$3); + } else { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_LE, &$1, &$3); + } + } + | rvalue GTE rvalue + { + @1.last_column =3D @3.last_column; + + assert_signedness(c, &@1, $1.signedness); + assert_signedness(c, &@1, $3.signedness); + if ($1.signedness =3D=3D UNSIGNED || $3.signedness =3D=3D UNS= IGNED) { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_GEU, &$1, &$3); + } else { + $$ =3D gen_bin_cmp(c, &@1, TCG_COND_GE, &$1, &$3); + } + } + | rvalue '?' + { + $1.is_manual =3D true; + Ternary t =3D { 0 }; + t.state =3D IN_LEFT; + t.cond =3D $1; + g_array_append_val(c->ternary, t); + } + rvalue ':' + { + Ternary *t =3D &g_array_index(c->ternary, Ternary, + c->ternary->len - 1); + t->state =3D IN_RIGHT; + } + rvalue + { + @1.last_column =3D @5.last_column; + $$ =3D gen_rvalue_ternary(c, &@1, &$1, &$4, &$7); + } + | FSCR '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + $$ =3D gen_rvalue_fscr(c, &@1, &$3); + } + | SXT '(' rvalue ',' IMM ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + yyassert(c, &@1, $5.type =3D=3D IMMEDIATE && + $5.imm.type =3D=3D VALUE, + "SXT expects immediate values\n"); + $$ =3D gen_extend_op(c, &@1, &$3, $5.imm.value, &$7, SIGNED); + } + | ZXT '(' rvalue ',' IMM ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + yyassert(c, &@1, $5.type =3D=3D IMMEDIATE && + $5.imm.type =3D=3D VALUE, + "ZXT expects immediate values\n"); + $$ =3D gen_extend_op(c, &@1, &$3, $5.imm.value, &$7, UNSIGNED= ); + } + | '(' rvalue ')' + { + $$ =3D $2; + } + | ABS rvalue + { + @1.last_column =3D @2.last_column; + $$ =3D gen_rvalue_abs(c, &@1, &$2); + } + | CROUND '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_convround_n(c, &@1, &$3, &$5); + } + | CROUND '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + $$ =3D gen_convround(c, &@1, &$3); + } + | ROUND '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_round(c, &@1, &$3, &$5); + } + | '-' rvalue + { + @1.last_column =3D @2.last_column; + $$ =3D gen_rvalue_neg(c, &@1, &$2); + } + | ICIRC '(' rvalue ')' ASL IMM + { + @1.last_column =3D @6.last_column; + $$ =3D gen_tmp(c, &@1, 32, UNSIGNED); + OUT(c, &@1, "gen_read_ireg(", &$$, ", ", &$3, ", ", &$6, ");\= n"); + gen_rvalue_free(c, &@1, &$3); + } + | CIRCADD '(' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + gen_circ_op(c, &@1, &$3, &$5, &$7); + } + | LOCNT '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + /* Leading ones count */ + $$ =3D gen_locnt_op(c, &@1, &$3); + } + | COUNTONES '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + /* Ones count */ + $$ =3D gen_ctpop_op(c, &@1, &$3); + } + | LPCFG + { + $$ =3D gen_tmp_value(c, &@1, "0", 32, UNSIGNED); + OUT(c, &@1, "GET_USR_FIELD(USR_LPCFG, ", &$$, ");\n"); + } + | EXTRACT '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_extract_op(c, &@1, &$5, &$3, &$1); + } + | EXTRANGE '(' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + yyassert(c, &@1, $5.type =3D=3D IMMEDIATE && + $5.imm.type =3D=3D VALUE && + $7.type =3D=3D IMMEDIATE && + $7.imm.type =3D=3D VALUE, + "Range extract needs immediate values!\n"); + $$ =3D gen_rextract_op(c, + &@1, + &$3, + $7.imm.value, + $5.imm.value - $7.imm.value + 1); + } + | CAST4_8U '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + $$ =3D gen_rvalue_truncate(c, &@1, &$3); + $$.signedness =3D UNSIGNED; + $$ =3D rvalue_materialize(c, &@1, &$$); + $$ =3D gen_rvalue_extend(c, &@1, &$$); + } + | BREV '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + $$ =3D gen_rvalue_brev(c, &@1, &$3); + } + | ROTL '(' rvalue ',' rvalue ')' + { + @1.last_column =3D @6.last_column; + $$ =3D gen_rotl(c, &@1, &$3, &$5); + } + | ADDSAT64 '(' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + gen_addsat64(c, &@1, &$3, &$5, &$7); + } + | CARRY_FROM_ADD '(' rvalue ',' rvalue ',' rvalue ')' + { + @1.last_column =3D @8.last_column; + $$ =3D gen_carry_from_add(c, &@1, &$3, &$5, &$7); + } + | LSBNEW '(' rvalue ')' + { + @1.last_column =3D @4.last_column; + HexValue one =3D gen_imm_value(c, &@1, 1, 32, UNSIGNED); + $$ =3D gen_bin_op(c, &@1, ANDB_OP, &$3, &one); + } + ; + +lvalue : FAIL + { + @1.last_column =3D @1.last_column; + yyassert(c, &@1, false, "Encountered a FAIL token as lvalue.\= n"); + } + | REG + { + $$ =3D $1; + } + | var + { + $$ =3D $1; + } + ; + +%% + +int main(int argc, char **argv) +{ + if (argc !=3D 5) { + fprintf(stderr, + "Semantics: Hexagon ISA to tinycode generator compiler\n\n= "); + fprintf(stderr, + "Usage: ./semantics IDEFS EMITTER_C EMITTER_H " + "ENABLED_INSTRUCTIONS_LIST\n"); + return 1; + } + + enum { + ARG_INDEX_ARGV0 =3D 0, + ARG_INDEX_IDEFS, + ARG_INDEX_EMITTER_C, + ARG_INDEX_EMITTER_H, + ARG_INDEX_ENABLED_INSTRUCTIONS_LIST + }; + + FILE *enabled_file =3D fopen(argv[ARG_INDEX_ENABLED_INSTRUCTIONS_LIST]= , "w"); + + FILE *output_file =3D fopen(argv[ARG_INDEX_EMITTER_C], "w"); + fputs("#include \"qemu/osdep.h\"\n", output_file); + fputs("#include \"qemu/log.h\"\n", output_file); + fputs("#include \"cpu.h\"\n", output_file); + fputs("#include \"internal.h\"\n", output_file); + fputs("#include \"tcg/tcg-op.h\"\n", output_file); + fputs("#include \"insn.h\"\n", output_file); + fputs("#include \"opcodes.h\"\n", output_file); + fputs("#include \"translate.h\"\n", output_file); + fputs("#define QEMU_GENERATE\n", output_file); + fputs("#include \"genptr.h\"\n", output_file); + fputs("#include \"tcg/tcg.h\"\n", output_file); + fputs("#include \"macros.h\"\n", output_file); + fprintf(output_file, "#include \"%s\"\n", argv[ARG_INDEX_EMITTER_H]); + + FILE *defines_file =3D fopen(argv[ARG_INDEX_EMITTER_H], "w"); + assert(defines_file !=3D NULL); + fputs("#ifndef HEX_EMITTER_H\n", defines_file); + fputs("#define HEX_EMITTER_H\n", defines_file); + fputs("\n", defines_file); + fputs("#include \"insn.h\"\n\n", defines_file); + + /* Parser input file */ + Context context =3D { 0 }; + context.defines_file =3D defines_file; + context.output_file =3D output_file; + context.enabled_file =3D enabled_file; + /* Initialize buffers */ + context.out_str =3D g_string_new(NULL); + context.signature_str =3D g_string_new(NULL); + context.header_str =3D g_string_new(NULL); + context.ternary =3D g_array_new(FALSE, TRUE, sizeof(Ternary)); + /* Read input file */ + FILE *input_file =3D fopen(argv[ARG_INDEX_IDEFS], "r"); + fseek(input_file, 0L, SEEK_END); + long input_size =3D ftell(input_file); + context.input_buffer =3D (char *) calloc(input_size + 1, sizeof(char)); + fseek(input_file, 0L, SEEK_SET); + size_t read_chars =3D fread(context.input_buffer, + sizeof(char), + input_size, + input_file); + if (read_chars !=3D (size_t) input_size) { + fprintf(stderr, "Error: an error occurred while reading input file= !\n"); + return -1; + } + yylex_init(&context.scanner); + YY_BUFFER_STATE buffer; + buffer =3D yy_scan_string(context.input_buffer, context.scanner); + /* Start the parsing procedure */ + yyparse(context.scanner, &context); + if (context.implemented_insn !=3D context.total_insn) { + fprintf(stderr, + "Warning: %d/%d meta instructions have been implemented!\n= ", + context.implemented_insn, + context.total_insn); + } + fputs("#endif " START_COMMENT " HEX_EMITTER_h " END_COMMENT "\n", + defines_file); + /* Cleanup */ + yy_delete_buffer(buffer, context.scanner); + yylex_destroy(context.scanner); + free(context.input_buffer); + g_string_free(context.out_str, TRUE); + g_string_free(context.signature_str, TRUE); + g_string_free(context.header_str, TRUE); + g_array_free(context.ternary, TRUE); + fclose(output_file); + fclose(input_file); + fclose(defines_file); + fclose(enabled_file); + + return 0; +} diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index 5af0a6f419..d782041069 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -203,6 +203,35 @@ if idef_parser_enabled and 'hexagon-linux-user' in tar= get_dirs output: ['@BASENAME@.yy.c', '@BASENAME@.yy.h'], arguments: ['-o', '@OUTPUT0@', '--header-file=3D@OUTPUT1@', '@INPU= T@'] ) + + bison =3D generator( + find_program('bison'), + output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'], + arguments: ['@INPUT@', '--defines=3D@OUTPUT1@', '--output=3D@OUTPU= T0@'] + ) + + glib_dep =3D dependency('glib-2.0', native: true) + + idef_parser =3D executable( + 'idef-parser', + [flex.process(idef_parser_dir / 'idef-parser.lex'), + bison.process(idef_parser_dir / 'idef-parser.y'), + idef_parser_dir / 'parser-helpers.c'], + include_directories: ['idef-parser', '../../include/'], + dependencies: [glib_dep], + c_args: ['-Wextra'], + native: true + ) + + idef_generated_tcg =3D custom_target( + 'idef-generated-tcg', + output: ['idef-generated-emitter.c', + 'idef-generated-emitter.h.inc', + 'idef-generated-enabled-instructions'], + input: preprocessed_idef_parser_input_generated, + depend_files: [hex_common_py], + command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTP= UT2@'] + ) endif =20 target_arch +=3D {'hexagon': hexagon_ss} --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224679; cv=none; d=zohomail.com; s=zohoarc; b=CaE78wWBMj9KewocJWOazMSFE2H1Fd3ExQgsdygnQr0vBlICInpxj84yMb0d542aHg6DpWV7g7ru5uKsNVNeWdsj7Wzm+IE7QeyJ51S7i2EtB27CG3NDrJTvFEjnYlGa9e9vnP05ML9qcpjjoDjH83eNEEQw7Cgf3t2YQuUxNCI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224679; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=CUc2XnPfxIIG0ZC9uoVhUAJOuXBJYOtMX3XP91fryio=; b=PS45hyev4qZUVhjIY1b/3ufy5+zLXaq/YING1x6FicBfpALBnkrtN36DoWJzP01JD61Y/EDWoz2HSrKhkR7ejDpsumaCePckiN1tNFdV+212FqFgXQYAPx3PjcfcMRtASl5CdTrAx2/fEb2d/m2DcSfE9BYU2b649M4+Urm4fjc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224679255194.42640577950385; Fri, 16 Dec 2022 13:04:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6HeD-0002s4-N7; Fri, 16 Dec 2022 15:49:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He7-0002pX-Cq for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:31 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004PK-Bq for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:31 -0500 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGKJeeV018666; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg06rws5d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA03.qualcomm.com [127.0.0.1]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKbSlQ019793; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 3mgw6trnfc-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA03.qualcomm.com (NALASPPMTA03.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKjjqp028035; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA03.qualcomm.com (PPS) with ESMTP id 2BGKnDu7000424; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 18D34500121; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=CUc2XnPfxIIG0ZC9uoVhUAJOuXBJYOtMX3XP91fryio=; b=Z5aV7ZVQmK7bNkHxmMNH0LbWZwqx03L5HmVGrQd0ljyAh6zQ+j6+x9Z8w2r0MD8DKQPB hXKq+PehYabHjy3uRRzUathSBGKAD3tND0erXyTUN9CNCgcp2qiRxUNevE0a6q+OWXoy WxJvH2xk4dnriFTJuTPVXcarE/qsz7p8pjPxqu0GWDYya2F0tB0Y30slkVRIlr9fg7ID PTLjTjMjvkuyvCSMoEiOZ6MqGlS3G5oDdfe7EHv7xZ50Qi0aT34EvduqKOBkxpqttVRP egYPz0LrA9jVR/77U4ov9zCAaL1LiiVwuyxHE1OZG/1/xrNhfTjpUQc/2nkRAyjhGd0a Aw== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, Alessandro Di Federico , Anton Johansson Subject: [PULL 20/21] target/hexagon: call idef-parser functions Date: Fri, 16 Dec 2022 12:48:44 -0800 Message-Id: <20221216204845.19290-21-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: hckTUzyisVdLv6ytW-zKE19ukyjgiosL X-Proofpoint-ORIG-GUID: hckTUzyisVdLv6ytW-zKE19ukyjgiosL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 spamscore=0 mlxlogscore=819 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 suspectscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224681288100003 From: Alessandro Di Federico Extend gen_tcg_funcs.py in order to emit calls to the functions emitted by the idef-parser, if available. Signed-off-by: Alessandro Di Federico Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-11-anjo@rev.ng> --- target/hexagon/gen_helper_funcs.py | 17 ++++- target/hexagon/gen_helper_protos.py | 17 ++++- target/hexagon/gen_tcg_funcs.py | 41 ++++++++++- target/hexagon/hex_common.py | 10 +++ target/hexagon/meson.build | 103 ++++++++++++++++++++-------- 5 files changed, 154 insertions(+), 34 deletions(-) diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper= _funcs.py index 00ee58f159..19e9883f4c 100755 --- a/target/hexagon/gen_helper_funcs.py +++ b/target/hexagon/gen_helper_funcs.py @@ -298,11 +298,24 @@ def main(): hex_common.read_attribs_file(sys.argv[2]) hex_common.read_overrides_file(sys.argv[3]) hex_common.read_overrides_file(sys.argv[4]) + ## Whether or not idef-parser is enabled is + ## determined by the number of arguments to + ## this script: + ## + ## 5 args. -> not enabled, + ## 6 args. -> idef-parser enabled. + ## + ## The 6:th arg. then holds a list of the successfully + ## parsed instructions. + is_idef_parser_enabled =3D len(sys.argv) > 6 + if is_idef_parser_enabled: + hex_common.read_idef_parser_enabled_file(sys.argv[5]) hex_common.calculate_attribs() tagregs =3D hex_common.get_tagregs() tagimms =3D hex_common.get_tagimms() =20 - with open(sys.argv[5], 'w') as f: + output_file =3D sys.argv[-1] + with open(output_file, 'w') as f: for tag in hex_common.tags: ## Skip the priv instructions if ( "A_PRIV" in hex_common.attribdict[tag] ) : @@ -319,6 +332,8 @@ def main(): continue if ( hex_common.skip_qemu_helper(tag) ): continue + if ( hex_common.is_idef_parser_enabled(tag) ): + continue =20 gen_helper_function(f, tag, tagregs, tagimms) =20 diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helpe= r_protos.py index ed4b9cf0d4..674bf370fa 100755 --- a/target/hexagon/gen_helper_protos.py +++ b/target/hexagon/gen_helper_protos.py @@ -146,11 +146,24 @@ def main(): hex_common.read_attribs_file(sys.argv[2]) hex_common.read_overrides_file(sys.argv[3]) hex_common.read_overrides_file(sys.argv[4]) + ## Whether or not idef-parser is enabled is + ## determined by the number of arguments to + ## this script: + ## + ## 5 args. -> not enabled, + ## 6 args. -> idef-parser enabled. + ## + ## The 6:th arg. then holds a list of the successfully + ## parsed instructions. + is_idef_parser_enabled =3D len(sys.argv) > 6 + if is_idef_parser_enabled: + hex_common.read_idef_parser_enabled_file(sys.argv[5]) hex_common.calculate_attribs() tagregs =3D hex_common.get_tagregs() tagimms =3D hex_common.get_tagimms() =20 - with open(sys.argv[5], 'w') as f: + output_file =3D sys.argv[-1] + with open(output_file, 'w') as f: for tag in hex_common.tags: ## Skip the priv instructions if ( "A_PRIV" in hex_common.attribdict[tag] ) : @@ -168,6 +181,8 @@ def main(): =20 if ( hex_common.skip_qemu_helper(tag) ): continue + if ( hex_common.is_idef_parser_enabled(tag) ): + continue =20 gen_helper_prototype(f, tag, tagregs, tagimms) =20 diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs= .py index f4cea6dfc4..7e8ba17ca2 100755 --- a/target/hexagon/gen_tcg_funcs.py +++ b/target/hexagon/gen_tcg_funcs.py @@ -616,7 +616,29 @@ def gen_tcg_func(f, tag, regs, imms): if (hex_common.is_read(regid)): genptr_src_read_opn(f,regtype,regid,tag) =20 - if ( hex_common.skip_qemu_helper(tag) ): + if hex_common.is_idef_parser_enabled(tag): + declared =3D [] + ## Handle registers + for regtype,regid,toss,numregs in regs: + if (hex_common.is_pair(regid) + or (hex_common.is_single(regid) + and hex_common.is_old_val(regtype, regid, tag))): + declared.append("%s%sV" % (regtype, regid)) + if regtype =3D=3D "M": + declared.append("%s%sN" % (regtype, regid)) + elif hex_common.is_new_val(regtype, regid, tag): + declared.append("%s%sN" % (regtype,regid)) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + + ## Handle immediates + for immlett,bits,immshift in imms: + declared.append(hex_common.imm_name(immlett)) + + arguments =3D ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declare= d) + f.write(" emit_%s(%s);\n" % (tag, arguments)) + + elif ( hex_common.skip_qemu_helper(tag) ): f.write(" fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag])) else: ## Generate the call to the helper @@ -694,12 +716,27 @@ def main(): hex_common.read_overrides_file(sys.argv[3]) hex_common.read_overrides_file(sys.argv[4]) hex_common.calculate_attribs() + ## Whether or not idef-parser is enabled is + ## determined by the number of arguments to + ## this script: + ## + ## 5 args. -> not enabled, + ## 6 args. -> idef-parser enabled. + ## + ## The 6:th arg. then holds a list of the successfully + ## parsed instructions. + is_idef_parser_enabled =3D len(sys.argv) > 6 + if is_idef_parser_enabled: + hex_common.read_idef_parser_enabled_file(sys.argv[5]) tagregs =3D hex_common.get_tagregs() tagimms =3D hex_common.get_tagimms() =20 - with open(sys.argv[5], 'w') as f: + output_file =3D sys.argv[-1] + with open(output_file, 'w') as f: f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") f.write("#define HEXAGON_TCG_FUNCS_H\n\n") + if is_idef_parser_enabled: + f.write("#include \"idef-generated-emitter.h.inc\"\n\n") =20 for tag in hex_common.tags: ## Skip the priv instructions diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index 8e631b444f..a29f61bb4f 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -28,6 +28,7 @@ attribinfo =3D {} # Register information and misc tags =3D [] # list of all tags overrides =3D {} # tags with helper overrides +idef_parser_enabled =3D {} # tags enabled for idef-parser =20 # We should do this as a hash for performance, # but to keep order let's keep it as a list. @@ -245,6 +246,9 @@ def is_tmp_result(tag): def is_new_result(tag): return ('A_CVI_NEW' in attribdict[tag]) =20 +def is_idef_parser_enabled(tag): + return tag in idef_parser_enabled + def imm_name(immlett): return "%siV" % immlett =20 @@ -276,3 +280,9 @@ def read_overrides_file(name): continue tag =3D overridere.findall(line)[0] overrides[tag] =3D True + +def read_idef_parser_enabled_file(name): + global idef_parser_enabled + with open(name, "r") as idef_parser_enabled_file: + lines =3D idef_parser_enabled_file.read().strip().split("\n") + idef_parser_enabled =3D set(lines) diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index d782041069..e8f250fcac 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -43,10 +43,7 @@ hexagon_ss.add(semantics_generated) # Step 2 # We use Python scripts to generate the following files # shortcode_generated.h.inc -# helper_protos_generated.h.inc -# tcg_funcs_generated.c.inc # tcg_func_table_generated.c.inc -# helper_funcs_generated.c.inc # printinsn_generated.h.inc # op_regs_generated.h.inc # op_attribs_generated.h.inc @@ -61,24 +58,6 @@ shortcode_generated =3D custom_target( ) hexagon_ss.add(shortcode_generated) =20 -helper_protos_generated =3D custom_target( - 'helper_protos_generated.h.inc', - output: 'helper_protos_generated.h.inc', - depends: [semantics_generated], - depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], - command: [python, files('gen_helper_protos.py'), semantics_generated, = attribs_def, gen_tcg_h, gen_tcg_hvx_h, '@OUTPUT@'], -) -hexagon_ss.add(helper_protos_generated) - -tcg_funcs_generated =3D custom_target( - 'tcg_funcs_generated.c.inc', - output: 'tcg_funcs_generated.c.inc', - depends: [semantics_generated], - depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], - command: [python, files('gen_tcg_funcs.py'), semantics_generated, attr= ibs_def, gen_tcg_h, gen_tcg_hvx_h, '@OUTPUT@'], -) -hexagon_ss.add(tcg_funcs_generated) - tcg_func_table_generated =3D custom_target( 'tcg_func_table_generated.c.inc', output: 'tcg_func_table_generated.c.inc', @@ -88,15 +67,6 @@ tcg_func_table_generated =3D custom_target( ) hexagon_ss.add(tcg_func_table_generated) =20 -helper_funcs_generated =3D custom_target( - 'helper_funcs_generated.c.inc', - output: 'helper_funcs_generated.c.inc', - depends: [semantics_generated], - depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], - command: [python, files('gen_helper_funcs.py'), semantics_generated, a= ttribs_def, gen_tcg_h, gen_tcg_hvx_h, '@OUTPUT@'], -) -hexagon_ss.add(helper_funcs_generated) - printinsn_generated =3D custom_target( 'printinsn_generated.h.inc', output: 'printinsn_generated.h.inc', @@ -180,6 +150,14 @@ hexagon_ss.add(files( 'mmvec/system_ext_mmvec.c', )) =20 +# +# Step 4.5 +# We use flex/bison based idef-parser to generate TCG code for a lot +# of instructions. idef-parser outputs +# idef-generated-emitter.c +# idef-generated-emitter.h.inc +# idef-generated-enabled-instructions +# idef_parser_enabled =3D get_option('hexagon_idef_parser') if idef_parser_enabled and 'hexagon-linux-user' in target_dirs idef_parser_input_generated =3D custom_target( @@ -232,6 +210,71 @@ if idef_parser_enabled and 'hexagon-linux-user' in tar= get_dirs depend_files: [hex_common_py], command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTP= UT2@'] ) + + indent =3D find_program('indent', required: false) + if indent.found() + idef_generated_tcg_c =3D custom_target( + 'indent', + input: idef_generated_tcg[0], + output: 'idef-generated-emitter.indented.c', + command: [indent, '-linux', '@INPUT@', '-o', '@OUTPUT@'] + ) + else + idef_generated_tcg_c =3D custom_target( + 'copy', + input: idef_generated_tcg[0], + output: 'idef-generated-emitter.indented.c', + command: ['cp', '@INPUT@', '@OUTPUT@'] + ) + endif + + idef_generated_list =3D idef_generated_tcg[2].full_path() + + hexagon_ss.add(idef_generated_tcg_c) + + # Setup input and dependencies for the next step, this depends on whet= her or + # not idef-parser is enabled + helper_dep =3D [semantics_generated, idef_generated_tcg_c, idef_genera= ted_tcg] + helper_in =3D [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hv= x_h, idef_generated_list] +else + # Setup input and dependencies for the next step, this depends on whet= her or + # not idef-parser is enabled + helper_dep =3D [semantics_generated] + helper_in =3D [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hv= x_h] endif =20 +# +# Step 5 +# We use Python scripts to generate the following files +# helper_protos_generated.h.inc +# helper_funcs_generated.c.inc +# tcg_funcs_generated.c.inc +# +helper_protos_generated =3D custom_target( + 'helper_protos_generated.h.inc', + output: 'helper_protos_generated.h.inc', + depends: helper_dep, + depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], + command: [python, files('gen_helper_protos.py'), helper_in, '@OUTPUT@'= ], +) +hexagon_ss.add(helper_protos_generated) + +helper_funcs_generated =3D custom_target( + 'helper_funcs_generated.c.inc', + output: 'helper_funcs_generated.c.inc', + depends: helper_dep, + depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], + command: [python, files('gen_helper_funcs.py'), helper_in, '@OUTPUT@'], +) +hexagon_ss.add(helper_funcs_generated) + +tcg_funcs_generated =3D custom_target( + 'tcg_funcs_generated.c.inc', + output: 'tcg_funcs_generated.c.inc', + depends: helper_dep, + depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h], + command: [python, files('gen_tcg_funcs.py'), helper_in, '@OUTPUT@'], +) +hexagon_ss.add(tcg_funcs_generated) + target_arch +=3D {'hexagon': hexagon_ss} --=20 2.17.1 From nobody Sun May 19 14:14:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1671224320; cv=none; d=zohomail.com; s=zohoarc; b=b30lxzF5N0GXWwy9+jbXQ5w1wleHpfUwZsZru2B8jKSY/fZHWQJ5qmuiggHTi7AqhkuGeGrBGYoZQXN3+TvJZJatp8toevKu9ZMjoTzD7Pu88VnbsP2C2D86Rfw8jK2n/avwQhldGDixXiYD2E73jYK/TiZAy2WicCwIMfKbOw0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671224320; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=LNQN4gN0GUYqihmIZqTNcV6Z5Hx/fXUW8xCnGw8Ziis=; b=n2Mm29LlwgOIIrr/nT4D6kdeLGS4fDZu6NyHT1KZZisTpOEmQ4d5nUd3P4WJL1N91ylJiA4AGKQSZW/Bdfw9JOmwVvKfU6i59Bv+70y8gqEwfJbjCGxY7L2oA10RiWtqLEgiL0UNDDX86XVKuoXlKbtLEunn/X4lqoY/V9Fg9YY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671224320680239.5499822289811; Fri, 16 Dec 2022 12:58:40 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p6Hen-0003E4-Om; Fri, 16 Dec 2022 15:50:15 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He9-0002qT-C0 for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p6He3-0004Pf-Ln for qemu-devel@nongnu.org; Fri, 16 Dec 2022 15:49:33 -0500 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BGJvWRJ019897; Fri, 16 Dec 2022 20:49:15 GMT Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3mg6y7v5t3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 16 Dec 2022 20:49:15 +0000 Received: from pps.filterd (NALASPPMTA02.qualcomm.com [127.0.0.1]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2BGKgSFb004312; Fri, 16 Dec 2022 20:49:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 3mgard52nm-1; Fri, 16 Dec 2022 20:49:14 +0000 Received: from NALASPPMTA02.qualcomm.com (NALASPPMTA02.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2BGKidXZ006092; Fri, 16 Dec 2022 20:49:14 GMT Received: from hu-devc-lv-u18-c.qualcomm.com (hu-tsimpson-lv.qualcomm.com [10.47.235.220]) by NALASPPMTA02.qualcomm.com (PPS) with ESMTP id 2BGKnDoa012008; Fri, 16 Dec 2022 20:49:14 +0000 Received: by hu-devc-lv-u18-c.qualcomm.com (Postfix, from userid 47164) id 1BCC4500122; Fri, 16 Dec 2022 12:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-type : content-transfer-encoding; s=qcppdkim1; bh=LNQN4gN0GUYqihmIZqTNcV6Z5Hx/fXUW8xCnGw8Ziis=; b=Xvt2weV1lAGSuNS4WAfWnKFkUMenUgr0yz6dsn0eaIFhT/vRPhmPArsk7LO53MPdQVfR OTb2+tr1+2hmzhTf6jtj9g9fmHsG9uoDdxV0ER6ZaL8aDM+SgmZhRK8xx9KjUCc6Q4/U VhGa7TMVNPkuiMG2XPaRKEFPli3wEnTqO3MVXspMR4I08PaEy6eVfpkt44zWrngwegKY hrmUB+aTK6R5+gsLhBZTElNqwPzuCUtbAIA2POdrwKFTo533Ely9fuNOCEfrbjDUFpg8 6iiMENK0U1P2nySsPg1YqNBT7YtH2dnXAQXpz4DkHp/IiiXu+qIzjCMDy3Mtw3wHIzWr tg== From: Taylor Simpson To: qemu-devel@nongnu.org Cc: tsimpson@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com, quic_mathbern@quicinc.com, stefanha@redhat.com, =?UTF-8?q?Niccol=C3=B2=20Izzo?= , Alessandro Di Federico , Anton Johansson Subject: [PULL 21/21] target/hexagon: import additional tests Date: Fri, 16 Dec 2022 12:48:45 -0800 Message-Id: <20221216204845.19290-22-tsimpson@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com> References: <20221216204845.19290-1-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: X0Aj3qh_QACI_Yds8r9UpJpL_j0R-6qK X-Proofpoint-GUID: X0Aj3qh_QACI_Yds8r9UpJpL_j0R-6qK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-16_14,2022-12-15_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=48 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 mlxlogscore=3 clxscore=1015 phishscore=0 suspectscore=0 spamscore=48 priorityscore=1501 mlxscore=48 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2212160185 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=tsimpson@qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 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.25, RCVD_IN_DNSWL_LOW=-0.7, 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @quicinc.com) X-ZM-MESSAGEID: 1671224322955100003 Content-Type: text/plain; charset="utf-8" From: Niccol=C3=B2 Izzo Signed-off-by: Alessandro Di Federico Signed-off-by: Niccol=C3=B2 Izzo Signed-off-by: Anton Johansson Signed-off-by: Taylor Simpson Reviewed-by: Taylor Simpson Message-Id: <20220923173831.227551-12-anjo@rev.ng> --- tests/tcg/hexagon/Makefile.target | 28 ++++++++++++- tests/tcg/hexagon/crt.S | 14 +++++++ tests/tcg/hexagon/test_abs.S | 17 ++++++++ tests/tcg/hexagon/test_bitcnt.S | 40 +++++++++++++++++++ tests/tcg/hexagon/test_bitsplit.S | 22 ++++++++++ tests/tcg/hexagon/test_call.S | 64 ++++++++++++++++++++++++++++++ tests/tcg/hexagon/test_clobber.S | 29 ++++++++++++++ tests/tcg/hexagon/test_cmp.S | 31 +++++++++++++++ tests/tcg/hexagon/test_dotnew.S | 38 ++++++++++++++++++ tests/tcg/hexagon/test_ext.S | 13 ++++++ tests/tcg/hexagon/test_fibonacci.S | 30 ++++++++++++++ tests/tcg/hexagon/test_hl.S | 16 ++++++++ tests/tcg/hexagon/test_hwloops.S | 19 +++++++++ tests/tcg/hexagon/test_jmp.S | 22 ++++++++++ tests/tcg/hexagon/test_lsr.S | 36 +++++++++++++++++ tests/tcg/hexagon/test_mpyi.S | 17 ++++++++ tests/tcg/hexagon/test_packet.S | 29 ++++++++++++++ tests/tcg/hexagon/test_reorder.S | 33 +++++++++++++++ tests/tcg/hexagon/test_round.S | 29 ++++++++++++++ tests/tcg/hexagon/test_vavgw.S | 31 +++++++++++++++ tests/tcg/hexagon/test_vcmpb.S | 30 ++++++++++++++ tests/tcg/hexagon/test_vcmpw.S | 30 ++++++++++++++ tests/tcg/hexagon/test_vlsrw.S | 20 ++++++++++ tests/tcg/hexagon/test_vmaxh.S | 35 ++++++++++++++++ tests/tcg/hexagon/test_vminh.S | 35 ++++++++++++++++ tests/tcg/hexagon/test_vpmpyh.S | 28 +++++++++++++ tests/tcg/hexagon/test_vspliceb.S | 31 +++++++++++++++ 27 files changed, 766 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/hexagon/crt.S create mode 100644 tests/tcg/hexagon/test_abs.S create mode 100644 tests/tcg/hexagon/test_bitcnt.S create mode 100644 tests/tcg/hexagon/test_bitsplit.S create mode 100644 tests/tcg/hexagon/test_call.S create mode 100644 tests/tcg/hexagon/test_clobber.S create mode 100644 tests/tcg/hexagon/test_cmp.S create mode 100644 tests/tcg/hexagon/test_dotnew.S create mode 100644 tests/tcg/hexagon/test_ext.S create mode 100644 tests/tcg/hexagon/test_fibonacci.S create mode 100644 tests/tcg/hexagon/test_hl.S create mode 100644 tests/tcg/hexagon/test_hwloops.S create mode 100644 tests/tcg/hexagon/test_jmp.S create mode 100644 tests/tcg/hexagon/test_lsr.S create mode 100644 tests/tcg/hexagon/test_mpyi.S create mode 100644 tests/tcg/hexagon/test_packet.S create mode 100644 tests/tcg/hexagon/test_reorder.S create mode 100644 tests/tcg/hexagon/test_round.S create mode 100644 tests/tcg/hexagon/test_vavgw.S create mode 100644 tests/tcg/hexagon/test_vcmpb.S create mode 100644 tests/tcg/hexagon/test_vcmpw.S create mode 100644 tests/tcg/hexagon/test_vlsrw.S create mode 100644 tests/tcg/hexagon/test_vmaxh.S create mode 100644 tests/tcg/hexagon/test_vminh.S create mode 100644 tests/tcg/hexagon/test_vpmpyh.S create mode 100644 tests/tcg/hexagon/test_vspliceb.S diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile= .target index 96a4d7a614..9ee1faa1e1 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -24,7 +24,7 @@ CFLAGS +=3D -fno-unroll-loops HEX_SRC=3D$(SRC_PATH)/tests/tcg/hexagon VPATH +=3D $(HEX_SRC) =20 -first: $(HEX_SRC)/first.S +%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S $(CC) -static -mv67 -nostdlib $^ -o $@ =20 HEX_TESTS =3D first @@ -44,6 +44,32 @@ HEX_TESTS +=3D atomics HEX_TESTS +=3D fpstuff HEX_TESTS +=3D overflow =20 +HEX_TESTS +=3D test_abs +HEX_TESTS +=3D test_bitcnt +HEX_TESTS +=3D test_bitsplit +HEX_TESTS +=3D test_call +HEX_TESTS +=3D test_clobber +HEX_TESTS +=3D test_cmp +HEX_TESTS +=3D test_dotnew +HEX_TESTS +=3D test_ext +HEX_TESTS +=3D test_fibonacci +HEX_TESTS +=3D test_hl +HEX_TESTS +=3D test_hwloops +HEX_TESTS +=3D test_jmp +HEX_TESTS +=3D test_lsr +HEX_TESTS +=3D test_mpyi +HEX_TESTS +=3D test_packet +HEX_TESTS +=3D test_reorder +HEX_TESTS +=3D test_round +HEX_TESTS +=3D test_vavgw +HEX_TESTS +=3D test_vcmpb +HEX_TESTS +=3D test_vcmpw +HEX_TESTS +=3D test_vlsrw +HEX_TESTS +=3D test_vmaxh +HEX_TESTS +=3D test_vminh +HEX_TESTS +=3D test_vpmpyh +HEX_TESTS +=3D test_vspliceb + TESTS +=3D $(HEX_TESTS) =20 # This test has to be compiled for the -mv67t target diff --git a/tests/tcg/hexagon/crt.S b/tests/tcg/hexagon/crt.S new file mode 100644 index 0000000000..f9e6bc80f7 --- /dev/null +++ b/tests/tcg/hexagon/crt.S @@ -0,0 +1,14 @@ +#define SYS_exit_group 94 + + .text + .globl pass +pass: + r0 =3D #0 + r6 =3D #SYS_exit_group + trap0(#1) + + .globl fail +fail: + r0 =3D #1 + r6 =3D #SYS_exit_group + trap0(#1) diff --git a/tests/tcg/hexagon/test_abs.S b/tests/tcg/hexagon/test_abs.S new file mode 100644 index 0000000000..d68aea6f64 --- /dev/null +++ b/tests/tcg/hexagon/test_abs.S @@ -0,0 +1,17 @@ +/* Purpose: test example, verify the soundness of the abs operation */ + + .text + .globl _start + +_start: + { + r1 =3D #-2 + r2 =3D #2 + } + { + r3 =3D abs(r1) + } + { + p0 =3D cmp.eq(r3, r2); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_bitcnt.S b/tests/tcg/hexagon/test_bitcn= t.S new file mode 100644 index 0000000000..624460488e --- /dev/null +++ b/tests/tcg/hexagon/test_bitcnt.S @@ -0,0 +1,40 @@ +/* + * Purpose: test example, verify the soundness of the cl[01] operations. + * + * The number 0x000001aa has 23 leading zeroes + * they become 55 when considered as 64 bit register + * and it has 1 trailing zero. + */ + .text + .globl _start + +_start: + { + r0 =3D #426 + r1 =3D #0 + } + { + r2 =3D cl0(r0) + } + { + p0 =3D cmp.eq(r2, #23); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + r2 =3D cl0(r1:0) + } + { + p0 =3D cmp.eq(r2, #55); if (p0.new) jump:t test3 + jump fail + } + +test3: + { + r2 =3D ct0(r0) + } + { + p0 =3D cmp.eq(r2, #1); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_bitsplit.S b/tests/tcg/hexagon/test_bit= split.S new file mode 100644 index 0000000000..275658e613 --- /dev/null +++ b/tests/tcg/hexagon/test_bitsplit.S @@ -0,0 +1,22 @@ +/* Purpose: test example, verify the soundness of the bitsplit operation */ + + .text + .globl _start + +_start: + { + r1 =3D #187 + } + { + r3:2 =3D bitsplit(r1, #3) + } + { + p0 =3D cmp.eq(r2, #3); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r3, #23); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_call.S b/tests/tcg/hexagon/test_call.S new file mode 100644 index 0000000000..338cd04e40 --- /dev/null +++ b/tests/tcg/hexagon/test_call.S @@ -0,0 +1,64 @@ +/* + * Purpose: test function calls and duplex instructions. + * The string "Hello there, I'm a test string!" with the first letter repl= aced + * with a capital L should be printed out. + */ + +#define SYS_write 64 +#define FD_STDOUT 1 + + .text + .globl test +test: + { + jumpr r31 + memb(r0+#0) =3D #76 + } +.Lfunc_end0: +.Ltmp0: + .size test, .Ltmp0-test + + .globl _start +_start: + { + r0 =3D ##dummy_buffer + allocframe(#0) + call test + } + { + call write + } + { + deallocframe + jump pass + } +.Lfunc_end1: +.Ltmp1: + .size _start, .Ltmp1-_start + +write: + { + r6 =3D #SYS_write + r0 =3D #FD_STDOUT + r1 =3D ##dummy_buffer + r2 =3D #33 + } + { + trap0(#1) + } + { + jumpr r31 + } + +.Lfunc_end2: +.Ltmp2: + .size write, .Ltmp2-write + + .type dummy_buffer,@object + .data + .globl dummy_buffer + .p2align 3 +dummy_buffer: + .string "Hello there, I'm a test string!\n" + .space 223 + .size dummy_buffer, 256 diff --git a/tests/tcg/hexagon/test_clobber.S b/tests/tcg/hexagon/test_clob= ber.S new file mode 100644 index 0000000000..a7aeb2b60c --- /dev/null +++ b/tests/tcg/hexagon/test_clobber.S @@ -0,0 +1,29 @@ +/* + * Purpose: demonstrate the succesful operation of the register save mecha= nism, + * in which the caller saves the registers that will be clobbered, and res= tores + * them after the call. + */ + + .text + .globl _start + +_start: + allocframe(#8) + { + r16 =3D #47 + r17 =3D #155 + } + memd(sp+#0) =3D r17:16 + { + r16 =3D #255 + r17 =3D #42 + } + { + deallocframe + r17:16 =3D memd(sp+#0) + } + { + p0 =3D cmp.eq(r16, #47) + p0 =3D cmp.eq(r17, #155); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_cmp.S b/tests/tcg/hexagon/test_cmp.S new file mode 100644 index 0000000000..1db87d3db5 --- /dev/null +++ b/tests/tcg/hexagon/test_cmp.S @@ -0,0 +1,31 @@ +/* Purpose: test a signed and unsigned comparison */ + + .text + .globl _start + +_start: + { + jump signed + } + + .globl signed +signed: + { + r0 =3D #-2 + r1 =3D #0 + } + { + p0 =3D cmp.lt(r0, r1); if (p0.new) jump:t unsigned + jump fail + } + + .globl unsigned +unsigned: + { + r0 =3D #-2 + r1 =3D #0 + } + { + p0 =3D cmp.gtu(r0, r1); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_dotnew.S b/tests/tcg/hexagon/test_dotne= w.S new file mode 100644 index 0000000000..b18b6a72e2 --- /dev/null +++ b/tests/tcg/hexagon/test_dotnew.S @@ -0,0 +1,38 @@ +/* Purpose: test the .new operator while performing memory stores. */ + + .text + .globl _start + +_start: + { + allocframe(#16) + } + { + r0 =3D #1 + memw(sp+#0) =3D r0.new + } + { + r1 =3D #2 + memw(sp+#4) =3D r1.new + } + { + r2 =3D #3 + memw(sp+#8) =3D r2.new + } + { + r0 =3D memw(sp+#8) + } + { + r1 =3D memw(sp+#4) + } + { + r2 =3D memw(sp+#0) + } + { + r3 =3D mpyi(r1, r2) + } + { + deallocframe + p0 =3D cmp.eq(r3, #2); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_ext.S b/tests/tcg/hexagon/test_ext.S new file mode 100644 index 0000000000..03e7bce2a7 --- /dev/null +++ b/tests/tcg/hexagon/test_ext.S @@ -0,0 +1,13 @@ +/* Purpose: test immediate extender instructions. */ + + .text + .globl _start + +_start: + { + r2 =3D ##-559038737 + } + { + p0 =3D cmp.eq(r2, ##-559038737); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_fibonacci.S b/tests/tcg/hexagon/test_fi= bonacci.S new file mode 100644 index 0000000000..4ef2c3896e --- /dev/null +++ b/tests/tcg/hexagon/test_fibonacci.S @@ -0,0 +1,30 @@ +/* Purpose: computes the Fibonacci series up to a constant number. */ + + .text + .globl _start + +_start: + { + r2 =3D #100 + } + { + p0 =3D cmp.gt(r2, #0); if (!p0.new) jump:nt .LBB0_3 + } + { + r3 =3D #0 + r4 =3D #1 + } +.LBB0_2: + { + r5 =3D r4 + } + { + p0 =3D cmp.gt(r2, r5); if (p0.new) jump:nt .LBB0_2 + r4 =3D add(r3, r4) + r3 =3D r5 + } +.LBB0_3: + { + p0 =3D cmp.eq(r3, #144); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_hl.S b/tests/tcg/hexagon/test_hl.S new file mode 100644 index 0000000000..93ace46aeb --- /dev/null +++ b/tests/tcg/hexagon/test_hl.S @@ -0,0 +1,16 @@ +/* Purpose: test example, verify the soundness of the high/low assignment = */ + + .text + .globl _start + +_start: + { + r0.H =3D #42 + } + { + r0.L =3D #69 + } + { + p0 =3D cmp.eq(r0, #2752581); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_hwloops.S b/tests/tcg/hexagon/test_hwlo= ops.S new file mode 100644 index 0000000000..42785e6f25 --- /dev/null +++ b/tests/tcg/hexagon/test_hwloops.S @@ -0,0 +1,19 @@ +/* Purpose: simple C Program to test hardware loops. */ + + .text + .globl _start + +_start: + { + loop0(.LBB0_1, #10) + r2 =3D #0 + } +.LBB0_1: + { + r2 =3D add(r2, #1) + nop + }:endloop0 + { + p0 =3D cmp.eq(r2, #10); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_jmp.S b/tests/tcg/hexagon/test_jmp.S new file mode 100644 index 0000000000..5be25c52b2 --- /dev/null +++ b/tests/tcg/hexagon/test_jmp.S @@ -0,0 +1,22 @@ +/* Purpose: test example, verify the soundness of the jump operation */ + +#define SYS_exit_group 94 + + .text + .globl _start + +_start: + { + jump pass + } + /* + * Inlined fail label in crt.S so we can fail without + * having a functioning jump + */ + { + r0 =3D #1 + r6 =3D #SYS_exit_group + } + { + trap0(#1) + } diff --git a/tests/tcg/hexagon/test_lsr.S b/tests/tcg/hexagon/test_lsr.S new file mode 100644 index 0000000000..b30aa64673 --- /dev/null +++ b/tests/tcg/hexagon/test_lsr.S @@ -0,0 +1,36 @@ +/* Purpose: test the soundness of the lsr operation */ + + .text + .globl _start + +_start: + { + r0 =3D #-56984 + r1 =3D #2147483647 + } + { + r2 =3D #0x19 + } + { + r0 &=3D lsr(r1, r2) + } + { + p0 =3D cmp.eq(r0, #0x28); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + r0 =3D #0x0000000a + r1 =3D #0x00000000 + } + { + r2 =3D #-1 + } + { + r1:0 =3D lsl(r1:0, r2) + } + { + p0 =3D cmp.eq(r0, #0x5); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_mpyi.S b/tests/tcg/hexagon/test_mpyi.S new file mode 100644 index 0000000000..953b46e57e --- /dev/null +++ b/tests/tcg/hexagon/test_mpyi.S @@ -0,0 +1,17 @@ +/* Purpose: test a simple multiplication operation */ + + .text + .globl _start + +_start: + { + r1 =3D #4 + r2 =3D #6 + } + { + r3 =3D mpyi(r1, r2) + } + { + p0 =3D cmp.eq(r3, #24); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_packet.S b/tests/tcg/hexagon/test_packe= t.S new file mode 100644 index 0000000000..9ec9d8d6fb --- /dev/null +++ b/tests/tcg/hexagon/test_packet.S @@ -0,0 +1,29 @@ +/* + * Purpose: test that writes of a register in a packet are performed only = after + * that packet has finished its execution. + */ + + .text + .globl _start + +_start: + { + allocframe(#8) + } + { + r2 =3D #4 + r3 =3D #6 + } + { + memw(sp+#0) =3D r2 + } + { + r3 =3D memw(sp+#0) + r0 =3D add(r2, r3) + } + { + deallocframe + p0 =3D cmp.eq(r3, #4) + p0 =3D cmp.eq(r0, #10); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_reorder.S b/tests/tcg/hexagon/test_reor= der.S new file mode 100644 index 0000000000..5ee0539836 --- /dev/null +++ b/tests/tcg/hexagon/test_reorder.S @@ -0,0 +1,33 @@ +/* + * Purpose: demonstrate handling of .new uses appearing before the associa= ted + * definition. + * Here we perform a jump that skips the code resetting R2 from 0xDEADBEEF= to 0, + * only if P0.new is true, but P0 is assigned to 1 (R4) in the next instru= ction + * in the packet. + */ + + .text + .globl _start + +_start: + { + r2 =3D #-559038737 + } + { + r4 =3D #1 + } + { + if (p0.new) jump:nt skip + p0 =3D r4; + } + +fallthrough: + { + r2 =3D #0 + } + +skip: + { + p0 =3D cmp.eq(r2, #-559038737); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_round.S b/tests/tcg/hexagon/test_round.S new file mode 100644 index 0000000000..3c83812fe8 --- /dev/null +++ b/tests/tcg/hexagon/test_round.S @@ -0,0 +1,29 @@ +/* + * Purpose: test example, verify the soundness of the cround operation + * 106 =3D 0b1101010 with the comma at third digit is 12.5 which is cround= ed to 12 + * but rounded to 13. + */ + + .text + .globl _start + +_start: + { + r1 =3D #200 + } + { + r2 =3D round(r1, #4) + } + { + p0 =3D cmp.eq(r2, #13); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + r2 =3D cround(r1, #4) + } + { + p0 =3D cmp.eq(r2, #12); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vavgw.S b/tests/tcg/hexagon/test_vavgw.S new file mode 100644 index 0000000000..53c9df706a --- /dev/null +++ b/tests/tcg/hexagon/test_vavgw.S @@ -0,0 +1,31 @@ +/* + * Purpose: test example, verify the soundness of the vavgw operation. + * + * 0x00030001 averaged with 0x00010003 results 0x00020002. + */ + + .text + .globl _start + +_start: + { + r0 =3D #3 + r1 =3D #1 + } + { + r2 =3D #1 + r3 =3D #3 + } + { + r1:0 =3D vavgw(r1:0, r3:2):crnd + } + { + p0 =3D cmp.eq(r0, #2); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r1, #2); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vcmpb.S b/tests/tcg/hexagon/test_vcmpb.S new file mode 100644 index 0000000000..66d253eb48 --- /dev/null +++ b/tests/tcg/hexagon/test_vcmpb.S @@ -0,0 +1,30 @@ +/* + * Purpose: test example, verify the soundness of the vector compare bytes + * operation. + * + * Vector byte comparison between 0x1234567887654321 and 0x1234567800000000 + * should result in 0b11110000 in binary, or 0xf0 in hex. + */ + + .text + .globl _start + +_start: + { + r0 =3D #0x87654321 + r1 =3D #0x12345678 + } + { + r2 =3D #0x00000000 + r3 =3D #0x12345678 + } + { + p2 =3D vcmpb.eq(r1:0, r3:2) + } + { + r4 =3D p2 + } + { + p0 =3D cmp.eq(r4, #0xf0); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vcmpw.S b/tests/tcg/hexagon/test_vcmpw.S new file mode 100644 index 0000000000..5be88d1e2e --- /dev/null +++ b/tests/tcg/hexagon/test_vcmpw.S @@ -0,0 +1,30 @@ +/* + * Purpose: test example, verify the soundness of the vector compare words + * operation. + * + * Vector word comparison between 0x1234567887654321 and 0x1234567800000000 + * should result in 0b11110000 in binary, or 0xf0 in hex. + */ + + .text + .globl _start + +_start: + { + r0 =3D #0x87654321 + r1 =3D #0x12345678 + } + { + r2 =3D #0x00000000 + r3 =3D #0x12345678 + } + { + p2 =3D vcmpw.eq(r1:0, r3:2) + } + { + r4 =3D p2 + } + { + p0 =3D cmp.eq(r4, #0xf0); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vlsrw.S b/tests/tcg/hexagon/test_vlsrw.S new file mode 100644 index 0000000000..912e49aa0b --- /dev/null +++ b/tests/tcg/hexagon/test_vlsrw.S @@ -0,0 +1,20 @@ +/* Purpose: test the soundness of the vlsrw operation */ + + .text + .globl _start + +_start: + { + r0 =3D #0x00000001 + r1 =3D #0x00000001 + } + { + r1:0 =3D vlsrw(r1:0, #1) + } + { + r0 =3D add(r0, r1) + } + { + p0 =3D cmp.eq(r0, #0); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vmaxh.S b/tests/tcg/hexagon/test_vmaxh.S new file mode 100644 index 0000000000..4ea6bd9d96 --- /dev/null +++ b/tests/tcg/hexagon/test_vmaxh.S @@ -0,0 +1,35 @@ +/* + * Purpose: test example, verify the soundness of the vrmaxh operation. + * + * The maximum between 0x0002000300010005 and 0x0003000200020007 is + * 0x0003000300020007. + * + * input: r1 =3D 0x00010003 r0 =3D 0x00010005 r3 =3D 0x00030002 r2 = =3D 0x00020007 + * output: r1 =3D 0x00030003 r0 =3D 0x00020007 + */ + + .text + .globl _start + +_start: + { + r0 =3D #65541 + r1 =3D #65539 + } + { + r2 =3D #131079 + r3 =3D #196610 + } + { + r1:0 =3D vmaxh(r1:0, r3:2) + } + { + p0 =3D cmp.eq(r0, #131079); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r1, #196611); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vminh.S b/tests/tcg/hexagon/test_vminh.S new file mode 100644 index 0000000000..e5fcf2eb94 --- /dev/null +++ b/tests/tcg/hexagon/test_vminh.S @@ -0,0 +1,35 @@ +/* + * Purpose: test example, verify the soundness of the vrmaxh operation. + * + * The minimum between 0x0002000300010005 and 0x0003000200020007 is + * 0x0003000300020007. + * + * input: r1 =3D 0x00010003 r0 =3D 0x00010005 r3 =3D 0x00030002 r2 = =3D 0x00020007 + * output: r1 =3D 0x00010002 r0 =3D 0x00010005 + */ + + .text + .globl _start + +_start: + { + r0 =3D #65541 + r1 =3D #65539 + } + { + r2 =3D #131079 + r3 =3D #196610 + } + { + r1:0 =3D vminh(r1:0, r3:2) + } + { + p0 =3D cmp.eq(r0, #65541); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r1, #65538); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vpmpyh.S b/tests/tcg/hexagon/test_vpmpy= h.S new file mode 100644 index 0000000000..f02758e449 --- /dev/null +++ b/tests/tcg/hexagon/test_vpmpyh.S @@ -0,0 +1,28 @@ +/* + * Purpose: test example, verify the soundness of the vpmpyh operator. + * + * 0x01020304 vector polynomial multiplied with 0x04030201 results + * 0x000400060b060b04. + */ + + .text + .globl _start + +_start: + { + r0 =3D #16909060 + r1 =3D #67305985 + } + { + r1:0 =3D vpmpyh(r0, r1) + } + { + p0 =3D cmp.eq(r0, #184945412); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r1, #262150); if (p0.new) jump:t pass + jump fail + } diff --git a/tests/tcg/hexagon/test_vspliceb.S b/tests/tcg/hexagon/test_vsp= liceb.S new file mode 100644 index 0000000000..53c4a91c51 --- /dev/null +++ b/tests/tcg/hexagon/test_vspliceb.S @@ -0,0 +1,31 @@ +/* + * Purpose: test example, verify the soundness of the vspliceb operation + * the operation is a binary splice of two 64bit operators. + * + * vspliceb(0xffffffffffffffff,0x0000000000000000,5) =3D 0x000000ffffffff= ff. + */ + .text + .globl _start + +_start: + { + r0 =3D #-1 + r1 =3D #-1 + } + { + r2 =3D #0 + r3 =3D #0 + } + { + r5:4 =3D vspliceb(r1:0, r3:2, #5) + } + { + p0 =3D cmp.eq(r4, #-1); if (p0.new) jump:t test2 + jump fail + } + +test2: + { + p0 =3D cmp.eq(r5, #255); if (p0.new) jump:t pass + jump fail + } --=20 2.17.1