aboutsummaryrefslogtreecommitdiff
path: root/target/hexagon
diff options
context:
space:
mode:
authorTaylor Simpson <tsimpson@quicinc.com>2021-04-08 20:07:49 -0500
committerRichard Henderson <richard.henderson@linaro.org>2021-05-01 08:31:43 -0700
commit57d352ac298b27617a53783305af2554025060d9 (patch)
tree410a2da292b95cb585c110070595ebb1ab5f846c /target/hexagon
parent0a65d286936a5fd0ac459a0a047e527ce55731e3 (diff)
Hexagon (target/hexagon) add A4_addp_c/A4_subp_c
Rdd32 = add(Rss32, Rtt32, Px4):carry Add with carry Rdd32 = sub(Rss32, Rtt32, Px4):carry Sub with carry Test cases in tests/tcg/hexagon/multi_result.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-22-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hexagon')
-rw-r--r--target/hexagon/gen_tcg.h37
-rw-r--r--target/hexagon/genptr.c11
-rw-r--r--target/hexagon/imported/alu.idef15
-rw-r--r--target/hexagon/imported/encode_pp.def2
4 files changed, 65 insertions, 0 deletions
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index aea0c55564..6bc578dfda 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -238,6 +238,43 @@
} while (0)
/*
+ * Add or subtract with carry.
+ * Predicate register is used as an extra input and output.
+ * r5:4 = add(r1:0, r3:2, p1):carry
+ */
+#define fGEN_TCG_A4_addp_c(SHORTCODE) \
+ do { \
+ TCGv_i64 carry = tcg_temp_new_i64(); \
+ TCGv_i64 zero = tcg_const_i64(0); \
+ tcg_gen_extu_i32_i64(carry, PxV); \
+ tcg_gen_andi_i64(carry, carry, 1); \
+ tcg_gen_add2_i64(RddV, carry, RssV, zero, carry, zero); \
+ tcg_gen_add2_i64(RddV, carry, RddV, carry, RttV, zero); \
+ tcg_gen_extrl_i64_i32(PxV, carry); \
+ gen_8bitsof(PxV, PxV); \
+ tcg_temp_free_i64(carry); \
+ tcg_temp_free_i64(zero); \
+ } while (0)
+
+/* r5:4 = sub(r1:0, r3:2, p1):carry */
+#define fGEN_TCG_A4_subp_c(SHORTCODE) \
+ do { \
+ TCGv_i64 carry = tcg_temp_new_i64(); \
+ TCGv_i64 zero = tcg_const_i64(0); \
+ TCGv_i64 not_RttV = tcg_temp_new_i64(); \
+ tcg_gen_extu_i32_i64(carry, PxV); \
+ tcg_gen_andi_i64(carry, carry, 1); \
+ tcg_gen_not_i64(not_RttV, RttV); \
+ tcg_gen_add2_i64(RddV, carry, RssV, zero, carry, zero); \
+ tcg_gen_add2_i64(RddV, carry, RddV, carry, not_RttV, zero); \
+ tcg_gen_extrl_i64_i32(PxV, carry); \
+ gen_8bitsof(PxV, PxV); \
+ tcg_temp_free_i64(carry); \
+ tcg_temp_free_i64(zero); \
+ tcg_temp_free_i64(not_RttV); \
+ } while (0)
+
+/*
* Compare each of the 8 unsigned bytes
* The minimum is placed in each byte of the destination.
* Each bit of the predicate is set true if the bit from the first operand
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 9dbebc64b5..333f7d74bf 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -361,5 +361,16 @@ static inline void gen_store_conditional8(CPUHexagonState *env,
tcg_gen_movi_tl(hex_llsc_addr, ~0);
}
+static TCGv gen_8bitsof(TCGv result, TCGv value)
+{
+ TCGv zero = tcg_const_tl(0);
+ TCGv ones = tcg_const_tl(0xff);
+ tcg_gen_movcond_tl(TCG_COND_NE, result, value, zero, ones, zero);
+ tcg_temp_free(zero);
+ tcg_temp_free(ones);
+
+ return result;
+}
+
#include "tcg_funcs_generated.c.inc"
#include "tcg_func_table_generated.c.inc"
diff --git a/target/hexagon/imported/alu.idef b/target/hexagon/imported/alu.idef
index f0c9bb47ec..58477ae40a 100644
--- a/target/hexagon/imported/alu.idef
+++ b/target/hexagon/imported/alu.idef
@@ -153,6 +153,21 @@ Q6INSN(A2_subp,"Rdd32=sub(Rtt32,Rss32)",ATTRIBS(),
"Sub",
{ RddV=RttV-RssV;})
+/* 64-bit with carry */
+
+Q6INSN(A4_addp_c,"Rdd32=add(Rss32,Rtt32,Px4):carry",ATTRIBS(),"Add with Carry",
+{
+ RddV = RssV + RttV + fLSBOLD(PxV);
+ PxV = f8BITSOF(fCARRY_FROM_ADD(RssV,RttV,fLSBOLD(PxV)));
+})
+
+Q6INSN(A4_subp_c,"Rdd32=sub(Rss32,Rtt32,Px4):carry",ATTRIBS(),"Sub with Carry",
+{
+ RddV = RssV + ~RttV + fLSBOLD(PxV);
+ PxV = f8BITSOF(fCARRY_FROM_ADD(RssV,~RttV,fLSBOLD(PxV)));
+})
+
+
/* NEG and ABS */
Q6INSN(A2_negsat,"Rd32=neg(Rs32):sat",ATTRIBS(),
diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/imported/encode_pp.def
index 46193984c5..514c2404ce 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -1749,6 +1749,8 @@ SH_RRR_ENC(S4_extractp_rp, "0001","11-","-","10-","ddddd")
DEF_FIELDROW_DESC32(ICLASS_S3op" 0010 -------- PP------ --------","[#2] Rdd=(Rss,Rtt,Pu)")
SH_RRR_ENC(S2_valignrb, "0010","0--","-","-uu","ddddd")
SH_RRR_ENC(S2_vsplicerb, "0010","100","-","-uu","ddddd")
+SH_RRR_ENC(A4_addp_c, "0010","110","-","-xx","ddddd")
+SH_RRR_ENC(A4_subp_c, "0010","111","-","-xx","ddddd")
DEF_FIELDROW_DESC32(ICLASS_S3op" 0011 -------- PP------ --------","[#3] Rdd=(Rss,Rt)")